[blocks.lua] Portal block added. Send PlayerChangeDimension on right-click.

This commit is contained in:
Quentin Bazin 2020-03-08 15:28:46 +01:00
parent 81986cb55d
commit be1e49cfe0
22 changed files with 119 additions and 64 deletions

View File

@ -173,6 +173,16 @@ void ClientCommandHandler::setupCallbacks() {
}
});
m_client.setCommandCallback(Network::Command::PlayerChangeDimension, [this](sf::Packet &packet) {
u16 clientId, dimension;
s32 x, y, z;
packet >> clientId >> x >> y >> z >> dimension;
if (clientId == m_client.id()) {
DEBUG("PlayerChangeDimension received:", clientId, x, y, z, dimension);
}
});
m_client.setCommandCallback(Network::Command::BlockGUIData, [this](sf::Packet &packet) {
gk::ApplicationStateStack::getInstance().push<LuaGUIState>(*this, m_player, m_world, packet, &gk::ApplicationStateStack::getInstance().top());
});

View File

@ -32,33 +32,34 @@
std::string Network::commandToString(Network::Command command) {
std::map<Network::Command, std::string> commandNames = {
{Network::Command::ClientConnect, "ClientConnect"},
{Network::Command::ClientDisconnect, "ClientDisconnect"},
{Network::Command::ClientOk, "ClientOk"},
{Network::Command::ClientRefused, "ClientRefused"},
{Network::Command::ClientConnect, "ClientConnect"},
{Network::Command::ClientDisconnect, "ClientDisconnect"},
{Network::Command::ClientOk, "ClientOk"},
{Network::Command::ClientRefused, "ClientRefused"},
{Network::Command::KeyState, "KeyState"},
{Network::Command::KeyState, "KeyState"},
{Network::Command::ChunkData, "ChunkData"},
{Network::Command::ChunkRequest, "ChunkRequest"},
{Network::Command::ChunkData, "ChunkData"},
{Network::Command::ChunkRequest, "ChunkRequest"},
{Network::Command::PlayerPlaceBlock, "PlayerPlaceBlock"},
{Network::Command::PlayerDigBlock, "PlayerDigBlock"},
{Network::Command::PlayerInvUpdate, "PlayerInvUpdate"},
{Network::Command::PlayerPosUpdate, "PlayerPosUpdate"},
{Network::Command::PlayerSpawn, "PlayerSpawn"},
{Network::Command::PlayerInventory, "PlayerInventory"},
{Network::Command::PlayerCreativeWindow, "PlayerCreativeWindow"},
{Network::Command::PlayerPlaceBlock, "PlayerPlaceBlock"},
{Network::Command::PlayerDigBlock, "PlayerDigBlock"},
{Network::Command::PlayerInvUpdate, "PlayerInvUpdate"},
{Network::Command::PlayerPosUpdate, "PlayerPosUpdate"},
{Network::Command::PlayerSpawn, "PlayerSpawn"},
{Network::Command::PlayerInventory, "PlayerInventory"},
{Network::Command::PlayerCreativeWindow, "PlayerCreativeWindow"},
{Network::Command::PlayerChangeDimension, "PlayerChangeDimension"},
{Network::Command::BlockUpdate, "BlockUpdate"},
{Network::Command::BlockActivated, "BlockActivated"},
{Network::Command::BlockGUIData, "BlockGUIData"},
{Network::Command::BlockInvUpdate, "BlockInvUpdate"},
{Network::Command::BlockDataUpdate, "BlockDataUpdate"},
{Network::Command::BlockUpdate, "BlockUpdate"},
{Network::Command::BlockActivated, "BlockActivated"},
{Network::Command::BlockGUIData, "BlockGUIData"},
{Network::Command::BlockInvUpdate, "BlockInvUpdate"},
{Network::Command::BlockDataUpdate, "BlockDataUpdate"},
{Network::Command::RegistryData, "RegistryData"},
{Network::Command::RegistryData, "RegistryData"},
{Network::Command::ChatMessage, "ChatMessage"}
{Network::Command::ChatMessage, "ChatMessage"}
};
return commandNames[command];
}

