merged 0.3.3 changes over to trunk

This commit is contained in:
Magnus Auvinen 2008-01-12 12:08:26 +00:00
parent 24e17b41a8
commit 1c1677f023
14 changed files with 380 additions and 163 deletions

View file

@ -304,6 +304,24 @@ int client_connection_problems()
return netclient_gotproblems(net); return netclient_gotproblems(net);
} }
void client_direct_input(int *input, int size)
{
int i;
msg_pack_start_system(NETMSG_INPUT, 0);
msg_pack_int(ack_game_tick);
msg_pack_int(current_predtick);
msg_pack_int(size);
for(i = 0; i < size/4; i++)
msg_pack_int(input[i]);
msg_pack_end();
client_send_msg();
dbg_msg("client", "sent direct input");
}
static void client_send_input() static void client_send_input()
{ {
int64 now = time_get(); int64 now = time_get();
@ -312,7 +330,7 @@ static void client_send_input()
if(current_predtick <= 0) if(current_predtick <= 0)
return; return;
/* fetch input */ /* fetch input */
size = modc_snap_input(inputs[current_input].data); size = modc_snap_input(inputs[current_input].data);
msg_pack_start_system(NETMSG_INPUT, 0); msg_pack_start_system(NETMSG_INPUT, 0);
@ -1006,6 +1024,9 @@ static void client_run()
/* update input */ /* update input */
inp_update(); inp_update();
/* update sound */
snd_update();
/* refocus */ /* refocus */
if(!gfx_window_active()) if(!gfx_window_active())

View file

@ -489,20 +489,22 @@ int gfx_load_texture_raw(int w, int h, int format, const void *data, int store_f
gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, w, h, oglformat, GL_UNSIGNED_BYTE, texdata); gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, w, h, oglformat, GL_UNSIGNED_BYTE, texdata);
/* calculate memory usage */ /* calculate memory usage */
int pixel_size = 4;
if(store_format == IMG_RGB)
pixel_size = 3;
else if(store_format == IMG_ALPHA)
pixel_size = 1;
textures[tex].memsize = w*h*pixel_size;
if(mipmap)
{ {
while(w > 2 && h > 2) int pixel_size = 4;
if(store_format == IMG_RGB)
pixel_size = 3;
else if(store_format == IMG_ALPHA)
pixel_size = 1;
textures[tex].memsize = w*h*pixel_size;
if(mipmap)
{ {
w>>=1; while(w > 2 && h > 2)
h>>=1; {
textures[tex].memsize += w*h*pixel_size; w>>=1;
h>>=1;
textures[tex].memsize += w*h*pixel_size;
}
} }
} }
@ -544,7 +546,9 @@ int gfx_load_mip_texture_raw(int w, int h, int format, const void *data)
int gfx_load_texture(const char *filename, int store_format) int gfx_load_texture(const char *filename, int store_format)
{ {
int l = strlen(filename); int l = strlen(filename);
int id;
IMAGE_INFO img; IMAGE_INFO img;
if(l < 3) if(l < 3)
return 0; return 0;
if(gfx_load_png(&img, filename)) if(gfx_load_png(&img, filename))
@ -552,7 +556,7 @@ int gfx_load_texture(const char *filename, int store_format)
if (store_format == IMG_AUTO) if (store_format == IMG_AUTO)
store_format = img.format; store_format = img.format;
int id = gfx_load_texture_raw(img.width, img.height, img.format, img.data, store_format); id = gfx_load_texture_raw(img.width, img.height, img.format, img.data, store_format);
mem_free(img.data); mem_free(img.data);
return id; return id;
} }
@ -1101,7 +1105,7 @@ void gfx_pretty_text(float x, float y, float size, const char *text, int max_wid
float gfx_pretty_text_width(float size, const char *text_, int length) float gfx_pretty_text_width(float size, const char *text_, int length)
{ {
return gfx_text_width(gfx_font_set, size, text_, length); return gfx_text_width(gfx_font_set, size, text_, length);
/*
const float spacing = 0.05f; const float spacing = 0.05f;
float w = 0.0f; float w = 0.0f;
const unsigned char *text = (unsigned char *)text_; const unsigned char *text = (unsigned char *)text_;
@ -1126,7 +1130,7 @@ float gfx_pretty_text_width(float size, const char *text_, int length)
text++; text++;
} }
return w; return w;*/
} }

View file

@ -48,19 +48,56 @@ void inp_mouse_relative(int *x, int *y)
last_y = ny; last_y = ny;
} }
static char last_c = 0; enum
static int last_k = 0; {
INPUT_BUFFER_SIZE=32
};
static INPUTEVENT input_events[INPUT_BUFFER_SIZE];
static int num_events = 0;
static void add_event(char c, int key)
{
if(num_events != INPUT_BUFFER_SIZE)
{
input_events[num_events].ch = c;
input_events[num_events].key = key;
num_events++;
}
}
int inp_num_events()
{
return num_events;
}
void inp_clear_events()
{
num_events = 0;
}
INPUTEVENT inp_get_event(int index)
{
if(index < 0 || index >= num_events)
{
INPUTEVENT e = {0,0};
return e;
}
return input_events[index];
}
static void char_callback(int character, int action) static void char_callback(int character, int action)
{ {
if(action == GLFW_PRESS && character < 256) if(action == GLFW_PRESS && character < 256)
last_c = (char)character; add_event((char)character, 0);
} }
static void key_callback(int key, int action) static void key_callback(int key, int action)
{ {
if(action == GLFW_PRESS) if(action == GLFW_PRESS)
last_k = key; add_event(0, key);
if(action == GLFW_PRESS) if(action == GLFW_PRESS)
input_count[input_current^1][key].presses++; input_count[input_current^1][key].presses++;
@ -72,7 +109,7 @@ static void key_callback(int key, int action)
static void mousebutton_callback(int button, int action) static void mousebutton_callback(int button, int action)
{ {
if(action == GLFW_PRESS) if(action == GLFW_PRESS)
last_k = KEY_MOUSE_FIRST+button; add_event(0, KEY_MOUSE_FIRST+button);
if(action == GLFW_PRESS) if(action == GLFW_PRESS)
input_count[input_current^1][KEY_MOUSE_FIRST+button].presses++; input_count[input_current^1][KEY_MOUSE_FIRST+button].presses++;
@ -99,7 +136,7 @@ static void mousewheel_callback(int pos)
input_count[input_current^1][KEY_MOUSE_WHEEL_UP].releases++; input_count[input_current^1][KEY_MOUSE_WHEEL_UP].releases++;
} }
last_k = KEY_MOUSE_WHEEL_UP; add_event(0, KEY_MOUSE_WHEEL_UP);
} }
else if(pos < 0) else if(pos < 0)
{ {
@ -109,7 +146,7 @@ static void mousewheel_callback(int pos)
input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].releases++; input_count[input_current^1][KEY_MOUSE_WHEEL_DOWN].releases++;
} }
last_k = KEY_MOUSE_WHEEL_DOWN; add_event(0, KEY_MOUSE_WHEEL_DOWN);
} }
glfwSetMouseWheel(0); glfwSetMouseWheel(0);
} }
@ -124,22 +161,6 @@ void inp_init()
glfwSetMouseWheelCallback(mousewheel_callback); glfwSetMouseWheelCallback(mousewheel_callback);
} }
char inp_last_char()
{
return last_c;
}
int inp_last_key()
{
return last_k;
}
void inp_clear()
{
last_k = 0;
last_c = 0;
}
void inp_mouse_mode_absolute() void inp_mouse_mode_absolute()
{ {
glfwEnable(GLFW_MOUSE_CURSOR); glfwEnable(GLFW_MOUSE_CURSOR);
@ -147,8 +168,8 @@ void inp_mouse_mode_absolute()
void inp_mouse_mode_relative() void inp_mouse_mode_relative()
{ {
//if (!config.gfx_debug_resizable) /*if (!config.gfx_debug_resizable)*/
//glfwDisable(GLFW_MOUSE_CURSOR); glfwDisable(GLFW_MOUSE_CURSOR);
} }
int inp_mouse_doubleclick() int inp_mouse_doubleclick()

View file

@ -55,6 +55,7 @@ static int center_x = 0;
static int center_y = 0; static int center_y = 0;
static int mixing_rate = 48000; static int mixing_rate = 48000;
static volatile int sound_volume = 100;
void snd_set_channel(int cid, float vol, float pan) void snd_set_channel(int cid, float vol, float pan)
{ {
@ -135,10 +136,13 @@ static void mix(short *final_out, unsigned frames)
{ {
int mix_buffer[MAX_FRAMES*2] = {0}; int mix_buffer[MAX_FRAMES*2] = {0};
int i, s; int i, s;
int master_vol;
/* aquire lock while we are mixing */ /* aquire lock while we are mixing */
lock_wait(sound_lock); lock_wait(sound_lock);
master_vol = sound_volume;
for(i = 0; i < NUM_VOICES; i++) for(i = 0; i < NUM_VOICES; i++)
{ {
if(voices[i].snd) if(voices[i].snd)
@ -208,12 +212,12 @@ static void mix(short *final_out, unsigned frames)
} }
} }
/* release the lock */ /* release the lock */
lock_release(sound_lock); lock_release(sound_lock);
{ {
int master_vol = config.snd_volume;
/* clamp accumulated values */ /* clamp accumulated values */
/* TODO: this seams slow */ /* TODO: this seams slow */
for(i = 0; i < frames; i++) for(i = 0; i < frames; i++)
@ -283,6 +287,25 @@ int snd_init()
err = Pa_StartStream(stream); err = Pa_StartStream(stream);
sound_enabled = 1; sound_enabled = 1;
snd_update(); /* update the volume */
return 0;
}
int snd_update()
{
/* update volume */
int wanted_volume = config.snd_volume;
if(!gfx_window_active() && config.snd_nonactive_mute)
wanted_volume = 0;
if(wanted_volume != sound_volume)
{
lock_wait(sound_lock);
sound_volume = wanted_volume;
lock_release(sound_lock);
}
return 0; return 0;
} }

View file

@ -149,6 +149,10 @@ static void client_serverbrowse_filter()
filtered = 1; filtered = 1;
else if(config.b_filter_pw && serverlist[i]->info.flags&1) else if(config.b_filter_pw && serverlist[i]->info.flags&1)
filtered = 1; filtered = 1;
else if(config.b_filter_ping < serverlist[i]->info.latency)
filtered = 1;
else if(!(config.b_filter_gametype&(1<<serverlist[i]->info.game_type)))
filtered = 1;
else if(config.b_filter_string[0] != 0) else if(config.b_filter_string[0] != 0)
{ {
if(strstr(serverlist[i]->info.name, config.b_filter_string) == 0) if(strstr(serverlist[i]->info.name, config.b_filter_string) == 0)
@ -167,6 +171,8 @@ static int client_serverbrowse_sorthash()
i |= config.b_filter_full<<5; i |= config.b_filter_full<<5;
i |= config.b_filter_pw<<6; i |= config.b_filter_pw<<6;
i |= config.b_sort_order<<7; i |= config.b_sort_order<<7;
i |= config.b_filter_gametype<<8;
i |= config.b_filter_ping<<16;
return i; return i;
} }

View file

@ -16,6 +16,9 @@ MACRO_CONFIG_STR(b_filter_string, 64, "")
MACRO_CONFIG_INT(b_filter_full, 0, 0, 1) MACRO_CONFIG_INT(b_filter_full, 0, 0, 1)
MACRO_CONFIG_INT(b_filter_empty, 0, 0, 1) MACRO_CONFIG_INT(b_filter_empty, 0, 0, 1)
MACRO_CONFIG_INT(b_filter_pw, 0, 0, 1) MACRO_CONFIG_INT(b_filter_pw, 0, 0, 1)
MACRO_CONFIG_INT(b_filter_ping, 999, 0, 999)
MACRO_CONFIG_INT(b_filter_gametype, 0xf, 0, 0xf)
MACRO_CONFIG_INT(b_sort, 0, 0, 256) MACRO_CONFIG_INT(b_sort, 0, 0, 256)
MACRO_CONFIG_INT(b_sort_order, 0, 0, 1) MACRO_CONFIG_INT(b_sort_order, 0, 0, 1)
MACRO_CONFIG_INT(b_max_requests, 10, 0, 1000) MACRO_CONFIG_INT(b_max_requests, 10, 0, 1000)
@ -25,6 +28,8 @@ MACRO_CONFIG_INT(snd_enable, 1, 0, 1)
MACRO_CONFIG_INT(snd_volume, 100, 0, 100) MACRO_CONFIG_INT(snd_volume, 100, 0, 100)
MACRO_CONFIG_INT(snd_device, -1, 0, 0) MACRO_CONFIG_INT(snd_device, -1, 0, 0)
MACRO_CONFIG_INT(snd_nonactive_mute, 0, 0, 1)
MACRO_CONFIG_INT(gfx_screen_width, 800, 0, 0) MACRO_CONFIG_INT(gfx_screen_width, 800, 0, 0)
MACRO_CONFIG_INT(gfx_screen_height, 600, 0, 0) MACRO_CONFIG_INT(gfx_screen_height, 600, 0, 0)
MACRO_CONFIG_INT(gfx_fullscreen, 1, 0, 1) MACRO_CONFIG_INT(gfx_fullscreen, 1, 0, 1)

View file

@ -396,6 +396,7 @@ void gfx_quads_text(float x, float y, float size, const char *text);
/* sound (client) */ /* sound (client) */
int snd_init(); int snd_init();
int snd_update();
void snd_set_channel(int cid, float vol, float pan); void snd_set_channel(int cid, float vol, float pan);
@ -758,6 +759,9 @@ const char *mods_version();
/* server */ /* server */
int server_getclientinfo(int client_id, CLIENT_INFO *info); int server_getclientinfo(int client_id, CLIENT_INFO *info);
const char *server_clientname(int client_id); const char *server_clientname(int client_id);
/* grabs the latest input for the client. not withholding anything */
int *server_latestinput(int client_id, int *size);
void server_setclientname(int client_id, const char *name); void server_setclientname(int client_id, const char *name);
void server_setclientscore(int client_id, int score); void server_setclientscore(int client_id, int score);
@ -770,9 +774,19 @@ int server_tickspeed();
/* input */ /* input */
int inp_key_was_pressed(int key); int inp_key_was_pressed(int key);
int inp_key_down(int key); int inp_key_down(int key);
char inp_last_char();
int inp_last_key();
void inp_clear();
typedef struct
{
char ch;
int key;
} INPUTEVENT;
int inp_num_events();
INPUTEVENT inp_get_event(int index);
void inp_clear_events();
void inp_update(); void inp_update();
void inp_init(); void inp_init();
void inp_mouse_mode_absolute(); void inp_mouse_mode_absolute();
@ -831,6 +845,7 @@ float client_intrapredtick();
int client_tickspeed(); int client_tickspeed();
float client_frametime(); float client_frametime();
float client_localtime(); float client_localtime();
void client_direct_input(int *input, int size);
int client_state(); int client_state();
const char *client_error_string(); const char *client_error_string();

View file

@ -89,6 +89,7 @@ typedef struct
int last_acked_snapshot; int last_acked_snapshot;
SNAPSTORAGE snapshots; SNAPSTORAGE snapshots;
CLIENT_INPUT latestinput;
CLIENT_INPUT inputs[200]; /* TODO: handle input better */ CLIENT_INPUT inputs[200]; /* TODO: handle input better */
int current_input; int current_input;
@ -184,6 +185,13 @@ void snap_free_id(int id)
} }
} }
int *server_latestinput(int client_id, int *size)
{
if(client_id < 0 || client_id > MAX_CLIENTS || clients[client_id].state < SRVCLIENT_STATE_READY)
return 0;
return clients[client_id].latestinput.data;
}
const char *server_clientname(int client_id) const char *server_clientname(int client_id)
{ {
if(client_id < 0 || client_id > MAX_CLIENTS || clients[client_id].state < SRVCLIENT_STATE_READY) if(client_id < 0 || client_id > MAX_CLIENTS || clients[client_id].state < SRVCLIENT_STATE_READY)
@ -489,6 +497,8 @@ static int new_client_callback(int cid, void *user)
} }
clients[cid].current_input = 0; clients[cid].current_input = 0;
mem_zero(&clients[cid].latestinput, sizeof(clients[cid].latestinput));
snapstorage_purge_all(&clients[cid].snapshots); snapstorage_purge_all(&clients[cid].snapshots);
clients[cid].last_acked_snapshot = -1; clients[cid].last_acked_snapshot = -1;
clients[cid].snap_rate = SRVCLIENT_SNAPRATE_INIT; clients[cid].snap_rate = SRVCLIENT_SNAPRATE_INIT;
@ -624,7 +634,9 @@ static void server_process_client_packet(NETPACKET *packet)
for(i = 0; i < size/4; i++) for(i = 0; i < size/4; i++)
input->data[i] = msg_unpack_int(); input->data[i] = msg_unpack_int();
mem_copy(clients[cid].latestinput.data, input->data, MAX_INPUT_SIZE*sizeof(int));
clients[cid].current_input++; clients[cid].current_input++;
clients[cid].current_input %= 200; clients[cid].current_input %= 200;
} }

