Program Listing for File player_look.c¶
↰ Return to documentation for file (server/game_events/player_look.c)
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "client/client.h"
#include "handler.h"
#include "server.h"
static const char *RES_NAMES[RES_COUNT] = {
"food", "linemate", "deraumere", "sibur", "mendiane", "phiras", "thystame"
};
static constexpr const size_t TIER_MAX = 8;
static constexpr const size_t TIER_MAX_AREA = (TIER_MAX + 1) * (TIER_MAX + 1);
static
void rotate(int8_t delta[2], uint8_t direction)
{
switch (direction) {
case OR_NORTH:
delta[1] = -delta[1];
break;
case OR_EAST:
break;
case OR_SOUTH:
delta[0] = -delta[0];
break;
case OR_WEST:
delta[0] = -delta[0];
delta[1] = -delta[1];
break;
default:
return;
}
}
static
void fill_coords(
uint8_t coords[][2], size_t, server_t *srv, client_state_t *cs)
{
int8_t delta[2];
size_t idx = 0;
for (uint8_t l = 0; l < cs->tier + 1; l++) {
for (int i = -l; i < l + 1; i++) {
delta[0] = i;
delta[1] = l;
rotate(delta, cs->orientation);
coords[idx][0] = cs->x + delta[0] + srv->map_width;
coords[idx][1] = cs->y + delta[1] + srv->map_height;
coords[idx][0] %= srv->map_width;
coords[idx][1] %= srv->map_height;
idx++;
}
}
}
static
uint16_t count_player_on_tile(
server_t *srv, uint8_t x, uint8_t y)
{
uint16_t count = 0;
for (size_t i = srv->cm.idx_of_players; i < srv->cm.count; i++) {
if (srv->cm.clients[i].x == x && srv->cm.clients[i].y == y) {
count++;
}
}
return count;
}
static
void serialize_item_on_tite(
server_t *srv, client_state_t *cs,
const uint8_t coords[2], bool prev)
{
inventory_t *tile = &srv->map[coords[1]][coords[0]];
for (size_t i = 0; i < RES_COUNT; i++) {
if (tile->qnts[i] == 0)
continue;
for (size_t j = 0; j < tile->qnts[i]; j++) {
append_to_output(srv, cs, prev ? " " : "");
vappend_to_output(srv, cs, "%s", RES_NAMES[i]);
prev = true;
}
}
}
static
void serialiaze_tile(
server_t *srv, client_state_t *cs, uint8_t coords[][2], size_t idx)
{
bool has_prev = false;
uint16_t players_on_tile =
count_player_on_tile(srv, coords[idx][0], coords[idx][1]);
for (size_t i = 0; i < players_on_tile; i++) {
vappend_to_output(srv, cs, "%splayer", has_prev ? " " : "");
has_prev = true;
}
for (size_t i = 0; i < srv->eggs.nmemb; i++) {
if (srv->eggs.buff[i].x != coords[idx][0]
|| srv->eggs.buff[i].y != coords[idx][1])
continue;
vappend_to_output(srv, cs, "%segg", has_prev ? " " : "");
has_prev = true;
}
serialize_item_on_tite(srv, cs, coords[idx], has_prev);
}
bool player_look_handler(server_t *srv, const event_t *event)
{
client_state_t *cs = event_get_client(srv, event);
uint8_t coords[TIER_MAX_AREA][2];
uint8_t view;
if (cs == nullptr)
return false;
view = (cs->tier + 1) * (cs->tier + 1);
fill_coords(coords, view, srv, cs);
append_to_output(srv, cs, "[ ");
for (size_t i = 0; i < view; i++) {
if (i != 0)
append_to_output(srv, cs, ", ");
serialiaze_tile(srv, cs, coords, i);
}
append_to_output(srv, cs, " ]\n");
return true;
}