View File

@ -32,39 +32,40 @@
namespace Network {
enum class Command {
// Client commands
ClientConnect = 0, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
ClientDisconnect = 1, // <TCP> [NetworkCommand] (from Client only)
ClientOk = 2, // <TCP> [NetworkCommand][u16 client id] (from Server only)
ClientRefused = 3, // <TCP> [NetworkCommand] (from Server only)
ClientConnect = 0, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
ClientDisconnect = 1, // <TCP> [NetworkCommand] (from Client only)
ClientOk = 2, // <TCP> [NetworkCommand][u16 client id] (from Server only)
ClientRefused = 3, // <TCP> [NetworkCommand] (from Server only)
// Input commands
KeyState = 4, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
KeyState = 4, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
// Chunk commands
ChunkData = 5, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 6, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
ChunkData = 5, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 6, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
// Player commands
PlayerPlaceBlock = 7, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 8, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 9, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 10, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 11, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 12, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerCreativeWindow = 13, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerPlaceBlock = 7, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 8, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 9, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 10, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 11, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 12, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerCreativeWindow = 13, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerChangeDimension = 14, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only)
// Block commands
BlockUpdate = 14, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 15, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 16, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 17, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 18, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
BlockUpdate = 15, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 16, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 17, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 18, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 19, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
// Registry commands
RegistryData = 19, // <TCP> [NetworkCommand][Block block] (from Server only)
RegistryData = 20, // <TCP> [NetworkCommand][Block block] (from Server only)
// Chat commands
ChatMessage = 20, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
ChatMessage = 21, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
};
std::string commandToString(Command command);

View File

@ -194,3 +194,20 @@ mod:block {
bounding_box = {0, 0, 0, 1, 1, 0.5}
}
mod:block {
id = "portal",
name = "Portal",
tiles = "portal.png",
-- FIXME: Use another layer for transparent blocks like this one
draw_type = "glass",
is_opaque = false,
on_block_activated = function(pos, player, world, client, server, screen_width, screen_height, gui_scale)
local dim = (player:dimension() + 1) % 2
server:send_player_change_dimension(client.id, 0, 0, 20, dim, client);
player:set_dimension(dim);
end,
}

View File