View file

@ -33,6 +33,8 @@ data_container *data = 0x0;
static player_input input_data = {0}; static player_input input_data = {0};
static int input_target_lock = 0; static int input_target_lock = 0;
static int64 debug_firedelay = 0;
extern void modmenu_render(); extern void modmenu_render();
extern void menu_init(); extern void menu_init();
@ -79,8 +81,25 @@ static struct client_data
int emoticon_start; int emoticon_start;
player_core predicted; player_core predicted;
tee_render_info skin_info; tee_render_info skin_info; // this is what the server reports
tee_render_info render_info; // this is what we use
void update_render_info()
{
render_info = skin_info;
// force team colors
if(gameobj && gameobj->gametype != GAMETYPE_DM)
{
const int team_colors[2] = {65387, 10223467};
if(team >= 0 || team <= 1)
{
render_info.texture = skin_get(skin_id)->color_texture;
render_info.color_body = skin_get_color(team_colors[team]);
render_info.color_feet = skin_get_color(team_colors[team]);
}
}
}
} client_datas[MAX_CLIENTS]; } client_datas[MAX_CLIENTS];
class client_effects class client_effects
@ -915,6 +934,9 @@ extern "C" void modc_newsnapshot()
if(item.type == OBJTYPE_PLAYER_INFO) if(item.type == OBJTYPE_PLAYER_INFO)
{ {
const obj_player_info *info = (const obj_player_info *)data; const obj_player_info *info = (const obj_player_info *)data;
client_datas[info->clientid].team = info->team;
if(info->local) if(info->local)
{ {
local_info = info; local_info = info;
@ -938,6 +960,9 @@ extern "C" void modc_newsnapshot()
} }
} }
} }
for(int i = 0; i < MAX_CLIENTS; i++)
client_datas[i].update_render_info();
} }
void send_info(bool start) void send_info(bool start)
@ -963,8 +988,15 @@ void send_emoticon(int emoticon)
client_send_msg(); client_send_msg();
} }
static void render_projectile(const obj_projectile *prev, const obj_projectile *current, int itemid) static void render_projectile(const obj_projectile *current, int itemid)
{ {
if(debug_firedelay)
{
debug_firedelay = time_get()-debug_firedelay;
dbg_msg("game", "firedelay=%.2f ms", debug_firedelay/(float)time_freq()*1000.0f);
debug_firedelay = 0;
}
gfx_texture_set(data->images[IMAGE_GAME].id); gfx_texture_set(data->images[IMAGE_GAME].id);
gfx_quads_begin(); gfx_quads_begin();
@ -1143,10 +1175,10 @@ void anim_eval_add(animstate *state, animation *anim, float time, float amount)
anim_add(state, &add, amount); anim_add(state, &add, amount);
} }
static void render_hand(int skin_id, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset) static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset)
{ {
// for drawing hand // for drawing hand
const skin *s = skin_get(skin_id); //const skin *s = skin_get(skin_id);
float basesize = 10.0f; float basesize = 10.0f;
//dir = normalize(hook_pos-pos); //dir = normalize(hook_pos-pos);
@ -1168,8 +1200,9 @@ static void render_hand(int skin_id, vec2 center_pos, vec2 dir, float angle_offs
hand_pos += diry * post_rot_offset.y; hand_pos += diry * post_rot_offset.y;
//gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id); //gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
gfx_texture_set(s->color_texture); gfx_texture_set(info->texture);
gfx_quads_begin(); gfx_quads_begin();
gfx_setcolor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a);
// two passes // two passes
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@ -1382,11 +1415,6 @@ static void render_player(
} }
} }
// TODO: proper skin selection
int skin_id = client_datas[info.clientid].skin_id; //charids[info.clientid];
//if(gametype != GAMETYPE_DM)
//skin_id = info.team*9; // 0 or 9
vec2 direction = get_direction(player.angle); vec2 direction = get_direction(player.angle);
float angle = player.angle/256.0f; float angle = player.angle/256.0f;
vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick); vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick);
@ -1463,7 +1491,7 @@ static void render_player(
gfx_quads_setrotation(0); gfx_quads_setrotation(0);
gfx_quads_end(); gfx_quads_end();
render_hand(skin_id, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0)); render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
} }
// draw gun // draw gun
@ -1581,9 +1609,9 @@ static void render_player(
switch (player.weapon) switch (player.weapon)
{ {
case WEAPON_GUN: render_hand(skin_id, p, direction, -3*pi/4, vec2(-15, 4)); break; case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
case WEAPON_SHOTGUN: render_hand(skin_id, p, direction, -pi/2, vec2(-5, 4)); break; case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
case WEAPON_ROCKET: render_hand(skin_id, p, direction, -pi/2, vec2(-4, 7)); break; case WEAPON_ROCKET: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
} }
} }
@ -1592,14 +1620,14 @@ static void render_player(
if(info.local && config.debug) if(info.local && config.debug)
{ {
vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick()); vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick());
tee_render_info ghost = client_datas[info.clientid].skin_info; tee_render_info ghost = client_datas[info.clientid].render_info;
ghost.color_body.a = 0.5f; ghost.color_body.a = 0.5f;
ghost.color_feet.a = 0.5f; ghost.color_feet.a = 0.5f;
render_tee(&state, &ghost, player.emote, direction, ghost_position); // render ghost render_tee(&state, &ghost, player.emote, direction, ghost_position); // render ghost
} }
// render the tee // render the tee
render_tee(&state, &client_datas[info.clientid].skin_info, player.emote, direction, position); render_tee(&state, &client_datas[info.clientid].render_info, player.emote, direction, position);
if(player.state == STATE_CHATTING) if(player.state == STATE_CHATTING)
{ {
@ -2103,7 +2131,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
gfx_quads_end(); gfx_quads_end();
} }
render_tee(&idlestate, &client_datas[info->clientid].skin_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28)); render_tee(&idlestate, &client_datas[info->clientid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
y += 50.0f; y += 50.0f;
@ -2202,9 +2230,9 @@ void render_world(float center_x, float center_y, float zoom)
if(item.type == OBJTYPE_PROJECTILE) if(item.type == OBJTYPE_PROJECTILE)
{ {
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); //const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
if(prev) //if(prev)
render_projectile((const obj_projectile *)prev, (const obj_projectile *)data, item.id); render_projectile((const obj_projectile *)data, item.id);
} }
else if(item.type == OBJTYPE_POWERUP) else if(item.type == OBJTYPE_POWERUP)
{ {
@ -2235,8 +2263,6 @@ void render_world(float center_x, float center_y, float zoom)
const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id); const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id); const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
client_datas[((const obj_player_info *)info)->clientid].team = ((const obj_player_info *)info)->team;
if(prev && prev_info && info) if(prev && prev_info && info)
{ {
render_player( render_player(
@ -2364,28 +2390,29 @@ void render_game()
chat_mode = CHATMODE_NONE; chat_mode = CHATMODE_NONE;
} }
int c = inp_last_char(); for(int i = 0; i < inp_num_events(); i++)
int k = inp_last_key();
if (!(c >= 0 && c < 32))
{ {
if (chat_input_len < sizeof(chat_input) - 1) INPUTEVENT e = inp_get_event(i);
if (!(e.ch >= 0 && e.ch < 32))
{ {
chat_input[chat_input_len] = c; if (chat_input_len < sizeof(chat_input) - 1)
chat_input[chat_input_len+1] = 0; {
chat_input_len++; chat_input[chat_input_len] = e.ch;
chat_input[chat_input_len+1] = 0;
chat_input_len++;
}
}
if(e.key == KEY_BACKSPACE)
{
if(chat_input_len > 0)
{
chat_input[chat_input_len-1] = 0;
chat_input_len--;
}
} }
} }
if(k == KEY_BACKSPACE)
{
if(chat_input_len > 0)
{
chat_input[chat_input_len-1] = 0;
chat_input_len--;
}
}
} }
else else
{ {
@ -2413,7 +2440,7 @@ void render_game()
} }
if (!menu_active) if (!menu_active)
inp_clear(); inp_clear_events();
// fetch new input // fetch new input
if(!menu_active && !emoticon_selector_active) if(!menu_active && !emoticon_selector_active)
@ -2451,6 +2478,8 @@ void render_game()
// update some input // update some input
if(!menu_active && chat_mode == CHATMODE_NONE) if(!menu_active && chat_mode == CHATMODE_NONE)
{ {
bool do_direct = false;
if(!emoticon_selector_active) if(!emoticon_selector_active)
{ {
if(do_input(&input_data.fire, config.key_fire)) if(do_input(&input_data.fire, config.key_fire))
@ -2460,6 +2489,17 @@ void render_game()
input_data.target_x = (int)mouse_pos.x; input_data.target_x = (int)mouse_pos.x;
input_data.target_y = (int)mouse_pos.y; input_data.target_y = (int)mouse_pos.y;
input_target_lock = 1; input_target_lock = 1;
if(inp_key_presses(config.key_fire))
{
if(config.dbg_firedelay)
{
if(debug_firedelay == 0)
debug_firedelay = time_get();
}
do_direct = true;
}
} }
} }
@ -2480,6 +2520,9 @@ void render_game()
if(inp_key_presses(config.key_weapon5)) input_data.wanted_weapon = 5; if(inp_key_presses(config.key_weapon5)) input_data.wanted_weapon = 5;
if(inp_key_presses(config.key_weapon6)) input_data.wanted_weapon = 6; if(inp_key_presses(config.key_weapon6)) input_data.wanted_weapon = 6;
} }
if(do_direct) // do direct input if wanted
client_direct_input((int *)&input_data, sizeof(input_data));
} }
@ -2720,7 +2763,7 @@ void render_game()
} }
} }
render_tee(&idlestate, &client_datas[killmsgs[r].victim].skin_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28)); render_tee(&idlestate, &client_datas[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
x -= 32.0f; x -= 32.0f;
// render weapon // render weapon
@ -2756,7 +2799,7 @@ void render_game()
// render killer tee // render killer tee
x -= 24.0f; x -= 24.0f;
render_tee(&idlestate, &client_datas[killmsgs[r].killer].skin_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28)); render_tee(&idlestate, &client_datas[killmsgs[r].killer].render_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
x -= 32.0f; x -= 32.0f;
// render killer name // render killer name
@ -2913,7 +2956,7 @@ void render_game()
const char *name = client_datas[id].name; const char *name = client_datas[id].name;
float w = gfx_pretty_text_width(10, name, -1); float w = gfx_pretty_text_width(10, name, -1);
gfx_pretty_text(whole-40-5-w, 300-40-15+t*20+2, 10, name, -1); gfx_pretty_text(whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
tee_render_info info = client_datas[id].skin_info; tee_render_info info = client_datas[id].render_info;
info.size = 18.0f; info.size = 18.0f;
render_tee(&idlestate, &info, EMOTE_NORMAL, vec2(1,0), render_tee(&idlestate, &info, EMOTE_NORMAL, vec2(1,0),
@ -3117,6 +3160,8 @@ extern "C" void modc_statechange(int state, int old)
menu_do_disconnected(); menu_do_disconnected();
menu_game_active = false; menu_game_active = false;
} }
else if(state == CLIENTSTATE_LOADING)
menu_do_connecting();
else if(state == CLIENTSTATE_CONNECTING) else if(state == CLIENTSTATE_CONNECTING)
menu_do_connecting(); menu_do_connecting();
else if (state == CLIENTSTATE_ONLINE) else if (state == CLIENTSTATE_ONLINE)
@ -3171,6 +3216,8 @@ extern "C" void modc_message(int msg)
client_datas[cid].skin_info.color_body = vec4(1,1,1,1); client_datas[cid].skin_info.color_body = vec4(1,1,1,1);
client_datas[cid].skin_info.color_feet = vec4(1,1,1,1); client_datas[cid].skin_info.color_feet = vec4(1,1,1,1);
} }
client_datas[cid].update_render_info();
} }
else if(msg == MSG_WEAPON_PICKUP) else if(msg == MSG_WEAPON_PICKUP)
{ {

View file

@ -451,6 +451,7 @@ static void ui2_draw_checkbox(const void *id, const char *text, int checked, con
ui2_draw_checkbox_common(id, text, checked?"X":"", r); ui2_draw_checkbox_common(id, text, checked?"X":"", r);
} }
static void ui2_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, void *extra) static void ui2_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, void *extra)
{ {
char buf[16]; char buf[16];
@ -466,8 +467,6 @@ int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hi
if(ui_last_active_item() == id) if(ui_last_active_item() == id)
{ {
int c = inp_last_char();
int k = inp_last_key();
int len = strlen(str); int len = strlen(str);
if (inside && ui_mouse_button(0)) if (inside && ui_mouse_button(0))
@ -489,35 +488,42 @@ int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hi
if (at_index > len) if (at_index > len)
at_index = len; at_index = len;
if (!(c >= 0 && c < 32)) for(int i = 0; i < inp_num_events(); i++)
{ {
if (len < str_size - 1 && at_index < str_size - 1) INPUTEVENT e = inp_get_event(i);
char c = e.ch;
int k = e.key;
if (!(c >= 0 && c < 32))
{ {
memmove(str + at_index + 1, str + at_index, len - at_index + 1); if (len < str_size - 1 && at_index < str_size - 1)
str[at_index] = c; {
at_index++; memmove(str + at_index + 1, str + at_index, len - at_index + 1);
str[at_index] = c;
at_index++;
}
} }
}
if (k == KEY_BACKSPACE && at_index > 0) if (k == KEY_BACKSPACE && at_index > 0)
{ {
memmove(str + at_index - 1, str + at_index, len - at_index + 1); memmove(str + at_index - 1, str + at_index, len - at_index + 1);
at_index--; at_index--;
}
else if (k == KEY_DEL && at_index < len)
memmove(str + at_index, str + at_index + 1, len - at_index);
else if (k == KEY_ENTER)
ui_clear_last_active_item();
else if (k == KEY_LEFT && at_index > 0)
at_index--;
else if (k == KEY_RIGHT && at_index < len)
at_index++;
else if (k == KEY_HOME)
at_index = 0;
else if (k == KEY_END)
at_index = len;
} }
else if (k == KEY_DEL && at_index < len)
memmove(str + at_index, str + at_index + 1, len - at_index);
else if (k == KEY_ENTER)
ui_clear_last_active_item();
else if (k == KEY_LEFT && at_index > 0)
at_index--;
else if (k == KEY_RIGHT && at_index < len)
at_index++;
else if (k == KEY_HOME)
at_index = 0;
else if (k == KEY_END)
at_index = len;
r = 1; r = 1;
} }
@ -698,14 +704,17 @@ int ui2_do_key_reader(void *id, const RECT *rect, int key)
if(ui_active_item() == id) if(ui_active_item() == id)
{ {
int k = inp_last_key(); for(int i = 0; i < inp_num_events(); i++)
if (k)
{ {
if(k != KEY_ESC) INPUTEVENT e = inp_get_event(i);
new_key = k; if(e.key && e.key != KEY_ESC)
{
ui_set_active_item(0); new_key = e.key;
mouse_released = false; ui_set_active_item(0);
mouse_released = false;
inp_clear_events();
break;
}
} }
} }
else if(ui_hot_item() == id) else if(ui_hot_item() == id)
@ -912,14 +921,15 @@ static void menu2_render_serverbrowser(RECT main_view)
RECT server_scoreboard; RECT server_scoreboard;
//ui2_hsplit_t(&view, 20.0f, &status, &view); //ui2_hsplit_t(&view, 20.0f, &status, &view);
ui2_hsplit_b(&view, 90.0f, &view, &filters); ui2_hsplit_b(&view, 110.0f, &view, &filters);
// split off a piece for details and scoreboard // split off a piece for details and scoreboard
ui2_vsplit_r(&view, 200.0f, &view, &server_details); ui2_vsplit_r(&view, 200.0f, &view, &server_details);
// server list // server list
ui2_hsplit_t(&view, 20.0f, &headers, &view); ui2_hsplit_t(&view, 20.0f, &headers, &view);
ui2_hsplit_b(&view, 5.0f, &view, 0x0); //ui2_hsplit_b(&view, 110.0f, &view, &filters);
ui2_hsplit_b(&view, 5.0f, &view, 0);
ui2_hsplit_b(&view, 20.0f, &view, &status); ui2_hsplit_b(&view, 20.0f, &view, &status);
//ui2_vsplit_r(&filters, 300.0f, &filters, &toolbox); //ui2_vsplit_r(&filters, 300.0f, &filters, &toolbox);
@ -1031,7 +1041,7 @@ static void menu2_render_serverbrowser(RECT main_view)
int num = (int)(view.h/cols[0].rect.h); int num = (int)(view.h/cols[0].rect.h);
static int scrollbar = 0; static int scrollbar = 0;
static float scrollvalue = 0; static float scrollvalue = 0;
static int selected_index = -1; //static int selected_index = -1;
ui2_hmargin(&scroll, 5.0f, &scroll); ui2_hmargin(&scroll, 5.0f, &scroll);
scrollvalue = ui2_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); scrollvalue = ui2_do_scrollbar_v(&scrollbar, &scroll, scrollvalue);
@ -1059,8 +1069,8 @@ static void menu2_render_serverbrowser(RECT main_view)
RECT original_view = view; RECT original_view = view;
view.y -= scrollvalue*scrollnum*cols[0].rect.h; view.y -= scrollvalue*scrollnum*cols[0].rect.h;
//int r = -1; int new_selected = -1;
int new_selected = selected_index; int selected_index = -1;
for (int i = 0; i < num_servers; i++) for (int i = 0; i < num_servers; i++)
{ {
@ -1069,10 +1079,12 @@ static void menu2_render_serverbrowser(RECT main_view)
RECT row; RECT row;
RECT select_hit_box; RECT select_hit_box;
int l = selected_index==item_index; int selected = strcmp(item->address, config.ui_server_address) == 0; //selected_index==item_index;
if(l) if(selected)
{ {
selected_index = i;
// selected server, draw the players on it // selected server, draw the players on it
RECT whole; RECT whole;
int h = (item->num_players+2)/3; int h = (item->num_players+2)/3;
@ -1129,13 +1141,9 @@ static void menu2_render_serverbrowser(RECT main_view)
select_hit_box.y = original_view.y; select_hit_box.y = original_view.y;
} }
if(ui2_do_button(item, "", l, &select_hit_box, 0, 0)) if(ui2_do_button(item, "", selected, &select_hit_box, 0, 0))
{ {
new_selected = item_index; new_selected = item_index;
dbg_msg("dbg", "addr = %s", item->address);
strncpy(config.ui_server_address, item->address, sizeof(config.ui_server_address));
if(inp_mouse_doubleclick())
client_connect(config.ui_server_address);
} }
} }
@ -1197,21 +1205,20 @@ static void menu2_render_serverbrowser(RECT main_view)
else if(item->game_type == GAMETYPE_CTF) type = "CTF"; else if(item->game_type == GAMETYPE_CTF) type = "CTF";
ui2_do_label(&button, type, 15.0f, 0); ui2_do_label(&button, type, 15.0f, 0);
} }
/*
if(s)
{
new_selected = item_index;
dbg_msg("dbg", "addr = %s", item->address);
strncpy(config.ui_server_address, item->address, sizeof(config.ui_server_address));
}*/
} }
} }
ui2_clip_disable(); ui2_clip_disable();
selected_index = new_selected; if(new_selected != -1)
{
// select the new server
SERVER_INFO *item = client_serverbrowse_sorted_get(new_selected);
strncpy(config.ui_server_address, item->address, sizeof(config.ui_server_address));
if(inp_mouse_doubleclick())
client_connect(config.ui_server_address);
}
SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index); SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index);
RECT server_header; RECT server_header;
@ -1267,7 +1274,10 @@ static void menu2_render_serverbrowser(RECT main_view)
char temp[16]; char temp[16];
sprintf(temp, "%d%%", selected_server->progression); if(selected_server->progression < 0)
sprintf(temp, "N/A");
else
sprintf(temp, "%d%%", selected_server->progression);
ui2_hsplit_t(&right_column, 15.0f, &row, &right_column); ui2_hsplit_t(&right_column, 15.0f, &row, &right_column);
ui2_do_label(&row, temp, 13.0f, -1); ui2_do_label(&row, temp, 13.0f, -1);
@ -1304,13 +1314,15 @@ static void menu2_render_serverbrowser(RECT main_view)
} }
} }
// render quick search
RECT button; RECT button;
RECT types;
ui2_hsplit_t(&filters, 20.0f, &button, &filters); ui2_hsplit_t(&filters, 20.0f, &button, &filters);
ui2_do_label(&button, "Quick search: ", 14.0f, -1); ui2_do_label(&button, "Quick search: ", 14.0f, -1);
ui2_vsplit_l(&button, 95.0f, 0, &button); ui2_vsplit_l(&button, 95.0f, 0, &button);
ui2_do_edit_box(&config.b_filter_string, &button, config.b_filter_string, sizeof(config.b_filter_string)); ui2_do_edit_box(&config.b_filter_string, &button, config.b_filter_string, sizeof(config.b_filter_string));
ui2_vsplit_l(&filters, 180.0f, &filters, &types);
// render filters // render filters
ui2_hsplit_t(&filters, 20.0f, &button, &filters); ui2_hsplit_t(&filters, 20.0f, &button, &filters);
if (ui2_do_button(&config.b_filter_empty, "Has people playing", config.b_filter_empty, &button, ui2_draw_checkbox, 0)) if (ui2_do_button(&config.b_filter_empty, "Has people playing", config.b_filter_empty, &button, ui2_draw_checkbox, 0))
@ -1321,9 +1333,36 @@ static void menu2_render_serverbrowser(RECT main_view)
config.b_filter_full ^= 1; config.b_filter_full ^= 1;
ui2_hsplit_t(&filters, 20.0f, &button, &filters); ui2_hsplit_t(&filters, 20.0f, &button, &filters);
if (ui2_do_button(&config.b_filter_pw, "Is not password protected", config.b_filter_pw, &button, ui2_draw_checkbox, 0)) if (ui2_do_button(&config.b_filter_pw, "No password", config.b_filter_pw, &button, ui2_draw_checkbox, 0))
config.b_filter_pw ^= 1; config.b_filter_pw ^= 1;
ui2_hsplit_t(&filters, 2.0f, &button, &filters); // ping
ui2_hsplit_t(&filters, 20.0f, &button, &filters);
{
RECT editbox;
ui2_vsplit_l(&button, 40.0f, &editbox, &button);
ui2_vsplit_l(&button, 5.0f, &button, &button);
char buf[8];
sprintf(buf, "%d", config.b_filter_ping);
ui2_do_edit_box(&config.b_filter_ping, &editbox, buf, sizeof(buf));
config.b_filter_ping = atoi(buf);
ui2_do_label(&button, "Maximum ping", 14.0f, -1);
}
ui2_hsplit_t(&types, 20.0f, &button, &types);
if (ui2_do_button(&config.b_filter_gametype, "DM", config.b_filter_gametype&(1<<GAMETYPE_DM), &button, ui2_draw_checkbox, 0))
config.b_filter_gametype ^= (1<<GAMETYPE_DM);
ui2_hsplit_t(&types, 20.0f, &button, &types);
if (ui2_do_button((char *)&config.b_filter_gametype + 1, "TDM", config.b_filter_gametype&(1<<GAMETYPE_TDM), &button, ui2_draw_checkbox, 0))
config.b_filter_gametype ^= (1<<GAMETYPE_TDM);
ui2_hsplit_t(&types, 20.0f, &button, &types);
if (ui2_do_button((char *)&config.b_filter_gametype + 2, "CTF", config.b_filter_gametype&(1<<GAMETYPE_CTF), &button, ui2_draw_checkbox, 0))
config.b_filter_gametype ^= (1<<GAMETYPE_CTF);
// render status // render status
ui2_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f); ui2_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f);
ui2_vmargin(&status, 50.0f, &status); ui2_vmargin(&status, 50.0f, &status);
@ -1749,6 +1788,10 @@ static void menu2_render_settings_sound(RECT main_view)
if(!config.snd_enable) if(!config.snd_enable)
return; return;
ui2_hsplit_t(&main_view, 20.0f, &button, &main_view);
if (ui2_do_button(&config.snd_nonactive_mute, "Mute when not active", config.snd_nonactive_mute, &button, ui2_draw_checkbox, 0))
config.snd_nonactive_mute ^= 1;
// sample rate box // sample rate box
{ {
char buf[64]; char buf[64];
@ -2273,5 +2316,5 @@ void modmenu_render()
gfx_quads_drawTL(mx,my,24,24); gfx_quads_drawTL(mx,my,24,24);
gfx_quads_end(); gfx_quads_end();
inp_clear(); inp_clear_events();
} }

