void PLAYERS::on_render() { // render other players in two passes, first pass we render the other, second pass we render our self for(int p = 0; p < 2; p++) { for(int i = 0; i < MAX_CLIENTS; i++) { // only render active characters if(!gameclient.snap.characters[i].active) continue; const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, i); const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i); if(prev_info && info) { // bool local = ((const NETOBJ_PLAYER_INFO *)info)->local !=0; if(p == 0 && local) continue; if(p == 1 && !local) continue; NETOBJ_CHARACTER prev_char = gameclient.snap.characters[i].prev; NETOBJ_CHARACTER cur_char = gameclient.snap.characters[i].cur; render_player( &prev_char, &cur_char, (const NETOBJ_PLAYER_INFO *)prev_info, (const NETOBJ_PLAYER_INFO *)info ); } } } }
void ITEMS::on_render() { int num = snap_num_items(SNAP_CURRENT); for(int i = 0; i < num; i++) { SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); if(item.type == NETOBJTYPE_PROJECTILE) { render_projectile((const NETOBJ_PROJECTILE *)data, item.id); } else if(item.type == NETOBJTYPE_PICKUP) { const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); if(prev) render_pickup((const NETOBJ_PICKUP *)prev, (const NETOBJ_PICKUP *)data); } else if(item.type == NETOBJTYPE_LASER) { render_laser((const NETOBJ_LASER *)data); } else if(item.type == NETOBJTYPE_FLAG) { const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); if (prev) render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data); } } // render extra projectiles /* for(int i = 0; i < extraproj_num; i++) { if(extraproj_projectiles[i].start_tick < client_tick()) { extraproj_projectiles[i] = extraproj_projectiles[extraproj_num-1]; extraproj_num--; } else render_projectile(&extraproj_projectiles[i], 0); }*/ }
void NAMEPLATES::on_render() { if (!config.cl_nameplates) return; for(int i = 0; i < MAX_CLIENTS; i++) { // only render active characters if(!gameclient.snap.characters[i].active) continue; const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i); if(info) { render_nameplate( &gameclient.snap.characters[i].prev, &gameclient.snap.characters[i].cur, (const NETOBJ_PLAYER_INFO *)info); } } }
void GAMECLIENT::on_snapshot() { new_tick = true; // clear out the invalid pointers mem_zero(&gameclient.snap, sizeof(gameclient.snap)); snap.local_cid = -1; // secure snapshot { int num = snap_num_items(SNAP_CURRENT); for(int index = 0; index < num; index++) { SNAP_ITEM item; void *data = snap_get_item(SNAP_CURRENT, index, &item); if(netobj_validate(item.type, data, item.datasize) != 0) { if(config.debug) dbg_msg("game", "invalidated index=%d type=%d (%s) size=%d id=%d", index, item.type, netobj_get_name(item.type), item.datasize, item.id); snap_invalidate_item(SNAP_CURRENT, index); } } } process_events(); if(config.dbg_stress) { if((client_tick()%100) == 0) { char message[64]; int msglen = rand()%(sizeof(message)-1); for(int i = 0; i < msglen; i++) message[i] = 'a'+(rand()%('z'-'a')); message[msglen] = 0; NETMSG_CL_SAY msg; msg.team = rand()&1; msg.message = message; msg.pack(MSGFLAG_VITAL); client_send_msg(); } } // go trough all the items in the snapshot and gather the info we want { snap.team_size[0] = snap.team_size[1] = 0; // TeeComp. for(int i=0; i<MAX_CLIENTS; i++) stats[i].active = false; int num = snap_num_items(SNAP_CURRENT); for(int i = 0; i < num; i++) { SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); if(item.type == NETOBJTYPE_CLIENT_INFO) { const NETOBJ_CLIENT_INFO *info = (const NETOBJ_CLIENT_INFO *)data; int cid = item.id; ints_to_str(&info->name0, 6, clients[cid].name); ints_to_str(&info->skin0, 6, clients[cid].skin_name); clients[cid].use_custom_color = info->use_custom_color; clients[cid].color_body = info->color_body; clients[cid].color_feet = info->color_feet; // prepare the info if(clients[cid].skin_name[0] == 'x' || clients[cid].skin_name[1] == '_') str_copy(clients[cid].skin_name, "default", 64); clients[cid].skin_info.color_body = skins->get_color(clients[cid].color_body); clients[cid].skin_info.color_feet = skins->get_color(clients[cid].color_feet); clients[cid].skin_info.size = 64; // find new skin clients[cid].skin_id = gameclient.skins->find(clients[cid].skin_name); if(clients[cid].skin_id < 0) { clients[cid].skin_id = gameclient.skins->find("default"); if(clients[cid].skin_id < 0) clients[cid].skin_id = 0; } if(clients[cid].use_custom_color) clients[cid].skin_info.texture = gameclient.skins->get(clients[cid].skin_id)->color_texture; else { clients[cid].skin_info.texture = gameclient.skins->get(clients[cid].skin_id)->org_texture; clients[cid].skin_info.color_body = vec4(1,1,1,1); clients[cid].skin_info.color_feet = vec4(1,1,1,1); } clients[cid].update_render_info(cid); gameclient.snap.num_players++; } else if(item.type == NETOBJTYPE_PLAYER_INFO) { const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; clients[info->cid].team = info->team; snap.player_infos[info->cid] = info; if(info->local) { snap.local_cid = item.id; snap.local_info = info; if (info->team == -1) snap.spectate = true; } // calculate team-balance if(info->team != -1) { snap.team_size[info->team]++; stats[info->cid].active = true; } } else if(item.type == NETOBJTYPE_CHARACTER) { const void *old = snap_find_item(SNAP_PREV, NETOBJTYPE_CHARACTER, item.id); if(old) { snap.characters[item.id].active = true; snap.characters[item.id].prev = *((const NETOBJ_CHARACTER *)old); snap.characters[item.id].cur = *((const NETOBJ_CHARACTER *)data); if(snap.characters[item.id].prev.tick) evolve(&snap.characters[item.id].prev, client_prevtick()); if(snap.characters[item.id].cur.tick) evolve(&snap.characters[item.id].cur, client_tick()); } } else if(item.type == NETOBJTYPE_GAME) { snap.gameobj = (NETOBJ_GAME *)data; if(snap.gameobj->game_over != last_game_over) { if(!last_game_over) on_game_over(); else on_game_restart(); last_game_over = snap.gameobj->game_over; } if((snap.gameobj->warmup > 0) != last_warmup) { if(last_warmup) on_warmup_end(); last_warmup = snap.gameobj->warmup > 0; } } else if(item.type == NETOBJTYPE_FLAG) { int fid = item.id%2; snap.flags[fid] = (const NETOBJ_FLAG *)data; if(snap.flags[fid]->carried_by != last_flag_carrier[fid]) { if(snap.flags[fid]->carried_by >= 0) on_flag_grab(fid); last_flag_carrier[fid] = snap.flags[fid]->carried_by; } } } // TeeComp for(int i=0; i<MAX_CLIENTS; i++) { if(stats[i].active && !stats[i].was_active) { stats[i].reset(); // Client connected, reset stats. stats[i].active = true; stats[i].join_date = client_tick(); } stats[i].was_active = stats[i].active; } } // setup local pointers if(snap.local_cid >= 0) { SNAPSTATE::CHARACTERINFO *c = &snap.characters[snap.local_cid]; if(c->active) { snap.local_character = &c->cur; snap.local_prev_character = &c->prev; local_character_pos = vec2(snap.local_character->x, snap.local_character->y); } } else snap.spectate = true; TUNING_PARAMS standard_tuning; SERVER_INFO current_server_info; client_serverinfo(¤t_server_info); if(current_server_info.gametype[0] != '0') { if(strcmp(current_server_info.gametype, "DM") != 0 && strcmp(current_server_info.gametype, "TDM") != 0 && strcmp(current_server_info.gametype, "CTF") != 0) servermode = SERVERMODE_MOD; else if(memcmp(&standard_tuning, &tuning, sizeof(TUNING_PARAMS)) == 0) servermode = SERVERMODE_PURE; else servermode = SERVERMODE_PUREMOD; } // update render info for(int i = 0; i < MAX_CLIENTS; i++) clients[i].update_render_info(i); }