Program Listing for File game_assign_team.c¶
↰ Return to documentation for file (server/game_assign_team.c)
#include <stdio.h>
#include <string.h>
#include "client/client.h"
#include "game_events/names.h"
#include "server.h"
static constexpr const uint64_t INITIAL_FOOD_INVENTORY = 10;
static constexpr const uint8_t FOUR_MASK = 0b11;
static const char *GRAPHIC_COMMAND = "GRAPHIC";
static
void send_guis_player_data(server_t *srv, client_state_t *client, size_t egg)
{
for (size_t i = srv->cm.idx_of_gui; i < srv->cm.idx_of_players; i++) {
vappend_to_output(srv, &srv->cm.clients[i],
"pnw #%d %hhu %hhu %hhu %hhu %s\npin #%d %hhu %hhu %s\nebo #%zu\n",
client->id, client->x, client->y, client->orientation + 1,
client->tier, srv->team_names[client->team_id],
client->id, client->x, client->y,
serialize_inventory(&client->inv), egg + 1);
}
}
static
bool assign_ai_egg_data(server_t *srv, client_state_t *client, size_t team_id)
{
for (size_t i = 0; i < srv->eggs.nmemb; i++)
if (srv->eggs.buff[i].team_id == team_id) {
client->x = srv->eggs.buff[i].x;
client->y = srv->eggs.buff[i].y;
srv->eggs.buff[i] = srv->eggs.buff[srv->eggs.nmemb - 1];
srv->eggs.nmemb--;
send_guis_player_data(srv, client, i);
return true;
}
__builtin_unreachable();
}
static
bool assign_ai_data(server_t *srv, client_state_t *client, size_t team_id)
{
event_t event = {
.timestamp = get_timestamp(),
.client_idx = client - srv->cm.clients,
.client_id = client->id,
.command = {PLAYER_DEATH}
};
DEBUG("Player (id: %u) death incoming in %lu ms",
client->id, (event.timestamp - get_timestamp()) / MILISEC_IN_SEC);
client->team_id = team_id;
client->orientation = (rand() & FOUR_MASK);
client->inv.food = INITIAL_FOOD_INVENTORY;
client->tier = 1;
if (!event_heap_push(&srv->events, &event)) {
srv->is_running = false;
return false;
}
return assign_ai_egg_data(srv, client, team_id);
}
static
bool send_ai_team_assignment_respone(
server_t *srv, client_state_t *client,
size_t team_id)
{
unsigned int count = 0;
client->team_id = team_id;
client = client_manager_promote(&srv->cm, client - srv->cm.clients);
if (client == nullptr)
return false;
DEBUG("Client %d assigned to the team with id %zu", client->fd, team_id);
for (size_t i = 0; i < srv->eggs.nmemb; i++)
count += srv->eggs.buff[i].team_id == team_id
&& srv->eggs.buff[i].hatch <= get_timestamp();
if (count == 0)
return vappend_to_output(srv, client, "ko\n"), false;
vappend_to_output(srv, client, "%u\n%hhu %hhu\n",
count - 1, srv->map_width, srv->map_height);
return assign_ai_data(srv, client, team_id);
}
static
void send_players_info(server_t *srv, client_state_t *client)
{
for (size_t i = srv->cm.idx_of_players; i < srv->cm.count; i++) {
vappend_to_output(srv, client, "pnw #%hu %hhu %hhu %hu %s\n",
srv->cm.clients[i].id, srv->cm.clients[i].x,
srv->cm.clients[i].y, srv->cm.clients[i].tier,
srv->team_names[srv->cm.clients[i].team_id]);
vappend_to_output(srv, client, "pin #%hu %s\n",
srv->cm.clients[i].id, serialize_inventory(
&srv->cm.clients[i].inv));
vappend_to_output(srv, client, "plv #%hu %hhu\n",
srv->cm.clients[i].id, srv->cm.clients[i].tier);
}
}
static
bool send_gui_team_assignment_respone(server_t *srv, client_state_t *client)
{
client->team_id = TEAM_ID_GRAPHIC;
client = client_manager_promote(&srv->cm, client - srv->cm.clients);
if (client == nullptr)
return false;
DEBUG("Client %d assigned to GRAPHIC team", client->fd);
vappend_to_output(srv, client, "msz %hhu %hhu\nsgt %hu\n",
srv->map_width, srv->map_height, srv->frequency);
for (size_t y = 0; y < srv->map_height; y++)
for (size_t x = 0; x < srv->map_width; x++)
vappend_to_output(srv, client, "bct %zu %zu %s\n",
x, y, serialize_inventory(&srv->map[y][x]));
for (size_t i = 0; srv->team_names[i] != nullptr; i++)
vappend_to_output(srv, client, "tna %s\n", srv->team_names[i]);
send_players_info(srv, client);
for (size_t i = 0; i < srv->eggs.nmemb; i++)
vappend_to_output(srv, client, "enw #%zu #-1 %hhu %hhu\n", i,
srv->eggs.buff[i].x, srv->eggs.buff[i].y);
return true;
}
bool handle_team(server_t *srv, client_state_t *client,
char *split[static COMMAND_WORD_COUNT])
{
if (client->team_id != TEAM_ID_UNASSIGNED)
return false;
if (!strcmp(split[0], GRAPHIC_COMMAND))
return send_gui_team_assignment_respone(srv, client);
for (size_t i = 0; srv->team_names[i] != nullptr; i++)
if (!strcmp(srv->team_names[i], split[0]))
return send_ai_team_assignment_respone(srv, client, i);
return false;
}