View file

@ -41,7 +41,7 @@ MACRO_CONFIG_INT(player_color_body, 65408, 0, 0)
MACRO_CONFIG_INT(player_color_feet, 65408, 0, 0) MACRO_CONFIG_INT(player_color_feet, 65408, 0, 0)
MACRO_CONFIG_STR(player_skin, 64, "default") MACRO_CONFIG_STR(player_skin, 64, "default")
MACRO_CONFIG_INT(dbg_new_gui, 0, 0, 1) MACRO_CONFIG_INT(dbg_firedelay, 0, 0, 1)
MACRO_CONFIG_INT(ui_page, 1, 0, 5) MACRO_CONFIG_INT(ui_page, 1, 0, 5)
MACRO_CONFIG_STR(ui_server_address, 128, "localhost:8303") MACRO_CONFIG_STR(ui_server_address, 128, "localhost:8303")

View file

@ -1,4 +1,4 @@
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#include "generated/nethash.c" #include "generated/nethash.c"
#define TEEWARS_VERSION "0.3.1" #define TEEWARS_VERSION "0.3.3"
#define TEEWARS_NETVERSION "0.3 " TEEWARS_NETVERSION_HASH #define TEEWARS_NETVERSION "0.3 " TEEWARS_NETVERSION_HASH

