diff --git a/src/main/java/de/bixilon/minosoft/data/Player.java b/src/main/java/de/bixilon/minosoft/data/Player.java
deleted file mode 100644
index 588090512..000000000
--- a/src/main/java/de/bixilon/minosoft/data/Player.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Minosoft
- * Copyright (C) 2020 Moritz Zwerger
- *
- * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with this program.If not, see .
- *
- * This software is not affiliated with Mojang AB, the original developer of Minecraft.
- */
-
-package de.bixilon.minosoft.data;
-
-import de.bixilon.minosoft.data.accounts.Account;
-import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity;
-import de.bixilon.minosoft.data.inventory.Inventory;
-import de.bixilon.minosoft.data.inventory.InventoryProperties;
-import de.bixilon.minosoft.data.inventory.InventorySlots;
-import de.bixilon.minosoft.data.inventory.Slot;
-import de.bixilon.minosoft.data.player.PlayerListItem;
-import de.bixilon.minosoft.data.scoreboard.ScoreboardManager;
-import de.bixilon.minosoft.data.text.ChatComponent;
-import de.bixilon.minosoft.data.world.BlockPosition;
-import de.bixilon.minosoft.data.world.World;
-
-import java.util.HashMap;
-import java.util.UUID;
-
-import static de.bixilon.minosoft.protocol.protocol.ProtocolDefinition.PLAYER_INVENTORY_ID;
-
-public class Player {
- public final HashMap playerList = new HashMap<>();
- private final Account account;
- private final ScoreboardManager scoreboardManager = new ScoreboardManager();
- private final World world = new World();
- private final HashMap inventories = new HashMap<>();
- private float health;
- private int food;
- private float saturation;
- private BlockPosition spawnPosition;
- private GameModes gameMode;
- private byte selectedSlot;
- private int level;
- private int totalExperience;
- private PlayerEntity entity;
- private boolean spawnConfirmed;
- private UUID uuid;
- private String playerName;
-
- private ChatComponent tabHeader = ChatComponent.valueOf("");
- private ChatComponent tabFooter = ChatComponent.valueOf("");
-
- public Player(Account account) {
- this.account = account;
- this.uuid = account.getUUID();
- this.playerName = account.getUsername();
- // create our own inventory without any properties
- this.inventories.put(PLAYER_INVENTORY_ID, new Inventory(null));
- }
-
- public String getPlayerName() {
- return this.playerName;
- }
-
- public void setPlayerName(String playerName) {
- this.playerName = playerName;
- }
-
-
- public UUID getPlayerUUID() {
- return this.uuid;
- }
-
- public void setPlayerUUID(UUID uuid) {
- this.uuid = uuid;
- }
-
- public Account getAccount() {
- return this.account;
- }
-
- public float getHealth() {
- return this.health;
- }
-
- public void setHealth(float health) {
- this.health = health;
- }
-
- public int getFood() {
- return this.food;
- }
-
- public void setFood(int food) {
- this.food = food;
- }
-
- public float getSaturation() {
- return this.saturation;
- }
-
- public void setSaturation(float saturation) {
- this.saturation = saturation;
- }
-
- public BlockPosition getSpawnPosition() {
- return this.spawnPosition;
- }
-
- public void setSpawnPosition(BlockPosition spawnPosition) {
- this.spawnPosition = spawnPosition;
- }
-
- public GameModes getGameMode() {
- return this.gameMode;
- }
-
- public void setGameMode(GameModes gameMode) {
- this.gameMode = gameMode;
- }
-
- public World getWorld() {
- return this.world;
- }
-
- public byte getSelectedSlot() {
- return this.selectedSlot;
- }
-
- public void setSelectedSlot(byte selectedSlot) {
- this.selectedSlot = selectedSlot;
- }
-
- public int getLevel() {
- return this.level;
- }
-
- public void setLevel(int level) {
- this.level = level;
- }
-
- public int getTotalExperience() {
- return this.totalExperience;
- }
-
- public void setTotalExperience(int totalExperience) {
- this.totalExperience = totalExperience;
- }
-
- public Inventory getPlayerInventory() {
- return getInventory(PLAYER_INVENTORY_ID);
- }
-
- public void setPlayerInventory(Slot[] data) {
- setInventory(PLAYER_INVENTORY_ID, data);
- }
-
- public void setInventory(int windowId, Slot[] data) {
- for (int i = 0; i < data.length; i++) {
- setSlot(windowId, i, data[i]);
- }
- }
-
- public void setSlot(int windowId, int slot, Slot data) {
- this.inventories.get(windowId).setSlot(slot, data);
- }
-
- public Inventory getInventory(int id) {
- return this.inventories.get(id);
- }
-
- public Slot getSlot(int windowId, InventorySlots.InventoryInterface slot, int versionId) {
- return getSlot(windowId, slot.getId(versionId));
- }
-
- public Slot getSlot(int windowId, int slot) {
- return this.inventories.get(windowId).getSlot(slot);
- }
-
- public void setSlot(int windowId, InventorySlots.InventoryInterface slot, int versionId, Slot data) {
- setSlot(windowId, slot.getId(versionId), data);
- }
-
- public void createInventory(InventoryProperties properties) {
- this.inventories.put(properties.getWindowId(), new Inventory(properties));
- }
-
- public void deleteInventory(int windowId) {
- this.inventories.remove(windowId);
- }
-
- public boolean isSpawnConfirmed() {
- return this.spawnConfirmed;
- }
-
- public void setSpawnConfirmed(boolean spawnConfirmed) {
- this.spawnConfirmed = spawnConfirmed;
- }
-
- public ScoreboardManager getScoreboardManager() {
- return this.scoreboardManager;
- }
-
- public HashMap getPlayerList() {
- return this.playerList;
- }
-
- public PlayerListItem getPlayerListItem(String name) {
- // only legacy
- for (PlayerListItem listItem : this.playerList.values()) {
- if (listItem.getName().equals(name)) {
- return listItem;
- }
- }
- return null;
- }
-
- public ChatComponent getTabHeader() {
- return this.tabHeader;
- }
-
- public void setTabHeader(ChatComponent tabHeader) {
- this.tabHeader = tabHeader;
- }
-
- public ChatComponent getTabFooter() {
- return this.tabFooter;
- }
-
- public void setTabFooter(ChatComponent tabFooter) {
- this.tabFooter = tabFooter;
- }
-
- public PlayerEntity getEntity() {
- return this.entity;
- }
-
- public void setEntity(PlayerEntity entity) {
- this.entity = entity;
- }
-}
diff --git a/src/main/java/de/bixilon/minosoft/data/Player.kt b/src/main/java/de/bixilon/minosoft/data/Player.kt
new file mode 100644
index 000000000..37c730452
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/Player.kt
@@ -0,0 +1,104 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+package de.bixilon.minosoft.data
+
+import de.bixilon.minosoft.data.accounts.Account
+import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
+import de.bixilon.minosoft.data.inventory.Inventory
+import de.bixilon.minosoft.data.inventory.InventoryProperties
+import de.bixilon.minosoft.data.inventory.InventorySlots.InventoryInterface
+import de.bixilon.minosoft.data.inventory.Slot
+import de.bixilon.minosoft.data.player.PlayerListItem
+import de.bixilon.minosoft.data.scoreboard.ScoreboardManager
+import de.bixilon.minosoft.data.text.ChatComponent
+import de.bixilon.minosoft.data.world.BlockPosition
+import de.bixilon.minosoft.data.world.World
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
+import java.util.*
+
+class Player(val account: Account) {
+ val playerList = HashMap()
+ val scoreboardManager = ScoreboardManager()
+ val world = World()
+ private val inventories = HashMap()
+ var health = 0f
+ var food = 0
+ var saturation = 0f
+ var spawnPosition: BlockPosition? = null
+ var gameMode: GameModes? = null
+ var selectedSlot: Byte = 0
+ var level = 0
+ var totalExperience = 0
+ var entity: PlayerEntity? = null
+ var isSpawnConfirmed = false
+ var playerUUID: UUID = account.uuid
+ var playerName: String = account.username
+ var tabHeader = ChatComponent.valueOf("")!!
+ var tabFooter = ChatComponent.valueOf("")!!
+
+ val playerInventory: Inventory?
+ get() = getInventory(ProtocolDefinition.PLAYER_INVENTORY_ID)
+
+ fun setPlayerInventory(data: Array) {
+ setInventory(ProtocolDefinition.PLAYER_INVENTORY_ID, data)
+ }
+
+ fun setInventory(windowId: Int, data: Array) {
+ for (i in data.indices) {
+ setSlot(windowId, i, data[i])
+ }
+ }
+
+ fun setSlot(windowId: Int, slot: Int, data: Slot?) {
+ inventories[windowId]!!.setSlot(slot, data)
+ }
+
+ fun getInventory(id: Int): Inventory? {
+ return inventories[id]
+ }
+
+ fun getSlot(windowId: Int, slot: InventoryInterface, versionId: Int): Slot {
+ return getSlot(windowId, slot.getId(versionId))
+ }
+
+ fun getSlot(windowId: Int, slot: Int): Slot {
+ return inventories[windowId]!!.getSlot(slot)
+ }
+
+ fun setSlot(windowId: Int, slot: InventoryInterface, versionId: Int, data: Slot?) {
+ setSlot(windowId, slot.getId(versionId), data)
+ }
+
+ fun createInventory(properties: InventoryProperties) {
+ inventories[properties.windowId] = Inventory(properties)
+ }
+
+ fun deleteInventory(windowId: Int) {
+ inventories.remove(windowId)
+ }
+
+ fun getPlayerListItem(name: String): PlayerListItem? {
+ // only legacy
+ for (listItem in playerList.values) {
+ if (listItem.name == name) {
+ return listItem
+ }
+ }
+ return null
+ }
+
+ init {
+ // create our own inventory without any properties
+ inventories[ProtocolDefinition.PLAYER_INVENTORY_ID] = Inventory(null)
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt
index 09cc00468..8f1292795 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/BlockPosition.kt
@@ -45,12 +45,15 @@ data class BlockPosition(val x: Int, val y: Int, val z: Int) {
return InChunkPosition(x, this.y, z)
}
- infix operator fun plus(vec3: Vec3): BlockPosition {
+ infix operator fun plus(vec3: Vec3?): BlockPosition {
+ if (vec3 == null) {
+ return this
+ }
return BlockPosition((x + vec3.x).toInt(), (y + vec3.y).toInt(), (z + vec3.z).toInt())
}
- operator fun plus(directions: Directions): BlockPosition {
- return this + directions.directionVector
+ infix operator fun plus(directions: Directions?): BlockPosition {
+ return this + directions?.directionVector
}
fun getInChunkSectionPosition(): InChunkSectionPosition {
diff --git a/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt
index e74ccdbb6..2bb076df0 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/InChunkPosition.kt
@@ -12,6 +12,7 @@
*/
package de.bixilon.minosoft.data.world
+import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.vec3.Vec3
@@ -34,10 +35,17 @@ data class InChunkPosition(val x: Int, val y: Int, val z: Int) {
}
}
- operator fun plus(vec3: Vec3): InChunkPosition {
+ operator fun plus(vec3: Vec3?): InChunkPosition {
+ if (vec3 == null) {
+ return this
+ }
return InChunkPosition((x + vec3.x).toInt(), (y + vec3.y).toInt(), (z + vec3.z).toInt())
}
+ operator fun plus(direction: Directions?): InChunkPosition {
+ return this + direction?.directionVector
+ }
+
override fun toString(): String {
return "($x $y $z)"
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionPosition.kt b/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionPosition.kt
index bf9a53988..279e0ad5b 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionPosition.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/InChunkSectionPosition.kt
@@ -55,6 +55,11 @@ data class InChunkSectionPosition(val x: Int, val y: Int, val z: Int) {
return InChunkSectionPosition(nextX, nextY, nextZ)
}
+
+ fun isEdge(): Boolean {
+ return x == 0 || y == 0 || z == 0 || x == ProtocolDefinition.SECTION_MAX_X || y == ProtocolDefinition.SECTION_MAX_Y || z == ProtocolDefinition.SECTION_MAX_Z
+ }
+
operator fun plus(directions: Directions): InChunkSectionPosition {
return this + directions.directionVector
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt
index ec42728a4..565052db3 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/World.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt
@@ -13,10 +13,12 @@
package de.bixilon.minosoft.data.world
import com.google.common.collect.HashBiMap
+import de.bixilon.minosoft.data.Difficulties
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.mappings.Dimension
import de.bixilon.minosoft.data.mappings.blocks.BlockState
+import de.bixilon.minosoft.data.world.light.WorldLightAccessor
import java.util.*
import java.util.concurrent.ConcurrentHashMap
@@ -30,7 +32,9 @@ class World {
var isHardcore = false
var isRaining = false
var dimension: Dimension? = null
-
+ var difficulty: Difficulties? = null
+ var difficultyLocked = false
+ val worldLightAccessor = WorldLightAccessor(this)
fun getBlockInfo(blockPosition: BlockPosition): BlockInfo? {
val chunkLocation = blockPosition.getChunkPosition()
diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt
index 19deff0a6..cf7669fa1 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/light/ChunkLightAccessor.kt
@@ -13,24 +13,28 @@
package de.bixilon.minosoft.data.world.light
-import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.world.BlockPosition
import de.bixilon.minosoft.data.world.InChunkPosition
-import de.bixilon.minosoft.data.world.World
class ChunkLightAccessor(
- val blockLightLevel: MutableMap = mutableMapOf(),
- val skyLightLevel: MutableMap = mutableMapOf(),
- val world: World,
+ private val blockLightLevel: MutableMap> = mutableMapOf(),
+ private val skyLightLevel: MutableMap> = mutableMapOf(),
) : LightAccessor {
- override fun getLightLevel(blockPosition: BlockPosition, direction: Directions): Int {
- val inChunkPosition = blockPosition.getInChunkPosition()
- val lightLevel = blockLightLevel[inChunkPosition] ?: skyLightLevel[inChunkPosition]
+ override fun getSkyLight(blockPosition: BlockPosition): Byte {
+ return skyLightLevel[blockPosition.getSectionHeight()]?.get(blockPosition.getInChunkPosition()) ?: 0
+ }
- if (lightLevel == null) {
- return 1
+ override fun getBlockLight(blockPosition: BlockPosition): Byte {
+ return blockLightLevel[blockPosition.getSectionHeight()]?.get(blockPosition.getInChunkPosition()) ?: 0
+ }
+
+ fun merge(chunkLightAccessor: ChunkLightAccessor) {
+ for ((sectionHeight, section) in chunkLightAccessor.blockLightLevel) {
+ blockLightLevel[sectionHeight] = section
}
- return lightLevel.toInt()
+ for ((sectionHeight, section) in chunkLightAccessor.skyLightLevel) {
+ skyLightLevel[sectionHeight] = section
+ }
}
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt
index 40b0c42c5..cce59c31b 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/light/DummyLightAccessor.kt
@@ -13,19 +13,15 @@
package de.bixilon.minosoft.data.world.light
-import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.world.BlockPosition
object DummyLightAccessor : LightAccessor {
-
- override fun getLightLevel(blockPosition: BlockPosition, direction: Directions): Int {
- return when (direction) {
- Directions.NORTH -> 5
- Directions.SOUTH -> 7
- Directions.DOWN -> 3
- Directions.UP -> 9
- Directions.WEST -> 11
- Directions.EAST -> 13
- }
+ override fun getSkyLight(blockPosition: BlockPosition): Byte {
+ return 15
}
+
+ override fun getBlockLight(blockPosition: BlockPosition): Byte {
+ return 15
+ }
+
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt
index bf48e6af5..40ac49d3c 100644
--- a/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt
+++ b/src/main/java/de/bixilon/minosoft/data/world/light/LightAccessor.kt
@@ -13,10 +13,21 @@
package de.bixilon.minosoft.data.world.light
-import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.world.BlockPosition
interface LightAccessor {
- fun getLightLevel(blockPosition: BlockPosition, direction: Directions): Int
+ fun getSkyLight(blockPosition: BlockPosition): Byte
+
+ fun getBlockLight(blockPosition: BlockPosition): Byte
+
+ fun getLightLevel(blockPosition: BlockPosition): Byte {
+ val blockLight = getBlockLight(blockPosition)
+ val skyLight = getSkyLight(blockPosition)
+ if (blockLight > skyLight) {
+ return blockLight
+ }
+ return skyLight
+ }
+
}
diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt
new file mode 100644
index 000000000..5074acf7f
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt
@@ -0,0 +1,29 @@
+/*
+ * Minosoft
+ * Copyright (C) 2021 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.world.light
+
+import de.bixilon.minosoft.data.world.BlockPosition
+import de.bixilon.minosoft.data.world.World
+
+class WorldLightAccessor(
+ private val world: World,
+) : LightAccessor {
+ override fun getSkyLight(blockPosition: BlockPosition): Byte {
+ return world.chunks[blockPosition.getChunkPosition()]?.lightAccessor?.getSkyLight(blockPosition) ?: 0
+ }
+
+ override fun getBlockLight(blockPosition: BlockPosition): Byte {
+ return world.chunks[blockPosition.getChunkPosition()]?.lightAccessor?.getBlockLight(blockPosition) ?: 0
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt
index 34788ebd3..274154d66 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkMesh.kt
@@ -29,7 +29,7 @@ class ChunkMesh {
private var vbo: Int = 0
private var trianglesCount: Int = 0
- fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Float = 0.9f) {
+ fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Byte = 14) {
data.add(position.x)
data.add(position.y)
data.add(position.z)
@@ -48,7 +48,7 @@ class ChunkMesh {
data.add(Float.fromBits(tintColor.color))
}
- data.add(lightLevel)
+ data.add(lightLevel / MAX_LIGHT_LEVEL)
}
fun load() {
@@ -99,5 +99,6 @@ class ChunkMesh {
companion object {
private const val FLOATS_PER_VERTEX = 11
+ private const val MAX_LIGHT_LEVEL = 15f
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt
index 52094a170..8955c778b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt
@@ -77,7 +77,7 @@ class WorldRenderer(private val connection: Connection, private val world: World
blockInfo.block.tintColor?.let { tintColor = it }
}
- blockInfo.block.getBlockRenderer(blockPosition).render(blockInfo, chunk.lightAccessor!!, tintColor, blockPosition, mesh, neighborBlocks)
+ blockInfo.block.getBlockRenderer(blockPosition).render(blockInfo, world.worldLightAccessor, tintColor, blockPosition, mesh, neighborBlocks)
}
return mesh
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt
index 55542df82..e6f4695ab 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt
@@ -92,7 +92,8 @@ class BlockRenderer(data: JsonObject, parent: BlockModel) {
continue
}
- element.render(tintColor, lightAccessor.getLightLevel(position, direction) / 15f, textureMapping, modelMatrix, direction, mesh)
+ // ToDo: Lightning is determined by cullface attribute
+ element.render(tintColor, lightAccessor.getLightLevel(position + direction), textureMapping, modelMatrix, direction, mesh)
}
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt
index ec360f49c..8f2e44590 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt
@@ -50,7 +50,7 @@ class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvLock: Boolea
}
- fun render(tintColor: RGBColor?, lightLevel: Float, textureMapping: MutableMap, modelMatrix: Mat4, direction: Directions, mesh: ChunkMesh) {
+ fun render(tintColor: RGBColor?, lightLevel: Byte, textureMapping: MutableMap, modelMatrix: Mat4, direction: Directions, mesh: ChunkMesh) {
val realDirection = directionMapping[direction]!!
val positionTemplate = BlockModelElement.FACE_POSITION_MAP_TEMPLATE[realDirection.ordinal]
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt
index a7b899cc1..3ec640a2c 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDDebugScreenElement.kt
@@ -59,6 +59,15 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex
"Facing ${getFacing()}",
"Dimension ${hudTextElement.connection.player.world.dimension}",
"Biome ${camera.currentBiome}",
+ "",
+ "Difficulty ${hudTextElement.connection.player.world.difficulty?.name?.toLowerCase()}, ${
+ if (hudTextElement.connection.player.world.difficultyLocked) {
+ "locked"
+ } else {
+ "unlocked"
+ }
+ }",
+ "Client light: ${hudTextElement.connection.player.world.worldLightAccessor.getLightLevel(camera.blockPosition)} (sky=${hudTextElement.connection.player.world.worldLightAccessor.getSkyLight(camera.blockPosition)}, block=${hudTextElement.connection.player.world.worldLightAccessor.getBlockLight(camera.blockPosition)})"
))
chatComponents[FontBindings.RIGHT_UP]!!.addAll(listOf(
"Java: ${Runtime.version()} ${System.getProperty("sun.arch.data.model")}bit",
@@ -160,7 +169,8 @@ class HUDDebugScreenElement(private val hudTextElement: HUDTextElement) : HUDTex
private fun getFacing(): String {
val yaw = hudTextElement.renderWindow.camera.yaw
val pitch = hudTextElement.renderWindow.camera.pitch
- return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} (${formatRotation(yaw)} / ${formatRotation(pitch)})"
+ val direction = Directions.byDirection(camera.cameraFront)
+ return "${Directions.byDirection(camera.cameraFront).name.toLowerCase()} (${direction.directionVector} (${formatRotation(yaw)} / ${formatRotation(pitch)})"
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.java
deleted file mode 100644
index c8c220e37..000000000
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Minosoft
- * Copyright (C) 2020 Moritz Zwerger
- *
- * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with this program.If not, see .
- *
- * This software is not affiliated with Mojang AB, the original developer of Minecraft.
- */
-
-package de.bixilon.minosoft.protocol.packets.clientbound.play;
-
-import de.bixilon.minosoft.data.Difficulties;
-import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
-import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
-import de.bixilon.minosoft.util.logging.Log;
-
-import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_19W11A;
-
-public class PacketServerDifficulty extends ClientboundPacket {
- Difficulties difficulty;
- boolean locked;
-
- @Override
- public boolean read(InByteBuffer buffer) {
- this.difficulty = Difficulties.byId(buffer.readUnsignedByte());
- if (buffer.getVersionId() > V_19W11A) {
- this.locked = buffer.readBoolean();
- }
- return true;
- }
-
- @Override
- public void log() {
- Log.protocol(String.format("[IN] Received server difficulty (difficulty=%s)", this.difficulty));
- }
-
- public Difficulties getDifficulty() {
- return this.difficulty;
- }
-}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt
new file mode 100644
index 000000000..7c5ef0d62
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketServerDifficulty.kt
@@ -0,0 +1,42 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+package de.bixilon.minosoft.protocol.packets.clientbound.play
+
+import de.bixilon.minosoft.data.Difficulties
+import de.bixilon.minosoft.protocol.network.Connection
+import de.bixilon.minosoft.protocol.packets.ClientboundPacket
+import de.bixilon.minosoft.protocol.protocol.InByteBuffer
+import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
+import de.bixilon.minosoft.util.logging.Log
+
+class PacketServerDifficulty : ClientboundPacket() {
+ lateinit var difficulty: Difficulties
+ var locked = false
+
+ override fun read(buffer: InByteBuffer): Boolean {
+ difficulty = Difficulties.byId(buffer.readUnsignedByte().toInt())
+ if (buffer.versionId > ProtocolVersions.V_19W11A) {
+ locked = buffer.readBoolean()
+ }
+ return true
+ }
+
+ override fun handle(connection: Connection) {
+ connection.player.world.difficulty = difficulty
+ connection.player.world.difficultyLocked = locked
+ }
+
+ override fun log() {
+ Log.protocol("[IN] Received server difficulty (difficulty=$difficulty, locked=${locked})")
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt
index 2b8b50c37..546317a4f 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUpdateLight.kt
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play
import de.bixilon.minosoft.data.world.ChunkPosition
+import de.bixilon.minosoft.data.world.light.ChunkLightAccessor
import de.bixilon.minosoft.data.world.light.LightAccessor
import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.packets.ClientboundPacket
@@ -27,7 +28,7 @@ class PacketUpdateLight : ClientboundPacket() {
override fun read(buffer: InByteBuffer): Boolean {
position = ChunkPosition(buffer.readVarInt(), buffer.readVarInt())
- if (position == ChunkPosition(-1, 21)) {
+ if (position == ChunkPosition(-6, 20)) {
Log.debug("")
}
if (buffer.versionId >= ProtocolVersions.V_1_16_PRE3) {
@@ -61,7 +62,11 @@ class PacketUpdateLight : ClientboundPacket() {
override fun handle(connection: Connection) {
val chunk = connection.player.world.getOrCreateChunk(position!!)
- chunk.lightAccessor = lightAccessor
+ if (chunk.lightAccessor != null && chunk.lightAccessor is ChunkLightAccessor && lightAccessor is ChunkLightAccessor) {
+ (chunk.lightAccessor as ChunkLightAccessor).merge(lightAccessor as ChunkLightAccessor)
+ } else {
+ chunk.lightAccessor = lightAccessor
+ }
connection.renderer.renderWindow.worldRenderer.prepareChunk(position!!, chunk)
}
}
diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.java b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.java
index cf656cf4f..94c36a72d 100644
--- a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.java
+++ b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.java
@@ -60,8 +60,8 @@ public final class ChunkUtil {
// parse data
int arrayPos = 0;
HashMap sectionMap = new HashMap<>();
- for (int c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
- if (BitByte.isBitSet(sectionBitMasks[0], c)) {
+ for (int sectionHeight = dimension.getLowestSection(); sectionHeight < dimension.getHighestSection(); sectionHeight++) { // max sections per chunks in chunk column
+ if (BitByte.isBitSet(sectionBitMasks[0], sectionHeight)) {
HashMap blockMap = new HashMap<>();
for (int nibbleY = 0; nibbleY < ProtocolDefinition.SECTION_HEIGHT_Y; nibbleY++) {
@@ -73,13 +73,13 @@ public final class ChunkUtil {
if (arrayPos % 2 == 0) {
// high bits
singleMeta = (byte) (meta[arrayPos / 2] & 0xF);
- if (BitByte.isBitSet(addBitMask, c)) {
+ if (BitByte.isBitSet(addBitMask, sectionHeight)) {
singeBlockId = (short) ((singeBlockId << 4) | (addBlockTypes[arrayPos / 2] >>> 4));
}
} else {
// low 4 bits
singleMeta = (byte) ((meta[arrayPos / 2] >>> 4) & 0xF);
- if (BitByte.isBitSet(addBitMask, c)) {
+ if (BitByte.isBitSet(addBitMask, sectionHeight)) {
singeBlockId = (short) ((singeBlockId << 4) | (addBlockTypes[arrayPos / 2] & 0xF));
}
}
@@ -95,7 +95,7 @@ public final class ChunkUtil {
}
}
}
- sectionMap.put(dimension.getLowestSection() + c, new ChunkSection(blockMap)); // ToDo
+ sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap)); // ToDo
}
}
return new ChunkData(sectionMap, new DummyBiomeAccessor(buffer.getConnection().getMapping().getBiomeRegistry().get(0)), DummyLightAccessor.INSTANCE);
@@ -122,8 +122,8 @@ public final class ChunkUtil {
int arrayPos = 0;
HashMap sectionMap = new HashMap<>();
- for (int c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
- if (!BitByte.isBitSet(sectionBitMasks[0], c)) {
+ for (int sectionHeight = dimension.getLowestSection(); sectionHeight < dimension.getHighestSection(); sectionHeight++) { // max sections per chunks in chunk column
+ if (!BitByte.isBitSet(sectionBitMasks[0], sectionHeight)) {
continue;
}
HashMap blockMap = new HashMap<>();
@@ -142,15 +142,15 @@ public final class ChunkUtil {
}
}
}
- sectionMap.put(dimension.getLowestSection() + c, new ChunkSection(blockMap));
+ sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap));
}
return new ChunkData(sectionMap, new DummyBiomeAccessor(buffer.getConnection().getMapping().getBiomeRegistry().get(0)), DummyLightAccessor.INSTANCE); // ToDo
}
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
HashMap sectionMap = new HashMap<>();
BitSet sectionBitSet = BitSet.valueOf(sectionBitMasks);
- for (int c = 0; c < sectionBitSet.length(); c++) { // max sections per chunks in chunk column
- if (!sectionBitSet.get(c)) {
+ for (int sectionHeight = dimension.getLowestSection(); sectionHeight < sectionBitSet.length(); sectionHeight++) { // max sections per chunks in chunk column
+ if (!sectionBitSet.get(sectionHeight)) {
continue;
}
if (buffer.getVersionId() >= V_18W43A) {
@@ -206,7 +206,7 @@ public final class ChunkUtil {
// ToDo
}
- sectionMap.put(dimension.getLowestSection() + c, new ChunkSection(blockMap));
+ sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap));
}
ChunkData chunkData = new ChunkData();
chunkData.setBlocks(sectionMap);
diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt
index fea174001..758e99962 100644
--- a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt
+++ b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt
@@ -16,7 +16,6 @@ package de.bixilon.minosoft.util.chunk
import de.bixilon.minosoft.data.mappings.Dimension
import de.bixilon.minosoft.data.world.InChunkPosition
import de.bixilon.minosoft.data.world.light.ChunkLightAccessor
-import de.bixilon.minosoft.data.world.light.DummyLightAccessor
import de.bixilon.minosoft.data.world.light.LightAccessor
import de.bixilon.minosoft.protocol.protocol.InByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
@@ -26,16 +25,16 @@ object LightUtil {
fun readLightPacket(buffer: InByteBuffer, skyLightMask: LongArray, blockLightMask: LongArray, emptyBlockLightMask: LongArray, emptySkyLightMask: LongArray, dimension: Dimension): LightAccessor {
// ToDo
- val blockLight = readLightArray(buffer, BitSet.valueOf(blockLightMask), dimension)
- if (!dimension.hasSkyLight) {
- return ChunkLightAccessor(blockLight, world = buffer.connection.player.world)
+ val skyLight = if (dimension.hasSkyLight) {
+ readLightArray(buffer, BitSet.valueOf(skyLightMask), dimension)
+ } else {
+ mutableMapOf()
}
- val skyLight = readLightArray(buffer, BitSet.valueOf(skyLightMask), dimension)
- return DummyLightAccessor
- return ChunkLightAccessor(blockLight, skyLight, buffer.connection.player.world)
+ val blockLight = readLightArray(buffer, BitSet.valueOf(blockLightMask), dimension)
+ return ChunkLightAccessor(blockLight, skyLight)
}
- private fun readLightArray(buffer: InByteBuffer, lightMask: BitSet, dimension: Dimension): MutableMap {
+ private fun readLightArray(buffer: InByteBuffer, lightMask: BitSet, dimension: Dimension): MutableMap> {
var highestSectionIndex = dimension.highestSection + 1
val lowesSectionIndex = dimension.lowestSection - 1
if (buffer.versionId >= ProtocolVersions.V_20W49A) {
@@ -43,10 +42,11 @@ object LightUtil {
highestSectionIndex = lightMask.length()
}
- val lightLevels: MutableMap = mutableMapOf()
+ val lightLevels: MutableMap> = mutableMapOf()
- for ((arrayIndex, c) in (lowesSectionIndex until highestSectionIndex).withIndex()) { // light sections
+ for ((arrayIndex, sectionHeight) in (lowesSectionIndex until highestSectionIndex).withIndex()) { // light sections
+ val currentSectionLightLevel: MutableMap = mutableMapOf()
if (!lightMask[arrayIndex]) {
continue
}
@@ -55,12 +55,13 @@ object LightUtil {
for (y in 0 until 16) {
for (z in 0 until 16) {
for (x in 0 until 16 step 2) {
- lightLevels[InChunkPosition(x, y + c * 16, z)] = (lightArray[index].toInt() and 0x0F).toByte()
- lightLevels[InChunkPosition(x + 1, y + c * 16, z)] = ((lightArray[index].toInt() ushr 4) and 0x0F).toByte()
+ currentSectionLightLevel[InChunkPosition(x, y + sectionHeight * 16, z)] = (lightArray[index].toInt() and 0x0F).toByte()
+ currentSectionLightLevel[InChunkPosition(x + 1, y + sectionHeight * 16, z)] = ((lightArray[index].toInt() ushr 4) and 0x0F).toByte()
index++
}
}
}
+ lightLevels[sectionHeight] = currentSectionLightLevel
}
return lightLevels
}