implement player poses (sneak/sprint)

* Added sending player metadata with poses to everyone

* Renamed sendPlayerMetadataToAll to broadcastPlayerMetadata

* Made entity metadata system flexible

* Made broadcastPlayerMetadata create new metadata instead of using a global one

* Moved writeEntityData, sizeEntityData and sizeEntityMetadata to procedures

* style nitpicks

---------

Co-authored-by: p2r3 <p2r3@p2r3.com>
This commit is contained in:
SDFTDusername
2025-09-15 21:01:22 +02:00
committed by GitHub
parent e5dfe53d14
commit c5e8408052
6 changed files with 131 additions and 1 deletions

View File

@@ -368,6 +368,43 @@ void spawnPlayer (PlayerData *player) {
}
// Broadcasts a player's entity metadata (sneak/sprint state) to other players
void broadcastPlayerMetadata (PlayerData *player) {
uint8_t sneaking = (player->flags & 0x04) != 0;
uint8_t sprinting = (player->flags & 0x08) != 0;
uint8_t player_bit_mask = 0;
if (sneaking) player_bit_mask |= 0x02;
if (sprinting) player_bit_mask |= 0x08;
int pose = 0;
if (sneaking) pose = 5;
EntityData metadata[] = {
{
0, // Index (Bit Mask)
0, // Type (Byte)
player_bit_mask, // Value
},
{
6, // Index (Pose),
21, // Type (Pose),
pose, // Value (Standing)
}
};
for (int i = 0; i < MAX_PLAYERS; i ++) {
PlayerData* other_player = &player_data[i];
int client_fd = other_player->client_fd;
if (client_fd == -1) continue;
if (client_fd == player->client_fd) continue;
if (other_player->flags & 0x20) continue;
sc_setEntityMetadata(client_fd, player->client_fd, metadata, 2);
}
}
uint8_t getBlockChange (short x, uint8_t y, short z) {
for (int i = 0; i < block_changes_count; i ++) {
if (block_changes[i].block == 0xFF) continue;
@@ -1784,3 +1821,47 @@ void broadcastChestUpdate (int origin_fd, uint8_t *storage_ptr, uint16_t item, u
}
#endif
ssize_t writeEntityData (int client_fd, EntityData *data) {
writeByte(client_fd, data->index);
writeVarInt(client_fd, data->type);
switch (data->type) {
case 0: // Byte
return writeByte(client_fd, data->value.byte);
case 21: // Pose
writeVarInt(client_fd, data->value.pose);
return 0;
default: return -1;
}
}
// Returns the networked size of an EntityData entry
int sizeEntityData (EntityData *data) {
int value_size;
switch (data->type) {
case 0: // Byte
value_size = 1;
break;
case 21: // Pose
value_size = sizeVarInt(data->value.pose);
break;
default: return -1;
}
return 1 + sizeVarInt(data->type) + value_size;
}
// Returns the networked size of an array of EntityData entries
int sizeEntityMetadata (EntityData *metadata, size_t length) {
int total_size = 0;
for (size_t i = 0; i < length; i ++) {
int size = sizeEntityData(&metadata[i]);
if (size == -1) return -1;
total_size += size;
}
return total_size;
}