diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp index e5044ea8b..0c619c27c 100644 --- a/src/game/client/game_client.cpp +++ b/src/game/client/game_client.cpp @@ -342,7 +342,7 @@ public: num_particles = 0; } - void new_particle(vec2 pos, vec2 vel, float life, float size, float gravity, float friction) + void new_particle(vec2 pos, vec2 vel, float life, float size, float gravity, float friction, vec4 color=vec4(1,1,1,1)) { if (num_particles >= MAX_PARTICLES) return; @@ -357,6 +357,7 @@ public: particles[num_particles].friction = friction; particles[num_particles].rot = frandom()*pi*2; particles[num_particles].rotspeed = frandom() * 10.0f; + particles[num_particles].color = color; num_particles++; } @@ -398,10 +399,10 @@ public: gfx_quads_setrotation(particles[i].rot); gfx_setcolor( - data->particles[type].color_r, - data->particles[type].color_g, - data->particles[type].color_b, - pow(a, 0.75f)); + data->particles[type].color_r * particles[i].color.r, + data->particles[type].color_g * particles[i].color.g, + data->particles[type].color_b * particles[i].color.b, + pow(a, 0.75f) * particles[i].color.a); gfx_quads_draw(p.x, p.y,particles[i].size,particles[i].size); } @@ -798,15 +799,40 @@ extern "C" void modc_predict() world.players[c]->move(); world.players[c]->quantize(); + } + + if(tick > last_new_predicted_tick) + { + last_new_predicted_tick = tick; - if(tick > last_new_predicted_tick) + if(local_cid != -1 && world.players[local_cid]) { - last_new_predicted_tick = tick; - /* - dbg_msg("predict", "%d %d %d", tick, - (int)world.players[c]->pos.x, (int)world.players[c]->pos.y, - (int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/ + vec2 pos = world.players[local_cid]->pos; + int events = world.players[local_cid]->triggered_events; + if(events&COREEVENT_GROUND_JUMP) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); + if(events&COREEVENT_AIR_JUMP) + { + const int count = 12; + for(int i = 0; i <= count; i++) + { + float a = i/(float)count; + vec2 v = vec2((a-0.5f)*512.0f, 0); + temp_system.new_particle(pos+vec2(0,28), v, 0.4f, 16.0f, 0, 0.985f, vec4(0.25f,0.4f,1,1)); + } + + snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); + } + //if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos); + if(events&COREEVENT_HOOK_ATTACH_PLAYER) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH, 1.0f, pos); + if(events&COREEVENT_HOOK_ATTACH_GROUND) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH, 1.0f, pos); + //if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); } + + + /* + dbg_msg("predict", "%d %d %d", tick, + (int)world.players[c]->pos.x, (int)world.players[c]->pos.y, + (int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/ } if(tick == client_predtick() && world.players[local_cid]) diff --git a/src/game/game.cpp b/src/game/game.cpp index 4969a0f81..bbeb59403 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -101,6 +101,7 @@ void move_box(vec2 *inout_pos, vec2 *inout_vel, vec2 size, float elasticity) void player_core::tick() { float phys_size = 28.0f; + triggered_events = 0; #define MACRO_CHECK_VELOCITY { dbg_assert(length(vel) < 1000.0f, "velocity error"); } @@ -147,11 +148,13 @@ void player_core::tick() { if(grounded) { + triggered_events |= COREEVENT_GROUND_JUMP; vel.y = -ground_jump_speed; jumped |= 1; } else if(!(jumped&2)) { + triggered_events |= COREEVENT_AIR_JUMP; vel.y = -ground_air_speed; jumped |= 3; } @@ -172,6 +175,7 @@ void player_core::tick() hook_dir = direction; hooked_player = -1; hook_tick = -1; + triggered_events |= COREEVENT_HOOK_LAUNCH; } else if(hook_state == HOOK_FLYING) { @@ -187,6 +191,7 @@ void player_core::tick() //if(p != this && !p->dead && distance(p->pos, new_pos) < p->phys_size) if(distance(p->pos, new_pos) < phys_size) { + triggered_events |= COREEVENT_HOOK_ATTACH_PLAYER; hook_state = HOOK_GRABBED; hooked_player = i; break; @@ -212,11 +217,13 @@ void player_core::tick() // check against ground if(col_intersect_line(hook_pos, new_pos, &new_pos)) { + triggered_events |= COREEVENT_HOOK_ATTACH_GROUND; hook_state = HOOK_GRABBED; hook_pos = new_pos; } else if(distance(pos, new_pos) > hook_length) { + triggered_events |= COREEVENT_HOOK_RETRACT; hook_state = HOOK_RETRACTED; } else diff --git a/src/game/game.h b/src/game/game.h index 0951fb488..2c577d3ea 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -69,7 +69,14 @@ enum HOOK_RETRACTED=-1, HOOK_IDLE=0, HOOK_FLYING, - HOOK_GRABBED + HOOK_GRABBED, + + COREEVENT_GROUND_JUMP=0x01, + COREEVENT_AIR_JUMP=0x02, + COREEVENT_HOOK_LAUNCH=0x04, + COREEVENT_HOOK_ATTACH_PLAYER=0x08, + COREEVENT_HOOK_ATTACH_GROUND=0x10, + COREEVENT_HOOK_RETRACT=0x20, }; class world_core @@ -100,6 +107,8 @@ public: int jumped; player_input input; + int triggered_events; + void tick(); void move(); diff --git a/src/game/mapres.h b/src/game/mapres.h index 1b74f51f0..1fc92edc4 100644 --- a/src/game/mapres.h +++ b/src/game/mapres.h @@ -5,4 +5,5 @@ enum MAPRES_IMAGE=0x8001, MAPRES_TILEMAP=0x8002, MAPRES_COLLISIONMAP=0x8003, + MAPRES_TEMP_THEME=0x8fff, }; diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp index 9b69fd919..9b8933579 100644 --- a/src/game/server/game_server.cpp +++ b/src/game/server/game_server.cpp @@ -18,8 +18,7 @@ void create_explosion(vec2 p, int owner, int weapon, bool bnodamage); void create_smoke(vec2 p); void create_spawn(vec2 p); void create_death(vec2 p); -void create_sound(vec2 pos, int sound, int loopflags = 0); -void create_targetted_sound(vec2 pos, int sound, int target, int loopflags = 0); +void create_sound(vec2 pos, int sound, int mask=-1); class player *intersect_player(vec2 pos0, vec2 pos1, vec2 &new_pos, class entity *notthis = 0); game_world *world; @@ -32,7 +31,7 @@ event_handler::event_handler() clear(); } -void *event_handler::create(int type, int size, int target) +void *event_handler::create(int type, int size, int mask) { if(num_events == MAX_EVENTS) return 0; @@ -43,7 +42,7 @@ void *event_handler::create(int type, int size, int target) offsets[num_events] = current_offset; types[num_events] = type; sizes[num_events] = size; - targets[num_events] = target; + client_masks[num_events] = mask; current_offset += size; num_events++; return p; @@ -59,7 +58,7 @@ void event_handler::snap(int snapping_client) { for(int i = 0; i < num_events; i++) { - if (targets[i] == -1 || targets[i] == snapping_client) + if(cmask_is_set(client_masks[i], snapping_client)) { ev_common *ev = (ev_common *)&data[offsets[i]]; if(distance(players[snapping_client].pos, vec2(ev->x, ev->y)) < 1500.0f) @@ -975,6 +974,18 @@ void player::tick_defered() core.move(); core.quantize(); pos = core.pos; + + int events = core.triggered_events; + int mask = cmask_all_except_one(client_id); + + if(events&COREEVENT_GROUND_JUMP) create_sound(pos, SOUND_PLAYER_JUMP, mask); + if(events&COREEVENT_AIR_JUMP) create_sound(pos, SOUND_PLAYER_JUMP, mask); + //if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos); + if(events&COREEVENT_HOOK_ATTACH_PLAYER) create_sound(pos, SOUND_HOOK_ATTACH, mask); + if(events&COREEVENT_HOOK_ATTACH_GROUND) create_sound(pos, SOUND_HOOK_ATTACH, mask); + //if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); + + } if(team == -1) @@ -1056,7 +1067,7 @@ bool player::take_damage(vec2 force, int dmg, int from, int weapon) // do damage hit sound if(from >= 0) - create_targetted_sound(get_player(from)->pos, SOUND_HIT, from); + create_sound(get_player(from)->pos, SOUND_HIT, cmask_one(from)); // check for death if(health <= 0) @@ -1197,7 +1208,7 @@ void powerup::tick() spawntick = -1; if(type == POWERUP_WEAPON) - create_sound(pos, SOUND_WEAPON_SPAWN, 0); + create_sound(pos, SOUND_WEAPON_SPAWN); } else return; @@ -1214,7 +1225,7 @@ void powerup::tick() case POWERUP_HEALTH: if(pplayer->health < 10) { - create_sound(pos, SOUND_PICKUP_HEALTH, 0); + create_sound(pos, SOUND_PICKUP_HEALTH); pplayer->health = min(10, pplayer->health + data->powerupinfo[type].amount); respawntime = data->powerupinfo[type].respawntime; } @@ -1222,7 +1233,7 @@ void powerup::tick() case POWERUP_ARMOR: if(pplayer->armor < 10) { - create_sound(pos, SOUND_PICKUP_ARMOR, 0); + create_sound(pos, SOUND_PICKUP_ARMOR); pplayer->armor = min(10, pplayer->armor + data->powerupinfo[type].amount); respawntime = data->powerupinfo[type].respawntime; } @@ -1392,26 +1403,21 @@ void create_death(vec2 p) } } -void create_targetted_sound(vec2 pos, int sound, int target, int loopingflags) +void create_sound(vec2 pos, int sound, int mask) { if (sound < 0) return; // create a sound - ev_sound *ev = (ev_sound *)events.create(EVENT_SOUND_WORLD, sizeof(ev_sound), target); + ev_sound *ev = (ev_sound *)events.create(EVENT_SOUND_WORLD, sizeof(ev_sound), mask); if(ev) { ev->x = (int)pos.x; ev->y = (int)pos.y; - ev->sound = sound | loopingflags; + ev->sound = sound; } } -void create_sound(vec2 pos, int sound, int loopingflags) -{ - create_targetted_sound(pos, sound, -1, loopingflags); -} - void create_sound_global(int sound, int target) { if (sound < 0) diff --git a/src/game/server/srv_common.h b/src/game/server/srv_common.h index 70e52d5b6..16c78d3ff 100644 --- a/src/game/server/srv_common.h +++ b/src/game/server/srv_common.h @@ -5,6 +5,11 @@ void create_sound_global(int sound, int target=-1); +inline int cmask_all() { return -1; } +inline int cmask_one(int cid) { return 1<