implement chat, implement teleport, help and time command, use relative vertex positions for block rendering, version 1.0.3

This commit is contained in:
LabyStudio
2022-05-17 01:41:16 +02:00
parent 1e10dda0e2
commit 32245a9136
18 changed files with 416 additions and 81 deletions
+5 -3
View File
@@ -1,9 +1,11 @@
export default class GameSettings {
constructor() {
this.crouching = 'ShiftLeft';
this.sprinting = 'ControlLeft';
this.togglePerspective = 'F5';
this.keyCrouching = 'ShiftLeft';
this.keySprinting = 'ControlLeft';
this.keyTogglePerspective = 'F5';
this.keyOpenChat = 'KeyT';
this.thirdPersonView = 0;
this.fov = 70;
this.viewBobbing = true;
+19 -3
View File
@@ -4,7 +4,7 @@ import GameWindow from "./GameWindow.js";
import WorldRenderer from "./render/WorldRenderer.js";
import ScreenRenderer from "./render/gui/ScreenRenderer.js";
import ItemRenderer from "./render/gui/ItemRenderer.js";
import IngameOverlay from "./gui/IngameOverlay.js";
import IngameOverlay from "./gui/overlay/IngameOverlay.js";
import PlayerEntity from "./entity/PlayerEntity.js";
import SoundManager from "./sound/SoundManager.js";
import Block from "./world/block/Block.js";
@@ -16,10 +16,12 @@ import GuiMainMenu from "./gui/screens/GuiMainMenu.js";
import GuiLoadingScreen from "./gui/screens/GuiLoadingScreen.js";
import * as THREE from "../../../../../libraries/three.module.js";
import ParticleRenderer from "./render/particle/ParticleRenderer.js";
import GuiChat from "./gui/screens/GuiChat.js";
import CommandHandler from "./command/CommandHandler.js";
export default class Minecraft {
static VERSION = "1.0.2"
static VERSION = "1.0.3"
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
/**
@@ -52,6 +54,9 @@ export default class Minecraft {
// Create current screen and overlay
this.ingameOverlay = new IngameOverlay(this, this.window);
// Command handler
this.commandHandler = new CommandHandler(this);
this.frames = 0;
this.lastTime = Date.now();
@@ -125,6 +130,10 @@ export default class Minecraft {
return this.world !== null && this.worldRenderer !== null && this.player !== null;
}
addMessageToChat(message) {
this.ingameOverlay.chatOverlay.addMessage(message);
}
requestNextFrame() {
requestAnimationFrame(() => {
if (this.running) {
@@ -225,6 +234,9 @@ export default class Minecraft {
// Tick particle renderer
this.particleRenderer.onTick();
// Tick overlay
this.ingameOverlay.onTick();
}
// Tick the screen
@@ -269,10 +281,14 @@ export default class Minecraft {
}
}
if (button === this.settings.togglePerspective) {
if (button === this.settings.keyTogglePerspective) {
this.settings.thirdPersonView = (this.settings.thirdPersonView + 1) % 3;
this.settings.save();
}
if (button === this.settings.keyOpenChat) {
this.displayScreen(new GuiChat());
}
}
onMouseClicked(button) {
@@ -0,0 +1,13 @@
export default class Command {
constructor(command, usage, description) {
this.command = command;
this.usage = usage;
this.description = description;
}
execute(minecraft, args) {
return false;
}
}
@@ -0,0 +1,34 @@
import HelpCommand from "./command/HelpCommand.js";
import TimeCommand from "./command/TimeCommand.js";
import TeleportCommand from "./command/TeleportCommand.js";
export default class CommandHandler {
constructor(minecraft) {
this.minecraft = minecraft;
this.commands = [];
this.commands.push(new HelpCommand());
this.commands.push(new TimeCommand());
this.commands.push(new TeleportCommand());
}
handleMessage(message) {
let args = message.split(" ");
let command = args[0].toLowerCase();
this.handleCommand(command, args.slice(1));
}
handleCommand(command, args) {
for (let i = 0; i < this.commands.length; i++) {
let commandExecutor = this.commands[i];
if (commandExecutor.command === command) {
if (!this.commands[i].execute(this.minecraft, args)) {
this.minecraft.addMessageToChat("/" + commandExecutor.command + " " + commandExecutor.usage);
}
return;
}
}
this.minecraft.addMessageToChat("Unknown command! Type \"/help\" for help.");
}
}
@@ -0,0 +1,17 @@
import Command from "../Command.js";
export default class HelpCommand extends Command {
constructor() {
super("help", "", "Displays a list of commands")
}
execute(minecraft, args) {
minecraft.addMessageToChat("&2--- Showing help page ---");
minecraft.commandHandler.commands.forEach(command => {
minecraft.addMessageToChat("/" + command.command + " " + command.usage + " - " + command.description);
});
return true;
}
}
@@ -0,0 +1,28 @@
import Command from "../Command.js";
export default class TeleportCommand extends Command {
constructor() {
super("tp", "<x> <y> <y>", "Teleport to a position")
}
execute(minecraft, args) {
if (args.length !== 3) {
return false;
}
let x = parseInt(args[0]);
let y = parseInt(args[1]);
let z = parseInt(args[2]);
if (isNaN(x) || isNaN(y) || isNaN(z)) {
return false;
}
minecraft.player.setPosition(x, y, z);
minecraft.addMessageToChat("Teleported to " + x + " " + y + " " + z);
return true;
}
}
@@ -0,0 +1,48 @@
import Command from "../Command.js";
export default class TimeCommand extends Command {
constructor() {
super("time", "<set|add> <value>", "Change the time of the world")
}
execute(minecraft, args) {
if (args.length !== 2) {
return false;
}
let action = args[0];
let value = args[1];
if (action === "add") {
if (isNaN(value)) {
return false;
} else {
value = parseInt(value);
}
minecraft.world.time += value;
minecraft.addMessageToChat("Added " + value + " to the time");
} else if (action === "set") {
if (isNaN(value)) {
if (value === "day") {
value = 1000;
} else if (value === "night") {
value = 13000;
} else {
return false;
}
} else {
value = parseInt(value);
}
minecraft.world.time = value;
minecraft.addMessageToChat("Time set to " + value);
} else {
return false;
}
return true;
}
}
@@ -304,32 +304,32 @@ export default class PlayerEntity extends EntityLiving {
let sneaking = false;
if (this.minecraft.hasInGameFocus()) {
if (Keyboard.isKeyDown("KeyR")) { // R
if (Keyboard.isKeyDown("KeyR")) {
// this.respawn();
}
if (Keyboard.isKeyDown("KeyW")) { // W
if (Keyboard.isKeyDown("KeyW")) {
moveForward++;
}
if (Keyboard.isKeyDown("KeyS")) { // S
if (Keyboard.isKeyDown("KeyS")) {
moveForward--;
}
if (Keyboard.isKeyDown("KeyA")) { // A
if (Keyboard.isKeyDown("KeyA")) {
moveStrafe++;
}
if (Keyboard.isKeyDown("KeyD")) { // D
if (Keyboard.isKeyDown("KeyD")) {
moveStrafe--;
}
if (Keyboard.isKeyDown("Space")) { // Space
if (Keyboard.isKeyDown("Space")) {
jumping = true;
}
if (Keyboard.isKeyDown(this.minecraft.settings.sprinting)) {
if (Keyboard.isKeyDown(this.minecraft.settings.keySprinting)) {
if (this.moveForward > 0 && !this.sneaking && !this.sprinting && this.motionX !== 0 && this.motionZ !== 0) {
this.sprinting = true;
this.updateFOVModifier();
}
}
if (Keyboard.isKeyDown(this.minecraft.settings.crouching)) { // Q
if (Keyboard.isKeyDown(this.minecraft.settings.keyCrouching)) {
sneaking = true;
}
@@ -0,0 +1,54 @@
import Gui from "../Gui.js";
import ChatLine from "../../../util/ChatLine.js";
import GuiChat from "../screens/GuiChat.js";
import MathHelper from "../../../util/MathHelper.js";
export default class ChatOverlay extends Gui {
constructor(minecraft) {
super(minecraft);
this.messages = [];
this.sentHistory = [];
}
render(stack, mouseX, mouseY, partialTicks) {
let chatOpen = this.minecraft.currentScreen instanceof GuiChat;
for (let i = 0; i < this.messages.length; i++) {
let message = this.messages[i];
if (message.updateCounter >= 200 && !chatOpen) {
continue;
}
let opacity = MathHelper.clamp((1.0 - message.updateCounter / 200) * 10, 0.0, 1.0);
let alpha = Math.floor(255 * opacity * opacity);
if (chatOpen) {
alpha = 255;
}
if (alpha > 0) {
let y = this.minecraft.window.height - 40 - i * 9;
this.drawRect(stack, 2, y - 1, 2 + 320, y + 8, '#000000', alpha / 2 / 255);
this.drawString(stack, message.message, 2, y, 0xffffff + (alpha << 24));
}
}
}
onTick() {
for (let i = 0; i < this.messages.length; i++) {
let message = this.messages[i];
message.updateCounter++;
}
}
addMessage(message) {
this.messages.splice(0, 0, new ChatLine(message));
}
addMessageToSentHistory(message) {
this.sentHistory.splice(0, 0, message);
}
}
@@ -1,5 +1,6 @@
import Gui from "./Gui.js";
import Block from "../world/block/Block.js";
import Gui from "../Gui.js";
import Block from "../../world/block/Block.js";
import ChatOverlay from "./ChatOverlay.js";
export default class IngameOverlay extends Gui {
@@ -8,6 +9,8 @@ export default class IngameOverlay extends Gui {
this.minecraft = minecraft;
this.window = window;
this.chatOverlay = new ChatOverlay(minecraft);
this.textureCrosshair = minecraft.resources["gui/icons.png"];
this.textureHotbar = minecraft.resources["gui/gui.png"];
}
@@ -21,6 +24,9 @@ export default class IngameOverlay extends Gui {
// Render hotbar
this.renderHotbar(stack, this.window.width / 2 - 91, this.window.height - 22);
// Render chat
this.chatOverlay.render(stack, mouseX, mouseY, partialTicks);
let world = this.minecraft.world;
let player = this.minecraft.player;
@@ -38,6 +44,10 @@ export default class IngameOverlay extends Gui {
this.drawString(stack, x + ", " + y + ", " + z + " (" + (x >> 4) + ", " + (y >> 4) + ", " + (z >> 4) + ")", 1, 1 + 9);
}
onTick() {
this.chatOverlay.onTick();
}
renderCrosshair(stack, x, y) {
let size = 15;
this.drawSprite(stack, this.textureCrosshair, 0, 0, 15, 15, x - size / 2, y - size / 2, size, size, 0.6);
@@ -0,0 +1,76 @@
import GuiScreen from "../GuiScreen.js";
import GuiTextField from "../widgets/GuiTextField.js";
export default class GuiChat extends GuiScreen {
constructor() {
super();
this.inputField = new GuiTextField(0, 0, 0, 0);
this.inputField.renderBackground = false;
this.historyIndex = -1;
}
init() {
super.init();
this.inputField.x = 2;
this.inputField.y = this.height - 14;
this.inputField.width = this.width - 4;
this.inputField.height = 12;
this.inputField.isFocused = true;
this.buttonList.push(this.inputField);
}
drawScreen(stack, mouseX, mouseY, partialTicks) {
this.drawRect(stack, 2, this.height - 14, this.width - 2, this.height - 2, '#000000', 0.5);
super.drawScreen(stack, mouseX, mouseY, partialTicks);
}
keyTyped(key, character) {
if (key === "Enter") {
let message = this.inputField.getText().trim();
if (message.length === 0) {
return;
}
// Close screen
this.minecraft.displayScreen(null);
// Add message to sent history
this.minecraft.ingameOverlay.chatOverlay.addMessageToSentHistory(message);
// Handle message
if (message.startsWith("/")) {
this.minecraft.commandHandler.handleMessage(message.substring(1));
} else {
this.minecraft.addMessageToChat(message);
}
return;
}
if (key === "ArrowUp" || key === "ArrowDown") {
let up = key === "ArrowUp";
let history = this.minecraft.ingameOverlay.chatOverlay.sentHistory;
if (up) {
if (this.historyIndex + 1 < history.length) {
this.historyIndex++;
}
} else {
if (this.historyIndex >= 0) {
this.historyIndex--;
}
}
this.inputField.text = this.historyIndex < 0 ? "" : history[this.historyIndex];
return;
}
return super.keyTyped(key, character);
}
}
@@ -23,16 +23,20 @@ export default class GuiControls extends GuiScreen {
return name + ": " + value + "%";
}));
this.buttonList.push(new GuiKeyButton("Crouch", settings.crouching, this.width / 2 - 100, y + 24, 200, 20, key => {
settings.crouching = key;
this.buttonList.push(new GuiKeyButton("Crouch", settings.keyCrouching, this.width / 2 - 100, y + 24, 200, 20, key => {
settings.keyCrouching = key;
}));
this.buttonList.push(new GuiKeyButton("Sprint", settings.sprinting, this.width / 2 - 100, y + 24 * 2, 200, 20, key => {
settings.sprinting = key;
this.buttonList.push(new GuiKeyButton("Sprint", settings.keySprinting, this.width / 2 - 100, y + 24 * 2, 200, 20, key => {
settings.keySprinting = key;
}));
this.buttonList.push(new GuiKeyButton("Toggle Perspective", settings.togglePerspective, this.width / 2 - 100, y + 24 * 3, 200, 20, key => {
settings.togglePerspective = key;
this.buttonList.push(new GuiKeyButton("Toggle Perspective", settings.keyTogglePerspective, this.width / 2 - 100, y + 24 * 3, 200, 20, key => {
settings.keyTogglePerspective = key;
}));
this.buttonList.push(new GuiKeyButton("Open Chat", settings.keyOpenChat, this.width / 2 - 100, y + 24 * 4, 200, 20, key => {
settings.keyOpenChat = key;
}));
this.buttonList.push(new GuiButton("Done", this.width / 2 - 100, y + 130, 200, 20, () => {
@@ -64,11 +64,11 @@ export default class GuiMainMenu extends GuiScreen {
this.drawLogo(stack, x, y);
// Draw version
this.drawString(stack, "js-minecraft " + Minecraft.VERSION, 2, this.height - 10, 0xFFFFFF);
this.drawString(stack, "js-minecraft " + Minecraft.VERSION, 2, this.height - 10, 0xFFFFFFff);
// Draw copyright
let mouseOver = mouseX > this.width / 2 + 70 && mouseY > this.height - 20;
this.drawRightString(stack, "GitHub @LabyStudio/js-minecraft", this.width - 2, this.height - 10, mouseOver ? 0x0000FF : 0xFFFFFF);
this.drawRightString(stack, "GitHub @LabyStudio/js-minecraft", this.width - 2, this.height - 10, mouseOver ? 0x0000FFFF : 0xFFFFFFff);
// Draw buttons
super.drawScreen(stack, mouseX, mouseY, partialTicks);
@@ -9,15 +9,18 @@ export default class GuiTextField extends GuiButton {
this.isFocused = false;
this.cursorCounter = 0;
this.maxLength = 80;
this.renderBackground = true;
}
render(stack, mouseX, mouseY, partialTicks) {
let cursorVisible = this.isFocused && Math.floor(this.cursorCounter / 6) % 2 === 0;
let textColor = this.enabled ? 14737632 : 7368816;
let textColor = this.enabled ? 0xe0e0e0ff : 0x707070ff;
// Draw background
this.drawRect(stack, this.x - 1, this.y - 1, this.x + this.width + 1, this.y + this.height + 1, '#5f5f60');
this.drawRect(stack, this.x, this.y, this.x + this.width, this.y + this.height, 'black');
if (this.renderBackground) {
this.drawRect(stack, this.x - 1, this.y - 1, this.x + this.width + 1, this.y + this.height + 1, '#5f5f60');
this.drawRect(stack, this.x, this.y, this.x + this.width, this.y + this.height, 'black');
}
// Draw text
this.drawString(stack, this.text, this.x + 2, this.y + this.height / 2 - 4, textColor);
@@ -41,6 +44,10 @@ export default class GuiTextField extends GuiButton {
}
keyTyped(key, character) {
if (!this.isFocused || !this.enabled) {
return;
}
if (key === "Backspace") {
if (this.text.length > 0) {
this.text = this.text.substring(0, this.text.length - 1);
@@ -70,6 +77,10 @@ export default class GuiTextField extends GuiButton {
return;
}
if (character.length !== 1) {
return;
}
if (this.text.length < this.maxLength) {
this.text += character;
}
@@ -41,6 +41,10 @@ export default class BlockRenderer {
}
renderFace(world, block, boundingBox, face, ambientOcclusion, x, y, z) {
let chunkX = x >> 4;
let chunkY = y >> 4;
let chunkZ = z >> 4;
// Vertex mappings
let minX = x + boundingBox.minX;
let minY = y + boundingBox.minY;
@@ -78,55 +82,55 @@ export default class BlockRenderer {
// this.tessellator.setAlpha(1 - block.getTransparency());
// Add face to tessellator
this.addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red, green, blue);
this.addFace(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red, green, blue);
}
addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red = 1, green = 1, blue = 1) {
addFace(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red = 1, green = 1, blue = 1) {
if (face === EnumBlockFace.BOTTOM) {
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, maxZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, maxZ, minU, maxV, red, green, blue);
}
if (face === EnumBlockFace.TOP) {
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, maxZ, maxU, maxV, red, green, blue);
}
if (face === EnumBlockFace.NORTH) {
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, minZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, minZ, maxU, minV, red, green, blue);
}
if (face === EnumBlockFace.SOUTH) {
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, maxZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, maxZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, maxZ, maxU, maxV, red, green, blue);
}
if (face === EnumBlockFace.WEST) {
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, maxZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, minZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, maxZ, minU, minV, red, green, blue);
}
if (face === EnumBlockFace.EAST) {
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, maxZ, maxU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, minZ, minU, minV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, minZ, minU, maxV, red, green, blue);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, minY, maxZ, maxU, maxV, red, green, blue);
}
}
addBlockCorner(world, face, ambientOcclusion, x, y, z, u, v, red, green, blue) {
addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, x, y, z, u, v, red, green, blue) {
// Smooth lightning
if (ambientOcclusion) {
this.setAverageBrightness(world, face, x, y, z, red, green, blue);
}
this.tessellator.addVertexWithUV(x, y, z, u, v);
this.tessellator.addVertexWithUV(x - (chunkX << 4), y - (chunkY << 4), z - (chunkZ << 4), u, v);
}
setAverageBrightness(world, face, x, y, z, red = 1, green = 1, blue = 1) {
@@ -176,6 +180,10 @@ export default class BlockRenderer {
}
renderTorch(world, block, x, y, z) {
let chunkX = x >> 4;
let chunkY = y >> 4;
let chunkZ = z >> 4;
// Thickness of the torch
let size = 1 / 16;
@@ -238,37 +246,37 @@ export default class BlockRenderer {
this.tessellator.setColor(1, 1, 1);
// Add faces to tessellator
this.addDistortFace(world, EnumBlockFace.NORTH, false, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.EAST, false, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.SOUTH, false, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.WEST, false, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addFace(world, EnumBlockFace.TOP, false, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV + 8 / 256);
this.addDistortFace(world, EnumBlockFace.NORTH, false, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.EAST, false, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.SOUTH, false, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addDistortFace(world, EnumBlockFace.WEST, false, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
this.addFace(world, EnumBlockFace.TOP, false, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV + 8 / 256);
}
addDistortFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ) {
addDistortFace(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ) {
if (face === EnumBlockFace.NORTH) {
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, minX + distortX, minY, minZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, maxX + distortX, minY, minZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, minZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX + distortX, minY, minZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX + distortX, minY, minZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, minZ, maxU, minV);
}
if (face === EnumBlockFace.SOUTH) {
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, maxX + distortX, minY, maxZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, minX + distortX, minY, maxZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, maxZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, maxZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX + distortX, minY, maxZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX + distortX, minY, maxZ + distortZ, maxU, maxV);
}
if (face === EnumBlockFace.WEST) {
this.addBlockCorner(world, face, ambientOcclusion, minX + distortX, minY, maxZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, minX + distortX, minY, minZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX + distortX, minY, maxZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX + distortX, minY, minZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, minZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, minX, maxY, maxZ, minU, minV);
}
if (face === EnumBlockFace.EAST) {
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, maxX + distortX, minY, minZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, maxX + distortX, minY, maxZ + distortZ, maxU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, maxZ, maxU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX, maxY, minZ, minU, minV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX + distortX, minY, minZ + distortZ, minU, maxV);
this.addBlockCorner(world, face, ambientOcclusion, chunkX, chunkY, chunkZ, maxX + distortX, minY, maxZ + distortZ, maxU, maxV);
}
}
@@ -62,10 +62,13 @@ export default class FontRenderer {
this.setColor(stack, color, isShadow);
}
let alpha = ((color & 0xFF000000) >>> 24) / 255;
// For each character
for (let i = 0; i < string.length; i++) {
let character = string[i];
let code = string[i].charCodeAt(0);
let index = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000".indexOf(character);
let code = character.charCodeAt(0);
// Handle color codes if character is &
if (character === '&' && i !== string.length - 1) {
@@ -81,8 +84,8 @@ export default class FontRenderer {
}
// Get character offset in bitmap
let textureOffsetX = code % FontRenderer.BITMAP_SIZE * FontRenderer.FIELD_SIZE;
let textureOffsetY = Math.floor(code / FontRenderer.BITMAP_SIZE) * FontRenderer.FIELD_SIZE;
let textureOffsetX = index % FontRenderer.BITMAP_SIZE * FontRenderer.FIELD_SIZE;
let textureOffsetY = Math.floor(index / FontRenderer.BITMAP_SIZE) * FontRenderer.FIELD_SIZE;
// Draw character
Gui.drawSprite(
@@ -91,7 +94,8 @@ export default class FontRenderer {
textureOffsetX, textureOffsetY,
FontRenderer.FIELD_SIZE, FontRenderer.FIELD_SIZE,
Math.floor(x), Math.floor(y),
FontRenderer.FIELD_SIZE, FontRenderer.FIELD_SIZE
FontRenderer.FIELD_SIZE, FontRenderer.FIELD_SIZE,
alpha
);
// Increase drawing cursor
@@ -23,6 +23,10 @@ export default class ChunkSection {
this.boundingBox.max.z = z * ChunkSection.SIZE + ChunkSection.SIZE;
this.group = new THREE.Object3D();
this.group.position.x = this.x * ChunkSection.SIZE;
this.group.position.y = this.y * ChunkSection.SIZE;
this.group.position.z = this.z * ChunkSection.SIZE;
this.group.updateMatrix();
this.group.matrixAutoUpdate = false;
this.isModified = true;
+6
View File
@@ -0,0 +1,6 @@
export default class ChatLine {
constructor(message) {
this.message = message;
this.updateCounter = 0;
}
}