View file

@ -261,6 +261,11 @@ public:
int color_body; int color_body;
int color_feet; int color_feet;
// these are non-heldback inputs
player_input latest_previnput;
player_input latest_input;
// input // input
player_input previnput; player_input previnput;
player_input input; player_input input;

View file

@ -589,9 +589,10 @@ static float evaluate_spawn(spawneval *eval, vec2 pos)
if(!(players[c].flags&entity::FLAG_PHYSICS)) if(!(players[c].flags&entity::FLAG_PHYSICS))
continue; continue;
// don't count friends // team mates are not as dangerous as enemies
float scoremod = 1.0f;
if(eval->friendly_team != -1 && players[c].team == eval->friendly_team) if(eval->friendly_team != -1 && players[c].team == eval->friendly_team)
continue; scoremod = 0.5f;
float d = distance(pos, players[c].pos); float d = distance(pos, players[c].pos);
if(d == 0) if(d == 0)
@ -734,7 +735,7 @@ bool player::is_grounded()
int player::handle_ninja() int player::handle_ninja()
{ {
vec2 direction = normalize(vec2(input.target_x, input.target_y)); vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
if ((server_tick() - ninja_activationtick) > (data->weapons[WEAPON_NINJA].duration * server_tickspeed() / 1000)) if ((server_tick() - ninja_activationtick) > (data->weapons[WEAPON_NINJA].duration * server_tickspeed() / 1000))
{ {
@ -746,7 +747,7 @@ int player::handle_ninja()
} }
// Check if it should activate // Check if it should activate
if (count_input(previnput.fire, input.fire).presses && (server_tick() > currentcooldown)) if (count_input(latest_previnput.fire, latest_input.fire).presses && (server_tick() > currentcooldown))
{ {
// ok then, activate ninja // ok then, activate ninja
attack_tick = server_tick(); attack_tick = server_tick();
@ -958,7 +959,7 @@ int player::handle_bomb()
int player::handle_weapons() int player::handle_weapons()
{ {
vec2 direction = normalize(vec2(input.target_x, input.target_y)); vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
if(config.dbg_stress) if(config.dbg_stress)
{ {
@ -986,8 +987,8 @@ int player::handle_weapons()
} }
// select weapon // select weapon
int next = count_input(previnput.next_weapon, input.next_weapon).presses; int next = count_input(latest_previnput.next_weapon, latest_input.next_weapon).presses;
int prev = count_input(previnput.prev_weapon, input.prev_weapon).presses; int prev = count_input(latest_previnput.prev_weapon, latest_input.prev_weapon).presses;
if(next < 128) // make sure we only try sane stuff if(next < 128) // make sure we only try sane stuff
{ {
@ -1009,7 +1010,7 @@ int player::handle_weapons()
} }
} }
if(input.wanted_weapon) // direct weapon selection if(latest_input.wanted_weapon) // direct weapon selection
wanted_weapon = input.wanted_weapon-1; wanted_weapon = input.wanted_weapon-1;
if(wanted_weapon < 0 || wanted_weapon >= NUM_WEAPONS) if(wanted_weapon < 0 || wanted_weapon >= NUM_WEAPONS)
@ -1041,7 +1042,7 @@ int player::handle_weapons()
if(active_weapon == WEAPON_ROCKET || active_weapon == WEAPON_SHOTGUN) if(active_weapon == WEAPON_ROCKET || active_weapon == WEAPON_SHOTGUN)
fullauto = true; fullauto = true;
if(count_input(previnput.fire, input.fire).presses || ((fullauto && input.fire&1) && weapons[active_weapon].ammo)) if(count_input(latest_previnput.fire, latest_input.fire).presses || ((fullauto && latest_input.fire&1) && weapons[active_weapon].ammo))
{ {
// fire! // fire!
if(weapons[active_weapon].ammo) if(weapons[active_weapon].ammo)
@ -1211,12 +1212,26 @@ int player::handle_weapons()
void player::tick() void player::tick()
{ {
server_setclientscore(client_id, score); server_setclientscore(client_id, score);
// grab latest input
{
int size = 0;
int *input = server_latestinput(client_id, &size);
if(input)
{
mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
mem_copy(&latest_input, input, sizeof(latest_input));
}
}
// check if we have enough input // check if we have enough input
// this is to prevent initial weird clicks // this is to prevent initial weird clicks
if(num_inputs < 2) if(num_inputs < 2)
{
latest_previnput = latest_input;
previnput = input; previnput = input;
}
// do latency stuff // do latency stuff
{ {
CLIENT_INFO info; CLIENT_INFO info;
@ -1254,7 +1269,7 @@ void player::tick()
// TODO: rework the input to be more robust // TODO: rework the input to be more robust
if(dead) if(dead)
{ {
if(server_tick()-die_tick >= server_tickspeed()/2 && count_input(previnput.fire, input.fire).presses) if(server_tick()-die_tick >= server_tickspeed()/2 && count_input(latest_previnput.fire, latest_input.fire).presses)
die_tick = -1; die_tick = -1;
if(server_tick()-die_tick >= server_tickspeed()*5) // auto respawn after 3 sec if(server_tick()-die_tick >= server_tickspeed()*5) // auto respawn after 3 sec
respawn(); respawn();
@ -1466,7 +1481,7 @@ void player::snap(int snaping_client)
info->local = 1; info->local = 1;
} }
if(health > 0 && distance(players[snaping_client].pos, pos) < 1000.0f) if(health > 0 && team >= 0 && distance(players[snaping_client].pos, pos) < 1000.0f)
{ {
obj_player_character *character = (obj_player_character *)snap_new_item(OBJTYPE_PLAYER_CHARACTER, client_id, sizeof(obj_player_character)); obj_player_character *character = (obj_player_character *)snap_new_item(OBJTYPE_PLAYER_CHARACTER, client_id, sizeof(obj_player_character));