@ -36,7 +36,7 @@ mod:block {
world:add_block_data(pos.x, pos.y, pos.z, 3, 1)
end,
on_block_activated = function(pos, player, world, client, screen_width, screen_height, gui_scale)
on_block_activated = function(pos, player, world, client, server, screen_width, screen_height, gui_scale)
local gui = LuaGUI.new()
gui:set_size(176, 166)
@ -155,7 +155,7 @@ mod:block {
gui:show(client)
end,
on_tick = function(pos, player, chunk, world)
on_tick = function(pos, chunk, world)
local data = world:get_block_data(pos.x, pos.y, pos.z)
if not data then return end

View File

@ -55,6 +55,7 @@ function init(player)
player_inv:add_stack("default:iron_ore", 64);
player_inv:add_stack("default:coal", 64);
player_inv:add_stack("default:oak_slab", 64);
player_inv:add_stack("default:portal", 64);
player_inv:add_stack("default:iron_ingot", 64);
player_inv:add_stack("default:gold_ingot", 64);
@ -160,6 +161,7 @@ function show_creative_window(client, screen_width, screen_height, gui_scale)
{"default:bricks"},
{"default:clay"},
{"default:oak_slab"},
{"default:portal"},
-- Items
{"default:stick"},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

View File

@ -34,7 +34,7 @@ mod:block {
world:add_block_data(pos.x, pos.y, pos.z, 3, 3)
end,
on_block_activated = function(pos, player, world, client, screen_width, screen_height, gui_scale)
on_block_activated = function(pos, player, world, client, server, screen_width, screen_height, gui_scale)
local gui = LuaGUI.new()
gui:set_size(176, 166)

View File

@ -88,7 +88,7 @@ int ServerApplication::run(bool isProtected) {
}
void ServerApplication::update() {
m_worldController.update(m_players);
m_worldController.update();
if (gk::GameClock::getTicks() % 100 < 10) {
for (auto &it : m_players) {

View File

@ -30,6 +30,7 @@
#include "LuaMod.hpp"
#include "Registry.hpp"
#include "ScriptEngine.hpp"
#include "ServerCommandHandler.hpp"
#include "ServerPlayer.hpp"
#include "ServerWorld.hpp"
@ -80,7 +81,10 @@ void ScriptEngine::initUsertypes() {
);
m_lua.new_usertype<Player>("Player",
"inventory", &Player::inventory
"inventory", &Player::inventory,
"dimension", &Player::dimension,
"set_dimension", &Player::setDimension
);
m_lua.new_usertype<ServerPlayer>("ServerPlayer",
@ -124,6 +128,14 @@ void ScriptEngine::initUsertypes() {
"set_int", &BlockMetadata::setInt
);
m_lua.new_usertype<ClientInfo>("ClientInfo",
"id", &ClientInfo::id
);
m_lua.new_usertype<ServerCommandHandler>("ServerCommandHandler",
"send_player_change_dimension", &ServerCommandHandler::sendPlayerChangeDimension
);
LuaCore::initUsertype(m_lua);
LuaMod::initUsertype(m_lua);
LuaGUI::initUsertype(m_lua);

View File

@ -69,6 +69,17 @@ void ServerCommandHandler::sendPlayerPosUpdate(u16 clientID, bool isTeleportatio
client->tcpSocket->send(packet);
}
void ServerCommandHandler::sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client) const {
sf::Packet packet;
packet << Network::Command::PlayerChangeDimension;
packet << clientID << x << y << z << dimension;
if (!client)
m_server.sendToAllClients(packet);
else
client->tcpSocket->send(packet);
}
void ServerCommandHandler::sendChatMessage(u16 clientID, const std::string &message, const ClientInfo *client) const {
sf::Packet packet;
packet << Network::Command::ChatMessage << clientID << message;
@ -209,7 +220,8 @@ void ServerCommandHandler::setupCallbacks() {
ServerWorld &world = getWorldForClient(client.id);
u16 id = world.getBlock(x, y, z);
((ServerBlock &)(m_registry.getBlock(id))).onBlockActivated({x, y, z}, m_players.at(client.id), world, client, screenWidth, screenHeight, guiScale);
ServerBlock &block = (ServerBlock &)(m_registry.getBlock(id));
block.onBlockActivated({x, y, z}, m_players.at(client.id), world, client, *this, screenWidth, screenHeight, guiScale);
});
m_server.setCommandCallback(Network::Command::BlockInvUpdate, [this](ClientInfo &client, sf::Packet &packet) {

View File

@ -50,6 +50,7 @@ class ServerCommandHandler {
void sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client = nullptr) const;
void sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client = nullptr) const;
void sendPlayerPosUpdate(u16 clientID, bool isTeleportation = false, const ClientInfo *client = nullptr) const;
void sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client = nullptr) const;
void sendChatMessage(u16 clientID, const std::string &message, const ClientInfo *client = nullptr) const;
void setupCallbacks();

View File

@ -31,10 +31,10 @@
#include "ServerPlayer.hpp"
#include "World.hpp"
void ServerBlock::onTick(const glm::ivec3 &pos, std::unordered_map<u16, ServerPlayer> &players, Chunk &chunk, World &world, ServerCommandHandler &server) const {
void ServerBlock::onTick(const glm::ivec3 &pos, Chunk &chunk, World &world, ServerCommandHandler &server) const {
try {
if (m_onTick && m_onTickEnabled) {
m_onTick(pos, players, chunk, world);
m_onTick(pos, chunk, world);
BlockData *blockData = world.getBlockData(pos.x, pos.y, pos.z);
if (blockData) {
@ -55,10 +55,10 @@ void ServerBlock::onTick(const glm::ivec3 &pos, std::unordered_map<u16, ServerPl
}
}
bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, u16 screenWidth, u16 screenHeight, u8 guiScale) const {
bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const {
try {
if (m_onBlockActivated) {
m_onBlockActivated(pos, player, world, client, screenWidth, screenHeight, guiScale);
m_onBlockActivated(pos, player, world, client, server, screenWidth, screenHeight, guiScale);
return true;
}
}

View File

@ -38,8 +38,8 @@ class ServerBlock : public Block {
ServerBlock(u32 id, const TilesDef &tiles, const std::string &name, const std::string &label)
: Block(id, tiles, name, label) {}
void onTick(const glm::ivec3 &, std::unordered_map<u16, ServerPlayer> &, Chunk &, World &, ServerCommandHandler &) const;
bool onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, u16 screenWidth, u16 screenHeight, u8 guiScale) const;
void onTick(const glm::ivec3 &, Chunk &, World &, ServerCommandHandler &) const;
bool onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const;
void onBlockPlaced(const glm::ivec3 &pos, World &world) const;
bool canUpdate() const { return m_onTick.valid(); }

View File

@ -42,15 +42,14 @@ void ServerChunk::onBlockPlaced(int x, int y, int z, const Block &block) const {
serverBlock.onBlockPlaced(glm::ivec3{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_DEPTH, z + m_z * CHUNK_HEIGHT}, m_world);
}
void ServerChunk::tick(std::unordered_map<u16, ServerPlayer> &players, World &world, ServerCommandHandler &server) {
void ServerChunk::tick(World &world, ServerCommandHandler &server) {
if (!m_tickingBlocks.empty()) {
for (auto &it : m_tickingBlocks) {
int z = it.first / (width * height);
int y = (it.first - z * (width * height)) / width;
int x = (it.first - z * (width * height)) % width;
((ServerBlock &)it.second).onTick(
glm::ivec3{x + m_x * width, y + m_y * depth, z + m_z * height},
players, *this, world, server);
glm::ivec3{x + m_x * width, y + m_y * depth, z + m_z * height}, *this, world, server);
}
}
}

View File

@ -41,7 +41,7 @@ class ServerChunk : public Chunk {
void updateLights();
void onBlockPlaced(int x, int y, int z, const Block &block) const;
void tick(std::unordered_map<u16, ServerPlayer> &players, World &world, ServerCommandHandler &server);
void tick(World &world, ServerCommandHandler &server);
bool isSent() const { return m_isSent; }
void setSent(bool isSent) { m_isSent = isSent; }

View File

@ -33,12 +33,12 @@
#include "ServerPlayer.hpp"
#include "ServerWorld.hpp"
void ServerWorld::update(std::unordered_map<u16, ServerPlayer> &players) {
void ServerWorld::update() {
if (m_lastTick < gk::GameClock::getTicks() / 50) {
m_lastTick = gk::GameClock::getTicks() / 50;
for (auto &it : m_chunks) {
it.second->tick(players, *this, *m_server);
it.second->tick(*this, *m_server);
if (it.second->areAllNeighboursLoaded())
it.second->updateLights();

View File

@ -44,7 +44,7 @@ class ServerWorld : public World {
public:
ServerWorld(const Dimension &dimension) : m_dimension(dimension) {}
void update(std::unordered_map<u16, ServerPlayer> &players);
void update();
void createChunkNeighbours(ServerChunk *chunk);
void sendChunkData(const ClientInfo &client, ServerChunk *chunk);

View File

@ -34,8 +34,8 @@ void WorldController::init() {
}
}
void WorldController::update(std::unordered_map<u16, ServerPlayer> &players) {
void WorldController::update() {
for (auto &it : m_worldList)
it.update(players);
it.update();
}

View File

@ -40,7 +40,7 @@ class WorldController {
void init();
void update(std::unordered_map<u16, ServerPlayer> &players);
void update();
ServerWorld &getWorld(u16 dimension) { return m_worldList.at(dimension); }