Now saving last hotbar slot.
parent
c7a5d61ece
commit
7eaac50d48
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ¤tStack = 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 ¤tStack = 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 ¤tStack = 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 = ¤tStack;
|
||||
}
|
||||
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 ¤tStack = m_player.inventory().getStack(cursorPos, 0);
|
||||
if (m_currentTool->item().id() != currentStack.item().id()) {
|
||||
m_animationStart = ticks;
|
||||
m_currentTool = ¤tStack;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 ¤tItem() const { return m_inventory.getStack(m_cursorPos, 0).item(); }
|
||||
const Item ¤tItem() 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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue