Now saving last hotbar slot.

master
Quentin Bazin 2020-07-17 23:32:50 +02:00
parent c7a5d61ece
commit 7eaac50d48
13 changed files with 96 additions and 57 deletions

View File

@ -106,6 +106,7 @@
- `void set_dimension(u16 dimension)`
- `u16 client_id()`
- `Inventory *inventory()`
- `ItemStack held_item_stack()`
## Recipe
@ -144,7 +145,6 @@
## ServerPlayer
- `const ClientInfo &client()`
- `ItemStack held_item_stack()`
- `bool is_online()`
## ServerWorld

View File

@ -78,6 +78,7 @@ Packet sent at the beginning of every server tick.
| ------------- | ----------- | ---------------------------------------------------- |
| ID | u16 | Player ID |
| Inventory | Inventory | Player inventory |
| Current slot | s8 | Player held item slot |
#### PlayerPosUpdate (clientbound)

View File

@ -287,6 +287,7 @@ mod:block {
on_block_destroyed = function(pos, world)
if world:get_block(pos.x, pos.y, pos.z + 1) == world:get_block(pos.x, pos.y, pos.z) then
-- FIXME: Make something like "player:break_block(pos.x, pos.y, pos.z + 1)"
world:set_block(pos.x, pos.y, pos.z + 1, 0)
end
end,

View File

@ -48,10 +48,13 @@ BlockCursor::BlockCursor(ClientPlayer &player, ClientWorld &world, ClientCommand
}
void BlockCursor::onEvent(const SDL_Event &event, const Hotbar &hotbar) {
int cursorPos = hotbar.cursorPos();
if (cursorPos == -1) return;
if (event.type == SDL_MOUSEBUTTONDOWN && m_selectedBlock.w != -1) {
if (event.button.button == SDL_BUTTON_LEFT) {
m_animationStart = gk::GameClock::getInstance().getTicks();
m_currentTool = &m_player.inventory().getStack(hotbar.cursorPos(), 0);
m_currentTool = &m_player.inventory().getStack(cursorPos, 0);
}
else if (event.button.button == SDL_BUTTON_RIGHT) {
if (m_animationStart != 0)
@ -117,8 +120,8 @@ void BlockCursor::onEvent(const SDL_Event &event, const Hotbar &hotbar) {
m_client.sendPlayerPlaceBlock(x, y, z, block);
const ItemStack &currentStack = m_player.inventory().getStack(hotbar.cursorPos(), 0);
m_player.inventory().setStack(hotbar.cursorPos(), 0, currentStack.amount() > 1 ? currentStack.item().stringID() : "", currentStack.amount() - 1);
const ItemStack &currentStack = m_player.inventory().getStack(cursorPos, 0);
m_player.inventory().setStack(cursorPos, 0, currentStack.amount() > 1 ? currentStack.item().stringID() : "", currentStack.amount() - 1);
m_client.sendPlayerInvUpdate();
}
@ -152,43 +155,47 @@ void BlockCursor::update(const Hotbar &hotbar) {
if (selectedBlockChanged)
m_animationStart = (m_animationStart) ? ticks : 0;
const ItemStack &currentStack = m_player.inventory().getStack(hotbar.cursorPos(), 0);
float timeToBreak = 0;
if (m_animationStart) {
if (m_currentTool->item().id() != currentStack.item().id()) {
m_animationStart = ticks;
m_currentTool = &currentStack;
}
else {
bool isEffective = false;
for (auto &it : currentStack.item().effectiveOn()) {
if (m_currentBlock->block().hasGroup(it)) {
isEffective = true;
break;
// FIXME: This should use block param
u8f orientation = m_currentBlock->block().isRotatable() ? m_world.getData(selectedBlock.x, selectedBlock.y, selectedBlock.z) & 0x1F : 0;
int cursorPos = hotbar.cursorPos();
if (cursorPos != -1) {
float timeToBreak = 0;
if (m_animationStart) {
const ItemStack &currentStack = m_player.inventory().getStack(cursorPos, 0);
if (m_currentTool->item().id() != currentStack.item().id()) {
m_animationStart = ticks;
m_currentTool = &currentStack;
}
else {
bool isEffective = false;
for (auto &it : currentStack.item().effectiveOn()) {
if (m_currentBlock->block().hasGroup(it)) {
isEffective = true;
break;
}
}
timeToBreak = m_currentBlock->timeToBreak(currentStack.item().harvestCapability(), currentStack.item().miningSpeed(), isEffective);
if (ticks > m_animationStart + timeToBreak * 1000) {
m_world.setBlock(m_selectedBlock.x, m_selectedBlock.y, m_selectedBlock.z, 0);
m_animationStart = ticks;
m_client.sendPlayerDigBlock(m_selectedBlock);
}
}
timeToBreak = m_currentBlock->timeToBreak(currentStack.item().harvestCapability(), currentStack.item().miningSpeed(), isEffective);
if (ticks > m_animationStart + timeToBreak * 1000) {
m_world.setBlock(m_selectedBlock.x, m_selectedBlock.y, m_selectedBlock.z, 0);
m_animationStart = ticks;
m_client.sendPlayerDigBlock(m_selectedBlock);
}
}
}
u8f orientation = m_currentBlock->block().isRotatable() ? m_world.getData(selectedBlock.x, selectedBlock.y, selectedBlock.z) & 0x1F : 0;
if (m_animationStart && m_currentBlock)
updateAnimationVertexBuffer(*m_currentBlock, orientation,
(ticks - m_animationStart) / (timeToBreak * 100));
}
if (m_selectedBlock.w != -1)
updateVertexBuffer(*m_currentBlock, orientation);
else
m_currentBlock = nullptr;
if (m_animationStart && m_currentBlock)
updateAnimationVertexBuffer(*m_currentBlock, orientation,
(ticks - m_animationStart) / (timeToBreak * 100));
}
using namespace BlockGeometry;

View File

@ -35,7 +35,7 @@
#include "HUD.hpp"
HUD::HUD(ClientPlayer &player, ClientWorld &world, ClientCommandHandler &client)
: m_hotbar(player.inventory(), client),
: m_hotbar(player, client),
m_blockCursor(player, world, client),
m_debugOverlay(player, world),
m_chat(client.client())

View File

@ -25,11 +25,12 @@
* =====================================================================================
*/
#include "ClientCommandHandler.hpp"
#include "ClientPlayer.hpp"
#include "Config.hpp"
#include "Hotbar.hpp"
Hotbar::Hotbar(Inventory &inventory, ClientCommandHandler &client, Widget *parent)
: Widget(182, 22, parent), m_inventory(inventory), m_client(client)
Hotbar::Hotbar(ClientPlayer &player, ClientCommandHandler &client, Widget *parent)
: Widget(182, 22, parent), m_player(player), m_client(client)
{
m_background.load("texture-widgets");
m_background.setClipRect(0, 0, 182, 22);
@ -41,13 +42,17 @@ Hotbar::Hotbar(Inventory &inventory, ClientCommandHandler &client, Widget *paren
}
void Hotbar::onEvent(const SDL_Event &event) {
if (m_cursorPos == -1) return;
if (event.type == SDL_MOUSEWHEEL) {
if (event.wheel.y < 0) {
m_cursorPos = (m_cursorPos + 1) % 9;
m_player.setHeldItemSlot(m_cursorPos);
m_client.sendPlayerHeldItemChanged(m_cursorPos, currentItem().id());
}
else if (event.wheel.y > 0) {
m_cursorPos = (m_cursorPos == 0) ? 8 : m_cursorPos - 1;
m_player.setHeldItemSlot(m_cursorPos);
m_client.sendPlayerHeldItemChanged(m_cursorPos, currentItem().id());
}
@ -56,18 +61,33 @@ void Hotbar::onEvent(const SDL_Event &event) {
}
void Hotbar::update() {
if (m_cursorPos == -1) {
if (m_player.heldItemSlot() == -1)
return;
m_cursorPos = m_player.heldItemSlot();
m_cursor.setPosition(-1 + 20 * m_cursorPos, -1, 0);
}
for (u16 i = 0 ; i < 9 ; ++i) {
if (m_items.size() <= i) {
m_items.emplace_back(m_inventory, i, 0);
m_items.emplace_back(m_player.inventory(), i, 0);
ItemWidget &widget = m_items.back();
widget.setPosition(5 + 20 * i - 3, 2, 0);
}
m_items[i].setStack(m_inventory.getStack(i, 0).item().stringID(), m_inventory.getStack(i, 0).amount());
m_items[i].setStack(
m_player.inventory().getStack(i, 0).item().stringID(),
m_player.inventory().getStack(i, 0).amount()
);
}
}
const Item &Hotbar::currentItem() const {
return m_player.inventory().getStack(m_cursorPos, 0).item();
}
void Hotbar::draw(gk::RenderTarget &target, gk::RenderStates states) const {
states.transform *= getTransform();

View File

@ -33,17 +33,18 @@
#include "ItemWidget.hpp"
class ClientCommandHandler;
class ClientPlayer;
class Hotbar : public Widget {
public:
Hotbar(Inventory &inventory, ClientCommandHandler &client, Widget *parent = nullptr);
Hotbar(ClientPlayer &player, ClientCommandHandler &client, Widget *parent = nullptr);
void onEvent(const SDL_Event &event) override;
void update() override;
int cursorPos() const { return m_cursorPos; }
const Item &currentItem() const { return m_inventory.getStack(m_cursorPos, 0).item(); }
const Item &currentItem() const;
private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
@ -51,9 +52,9 @@ class Hotbar : public Widget {
gk::Image m_background;
gk::Image m_cursor;
int m_cursorPos = 0;
int m_cursorPos = -1;
Inventory &m_inventory;
ClientPlayer &m_player;
ClientCommandHandler &m_client;

View File

@ -208,8 +208,16 @@ void ClientCommandHandler::setupCallbacks() {
u16 clientId;
packet >> clientId;
if (clientId == m_client.id())
if (clientId == m_client.id()) {
packet >> m_player.inventory();
s8 heldItemSlot;
packet >> heldItemSlot;
if (m_player.heldItemSlot() == -1) {
m_player.setHeldItemSlot(heldItemSlot);
}
}
else
packet >> m_playerBoxes.at(clientId).inventory();
});

View File

@ -42,11 +42,11 @@ u8 Player::getOppositeDirection() const {
}
void Player::serialize(sf::Packet &packet) const {
packet << m_x << m_y << m_z << m_dimension << m_viewAngleH << m_viewAngleV << m_viewAngleRoll << m_inventory;
packet << m_x << m_y << m_z << m_dimension << m_viewAngleH << m_viewAngleV << m_viewAngleRoll << m_inventory << m_heldItemSlot;
}
void Player::deserialize(sf::Packet &packet) {
packet >> m_x >> m_y >> m_z >> m_dimension >> m_viewAngleH >> m_viewAngleV >> m_viewAngleRoll >> m_inventory;
packet >> m_x >> m_y >> m_z >> m_dimension >> m_viewAngleH >> m_viewAngleV >> m_viewAngleRoll >> m_inventory >> m_heldItemSlot;
}
// Please update 'docs/lua-api-cpp.md' if you change this
@ -64,7 +64,9 @@ void Player::initUsertype(sol::state &lua) {
"client_id", &Player::clientID,
"inventory", &Player::inventory
"inventory", &Player::inventory,
"held_item_stack", &Player::heldItemStack
);
}

View File

@ -68,6 +68,10 @@ class Player : public gk::ISerializable {
const gk::FloatBox &hitbox() const { return m_hitbox; }
const ItemStack &heldItemStack() { return m_inventory.getStack(m_heldItemSlot, 0); }
s8 heldItemSlot() const { return m_heldItemSlot; }
void setHeldItemSlot(u8 heldItemSlot) { m_heldItemSlot = heldItemSlot; }
static void initUsertype(sol::state &lua);
protected:
@ -88,6 +92,8 @@ class Player : public gk::ISerializable {
Inventory m_inventory{9, 4};
gk::FloatBox m_hitbox;
s8 m_heldItemSlot = -1;
};
#endif // PLAYER_HPP_

View File

@ -118,7 +118,7 @@ void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *c
if (player) {
Network::Packet packet;
packet << Network::Command::PlayerInvUpdate;
packet << clientID << player->inventory();
packet << clientID << player->inventory() << player->heldItemSlot();
if (!client)
m_server.sendToAllClients(packet);
@ -192,8 +192,10 @@ void ServerCommandHandler::setupCallbacks() {
return;
}
if (player->isNewPlayer())
if (player->isNewPlayer()) {
player->setPosition(m_spawnPosition.x, m_spawnPosition.y, m_spawnPosition.z);
player->setHeldItemSlot(0);
}
Network::Packet packet;
packet << Network::Command::RegistryData;
@ -212,10 +214,7 @@ void ServerCommandHandler::setupCallbacks() {
if (player->isNewPlayer())
m_scriptEngine.luaCore().onEvent(LuaEventType::PlayerConnected, glm::ivec3{player->x(), player->y(), player->z()}, player, client, *this);
Network::Packet invPacket;
invPacket << Network::Command::PlayerInvUpdate << client.id;
invPacket << player->inventory();
client.tcpSocket->send(invPacket);
sendPlayerInvUpdate(client.id, &client);
// Send spawn packet to all clients for this player
Network::Packet spawnPacket;

View File

@ -31,7 +31,6 @@ void ServerPlayer::initUsertype(sol::state &lua) {
lua.new_usertype<ServerPlayer>("ServerPlayer",
sol::base_classes, sol::bases<Player>(),
"client", &ServerPlayer::client,
"held_item_stack", &ServerPlayer::heldItemStack,
"is_online", &ServerPlayer::isOnline
);
}

View File

@ -42,9 +42,6 @@ class ServerPlayer : public Player {
const ClientInfo *client() const { return m_client; }
void setClient(ClientInfo *client) { m_client = client; }
const ItemStack &heldItemStack() { return m_inventory.getStack(m_heldItemSlot, 0); }
void setHeldItemSlot(u8 heldItemSlot) { m_heldItemSlot = heldItemSlot; }
bool isOnline() const { return m_client != nullptr; }
bool isNewPlayer() const { return m_isNewPlayer; }
void setNewPlayer(bool isNewPlayer) { m_isNewPlayer = isNewPlayer; }
@ -54,8 +51,6 @@ class ServerPlayer : public Player {
private:
ClientInfo *m_client = nullptr;
u8 m_heldItemSlot = 0;
bool m_isNewPlayer = false;
};