diff options
| author | Olle Rosenquist <phobos99@gmail.com> | 2007-07-21 19:03:50 +0000 |
|---|---|---|
| committer | Olle Rosenquist <phobos99@gmail.com> | 2007-07-21 19:03:50 +0000 |
| commit | 4ef0a10bf9990816f60cfe0f0d4d5131ba08b5cd (patch) | |
| tree | 8bfad3e79a9ef24ba7194fabc8078ff8b0b89384 /src | |
| parent | 0c786f6002380ea8fe8ecc459962d91844965a24 (diff) | |
| download | zcatch-4ef0a10bf9990816f60cfe0f0d4d5131ba08b5cd.tar.gz zcatch-4ef0a10bf9990816f60cfe0f0d4d5131ba08b5cd.zip | |
Updated stuff
Diffstat (limited to 'src')
| -rw-r--r-- | src/game/client/game_client.cpp | 98 | ||||
| -rw-r--r-- | src/game/game.h | 13 | ||||
| -rw-r--r-- | src/game/server/game_server.cpp | 264 | ||||
| -rw-r--r-- | src/game/server/game_server.h | 24 |
4 files changed, 367 insertions, 32 deletions
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp index 359bb880..b1071b76 100644 --- a/src/game/client/game_client.cpp +++ b/src/game/client/game_client.cpp @@ -479,6 +479,31 @@ void modc_newsnapshot() temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 128.0f, 0.985f); } } + else if(item.type == EVENT_SPAWN) + { + ev_explosion *ev = (ev_explosion *)data; + vec2 p(ev->x, ev->y); + + // center explosion + vec2 v = normalize(vec2(frandom()-0.5f, -frandom()))*(32.0f+frandom()*32.0f); + temp_system.new_particle(p, v, 1.2f, 64.0f, 0, 0.95f); + v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f); + temp_system.new_particle(p, v, 1.2f, 32.0f, 0, 0.95f); + v = normalize(vec2(frandom()-0.5f, -frandom()))*(128.0f+frandom()*128.0f); + temp_system.new_particle(p, v, 1.2f, 16.0f, 0, 0.95f); + + for(int i = 0; i < 8; i++) + { + vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(64.0f+frandom()*64.0f); + temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 0, 0.985f); + } + + for(int i = 0; i < 8; i++) + { + vec2 v = normalize(vec2(frandom()-0.5f, frandom()-0.5f))*(128.0f+frandom()*256.0f); + temp_system.new_particle(p, v, 0.5f+0.5f*frandom(), 16.0f, 128.0f, 0.985f); + } + } else if(item.type == EVENT_SOUND) { ev_sound *ev = (ev_sound *)data; @@ -715,9 +740,14 @@ static void render_player(obj_player *prev, obj_player *player) if (player->weapon == WEAPON_HAMMER) { - float a = clamp((client_tick()-player->attacktick+client_intratick())/7.5f, 0.0f, 1.0f); + float a = clamp((client_tick()-player->attacktick+client_intratick())/10.0f, 0.0f, 1.0f); anim_eval_add(&state, &data->animations[ANIM_HAMMER_SWING], a, 1.0f); } + if (player->weapon == WEAPON_NINJA) + { + float a = clamp((client_tick()-player->attacktick+client_intratick())/40.0f, 0.0f, 1.0f); + anim_eval_add(&state, &data->animations[ANIM_NINJA_SWING], a, 1.0f); + } // draw hook @@ -763,13 +793,39 @@ static void render_player(obj_player *prev, obj_player *player) vec2 dir = direction; float recoil = 0.0f; + vec2 p; if (player->weapon == WEAPON_HAMMER) { + // Static position for hammer + p = position; + p.y += data->weapons[iw].offsety; // if attack is under way, bash stuffs if(direction.x < 0) + { gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2); + p.x -= data->weapons[iw].offsetx; + } else + { gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2); + } + draw_sprite(p.x, p.y, data->weapons[iw].visual_size); + } + else if (player->weapon == WEAPON_NINJA) + { + p = position; + p.y += data->weapons[iw].offsety; + + if(direction.x < 0) + { + gfx_quads_setrotation(-pi/2-state.attach.angle*pi*2); + p.x -= data->weapons[iw].offsetx; + } + else + { + gfx_quads_setrotation(-pi/2+state.attach.angle*pi*2); + } + draw_sprite(p.x, p.y, data->weapons[iw].visual_size); } else { @@ -778,12 +834,44 @@ static void render_player(obj_player *prev, obj_player *player) float a = (client_tick()-player->attacktick+client_intratick())/5.0f; if(a < 1) recoil = sinf(a*pi); + p = position + dir * data->weapons[iw].offsetx - dir*recoil*10.0f; + p.y += data->weapons[iw].offsety; + draw_sprite(p.x, p.y, data->weapons[iw].visual_size); } - - vec2 p = position + dir*20.0f - dir*recoil*10.0f; - draw_sprite(p.x, p.y, data->weapons[iw].visual_size); - // TODO: draw muzzleflare + if (player->weapon == WEAPON_TYPE_GUN || player->weapon == WEAPON_TYPE_SHOTGUN) + { + // check if we're firing stuff + if (true)///prev->attackticks) + { + float alpha = 0.0f; + int phase1tick = (client_tick() - player->attacktick); + if (phase1tick < (data->weapons[iw].muzzleduration + 3)) + { + float intratick = client_intratick(); + float t = ((((float)phase1tick) + intratick)/(float)data->weapons[iw].muzzleduration); + alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t))); + } + + int itex = rand() % data->weapons[iw].nummuzzlesprites; + if (alpha > 0.0f && data->weapons[iw].sprite_muzzle[itex].psprite) + { + float offsety = -data->weapons[iw].muzzleoffsety; + select_sprite(data->weapons[iw].sprite_muzzle[itex].psprite, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); + if(direction.x < 0) + offsety = -offsety; + + vec2 diry(-dir.y,dir.x); + p += dir * data->weapons[iw].muzzleoffsetx + diry * offsety; + + draw_sprite(p.x, p.y, data->weapons[iw].visual_size); + /*gfx_quads_setcolor(1.0f,1.0f,1.0f,alpha); + vec2 diry(-dir.y,dir.x); + p += dir * muzzleparams[player->weapon].offsetx + diry * offsety; + gfx_quads_draw(p.x,p.y,muzzleparams[player->weapon].sizex, muzzleparams[player->weapon].sizey);*/ + } + } + } gfx_quads_end(); } diff --git a/src/game/game.h b/src/game/game.h index 5f69ef9e..64dcc685 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -18,6 +18,10 @@ inline float get_angle(baselib::vec2 dir) return a; } +#define LERP(a,b,t) (a + (b-a) * t) +#define min(a, b) ( a > b ? b : a) +#define max(a, b) ( a > b ? a : b) + inline bool col_check_point(float x, float y) { return col_check_point((int)x, (int)y) != 0; } inline bool col_check_point(baselib::vec2 p) { return col_check_point(p.x, p.y); } @@ -34,6 +38,7 @@ enum EVENT_DAMAGEINDICATION, EVENT_SOUND, EVENT_SMOKE, + EVENT_SPAWN, }; enum @@ -75,6 +80,11 @@ struct ev_explosion int x, y; }; +struct ev_spawn +{ + int x, y; +}; + struct ev_sound { int x, y; @@ -152,9 +162,6 @@ enum POWERUP_TYPE_TIMEFIELD = 4, POWERUP_TYPE_NUMPOWERUPS, - PLAYER_MAXHEALTH = 10, - PLAYER_MAXARMOR = 10, - MODIFIER_TYPE_NINJA = 0, MODIFIER_TYPE_TIMEFIELD = 1, MODIFIER_NUMMODIFIERS, diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp index 12685fe8..795e9941 100644 --- a/src/game/server/game_server.cpp +++ b/src/game/server/game_server.cpp @@ -5,6 +5,8 @@ #include "data.h" #include "game_server.h" +data_container *data = 0x0; + using namespace baselib; // --------- DEBUG STUFF --------- @@ -28,6 +30,7 @@ class player* get_player(int index); void create_damageind(vec2 p, vec2 dir, int amount); void create_explosion(vec2 p, int owner, int weapon, bool bnodamage); void create_smoke(vec2 p); +void create_spawn(vec2 p); void create_sound(vec2 pos, int sound, int loopflags = 0); class player *intersect_player(vec2 pos0, vec2 pos1, vec2 &new_pos, class entity *notthis = 0); @@ -339,6 +342,7 @@ game_world world; gameobject::gameobject() : entity(OBJTYPE_GAME) { + gametype = GAMETYPE_DM; game_over_tick = -1; sudden_death = 0; round_start_tick = server_tick(); @@ -577,6 +581,8 @@ void player::init() name[3] = 'b'; name[4] = 0; client_id = -1; + extrapowerflags = 0; + ninjaactivationtick = 0; reset(); } @@ -597,7 +603,7 @@ void player::destroy() { } void player::respawn() { - health = PLAYER_MAXHEALTH; + health = data->playerinfo[gameobj.gametype].maxhealth; armor = 0; jumped = 0; dead = false; @@ -624,7 +630,7 @@ void player::respawn() weapons[WEAPON_HAMMER].got = true; weapons[WEAPON_HAMMER].ammo = -1; weapons[WEAPON_GUN].got = true; - weapons[WEAPON_GUN].ammo = 10; + weapons[WEAPON_GUN].ammo = data->weapons[active_weapon].maxammo; // TEMP DEBUG weapons[WEAPON_ROCKET_BACKPACK].got = true; @@ -632,8 +638,15 @@ void player::respawn() active_weapon = WEAPON_GUN; reload_timer = 0; + + // TEMP TEMP TEMP + /*ninjaactivationtick = server_tick(); + weapons[WEAPON_NINJA].got = 1; + active_weapon = WEAPON_NINJA;*/ + // Create sound and spawn effects create_sound(pos, SOUND_PLAYER_SPAWN); + create_spawn(pos); } bool player::is_grounded() @@ -667,20 +680,111 @@ void player::release_hooks() } } -void player::handle_weapons() +int player::handle_ninja() +{ + if ((server_tick() - ninjaactivationtick) > (data->weapons[WEAPON_NINJA].duration * server_tickspeed() / 1000)) + { + // time's up, return + active_weapon = WEAPON_GUN; + return 0; + } + + // Check if it should activate + if ((input.fire && !(previnput.fire)) && (server_tick() > currentcooldown)) + { + // ok then, activate ninja + attack_tick = server_tick(); + activationdir = direction; + currentmovetime = data->weapons[WEAPON_NINJA].movetime * server_tickspeed() / 1000; + currentcooldown = data->weapons[WEAPON_NINJA].firedelay * server_tickspeed() / 1000 + server_tick(); + // reset hit objects + numobjectshit = 0; + + create_sound(pos, SOUND_NINJA_FIRE); + } + + currentmovetime--; + + if (currentmovetime == 0) + { + // reset player velocity + vel *= 0.2f; + //return MODIFIER_RETURNFLAGS_OVERRIDEWEAPON; + } + + if (currentmovetime > 0) + { + // Set player velocity + vel = activationdir * data->weapons[WEAPON_NINJA].velocity; + vec2 oldpos = pos; + move_box(&defered_pos, &vel, vec2(phys_size, phys_size), 0.0f); + // reset velocity so the client doesn't predict stuff + vel = vec2(0.0f,0.0f); + if ((currentmovetime % 2) == 0) + { + create_smoke(pos); + } + + // check if we hit anything along the way + { + int type = OBJTYPE_PLAYER; + entity *ents[64]; + vec2 dir = pos - oldpos; + float radius = length(dir * 0.5f); + vec2 center = oldpos + dir * 0.5f; + int num = world.find_entities(center, radius, ents, 64, &type, 1); + + for (int i = 0; i < num; i++) + { + // Check if entity is a player + if (ents[i] == this) + continue; + // make sure we haven't hit this object before + bool balreadyhit = false; + for (int j = 0; j < numobjectshit; j++) + { + if (hitobjects[j] == ents[i]) + balreadyhit = true; + } + if (balreadyhit) + continue; + + // check so we are sufficiently close + if (distance(ents[i]->pos, pos) > (phys_size * 2.0f)) + continue; + + // hit a player, give him damage and stuffs... + create_sound(ents[i]->pos, SOUND_NINJA_HIT); + // set his velocity to fast upward (for now) + hitobjects[numobjectshit++] = ents[i]; + ents[i]->take_damage(vec2(0,10.0f), data->weapons[WEAPON_NINJA].meleedamage, client_id,-1); + } + } + return MODIFIER_RETURNFLAGS_OVERRIDEVELOCITY | MODIFIER_RETURNFLAGS_OVERRIDEPOSITION | MODIFIER_RETURNFLAGS_OVERRIDEGRAVITY; + } + return 0; +} + +int player::handle_weapons() { // check reload timer if(reload_timer) { reload_timer--; - return; + return 0; + } + if (active_weapon == WEAPON_NINJA) + { + // don't update other weapons while ninja is active + return handle_ninja(); } // switch weapon if wanted - if(input.activeweapon >= 0 && input.activeweapon < NUM_WEAPONS && weapons[input.activeweapon].got) + if(input.activeweapon >= 0 && input.activeweapon < NUM_WEAPONS && weapons[input.activeweapon].got && + data->weapons[active_weapon].duration <= 0) active_weapon = input.activeweapon; - if(input.fire) + if(!previnput.fire && input.fire) { if(reload_timer == 0) { @@ -690,6 +794,8 @@ void player::handle_weapons() switch(active_weapon) { case WEAPON_HAMMER: + // reset objects hit + numobjectshit = 0; create_sound(pos, SOUND_HAMMER_FIRE); break; @@ -739,17 +845,89 @@ void player::handle_weapons() } weapons[active_weapon].ammo--; + attack_tick = server_tick(); + reload_timer = data->weapons[active_weapon].firedelay * server_tickspeed() / 1000; } else { // click!!! click // TODO: make sound here } - - attack_tick = server_tick(); - reload_timer = 10; // TODO: make this variable depending on weapon } } + // Update weapons + if (active_weapon == WEAPON_HAMMER && reload_timer > 0) + { + // Handle collisions + // only one that needs update (for now) + // do selection for the weapon and bash anything in it + // check if we hit anything along the way + int type = OBJTYPE_PLAYER; + entity *ents[64]; + float reach = 20.0f; + vec2 lookdir(direction.x > 0.0f ? 1.0f : -1.0f, 0.0f); + vec2 dir = lookdir * data->weapons[active_weapon].meleereach; + float radius = length(dir * 0.5f); + vec2 center = pos + dir * 0.5f; + int num = world.find_entities(center, radius, ents, 64, &type, 1); + + for (int i = 0; i < num; i++) + { + // Check if entity is a player + if (ents[i] == this) + continue; + // make sure we haven't hit this object before + bool balreadyhit = false; + for (int j = 0; j < numobjectshit; j++) + { + if (hitobjects[j] == ents[i]) + balreadyhit = true; + } + if (balreadyhit) + continue; + + // check so we are sufficiently close + if (distance(ents[i]->pos, pos) > (phys_size * 2.0f)) + continue; + + // hit a player, give him damage and stuffs... + // create sound for bash + //create_sound(ents[i]->pos, sound_impact); + + // set his velocity to fast upward (for now) + create_smoke(ents[i]->pos); + hitobjects[numobjectshit++] = ents[i]; + ents[i]->take_damage(vec2(0,10.0f), data->weapons[active_weapon].meleedamage, client_id, active_weapon); + player* target = (player*)ents[i]; + vec2 dir; + if (length(target->pos - pos) > 0.0f) + dir = normalize(target->pos - pos); + else + dir = vec2(0,-1); + target->vel += dir * 10.0f + vec2(0,-10.0f); + } + } + if (data->weapons[active_weapon].ammoregentime) + { + // If equipped and not active, regen ammo? + if (reload_timer <= 0) + { + if (weapons[active_weapon].ammoregenstart < 0) + weapons[active_weapon].ammoregenstart = server_tick(); + + if ((server_tick() - weapons[active_weapon].ammoregenstart) >= data->weapons[active_weapon].ammoregentime * server_tickspeed() / 1000) + { + // Add some ammo + weapons[active_weapon].ammo = min(weapons[active_weapon].ammo + 1, data->weapons[active_weapon].maxammo); + weapons[active_weapon].ammoregenstart = -1; + } + } + else + { + weapons[active_weapon].ammoregenstart = -1; + } + } + return 0; } void player::tick() @@ -851,7 +1029,7 @@ void player::tick() if(hook_state == HOOK_GRABBED) { - if(hooked_player) + /*if(hooked_player) hook_pos = hooked_player->pos; float d = distance(pos, hook_pos); @@ -861,7 +1039,25 @@ void player::tick() float accel = hook_drag_accel * (d/hook_length); vel.x = saturated_add(-hook_drag_speed, hook_drag_speed, vel.x, -accel*dir.x*0.75f); vel.y = saturated_add(-hook_drag_speed, hook_drag_speed, vel.y, -accel*dir.y); - } + }*/ + // Old version feels much better (to me atleast) + vec2 hookvel = normalize(hook_pos-pos)*hook_drag_accel; + // the hook as more power to drag you up then down. + // this makes it easier to get on top of an platform + if(hookvel.y > 0) + hookvel.y *= 0.3f; + + // the hook will boost it's power if the player wants to move + // in that direction. otherwise it will dampen everything abit + if((hookvel.x < 0 && input.left) || (hookvel.x > 0 && input.right)) + hookvel.x *= 0.95f; + else + hookvel.x *= 0.75f; + vec2 new_vel = vel+hookvel; + + // check if we are under the legal limit for the hook + if(length(new_vel) < hook_drag_speed || length(new_vel) < length(vel)) + vel = new_vel; // no problem. apply } // fix influence of other players, collision + hook @@ -897,14 +1093,20 @@ void player::tick() } // handle weapons - handle_weapons(); + int retflags = handle_weapons(); + if (!(retflags & (MODIFIER_RETURNFLAGS_OVERRIDEVELOCITY | MODIFIER_RETURNFLAGS_OVERRIDEPOSITION))) + { + // add gravity + if (!(retflags & MODIFIER_RETURNFLAGS_OVERRIDEGRAVITY)) + vel.y += gravity; - // add gravity - vel.y += gravity; + // do the move + defered_pos = pos; + move_box(&defered_pos, &vel, vec2(phys_size, phys_size), 0); + } - // do the move - defered_pos = pos; - move_box(&defered_pos, &vel, vec2(phys_size, phys_size), 0); + // Previnput + previnput = input; return; } @@ -1085,16 +1287,16 @@ void powerup::tick() switch (type) { case POWERUP_TYPE_HEALTH: - if(pplayer->health < PLAYER_MAXHEALTH) + if(pplayer->health < data->playerinfo[gameobj.gametype].maxhealth) { - pplayer->health = min((int)PLAYER_MAXHEALTH, pplayer->health + 1); + pplayer->health = min((int)data->playerinfo[gameobj.gametype].maxhealth, pplayer->health + 1); respawntime = 20; } break; case POWERUP_TYPE_ARMOR: - if(pplayer->armor < PLAYER_MAXARMOR) + if(pplayer->armor < data->playerinfo[gameobj.gametype].maxarmor) { - pplayer->armor = min((int)PLAYER_MAXARMOR, pplayer->armor + 1); + pplayer->armor = min((int)data->playerinfo[gameobj.gametype].maxarmor, pplayer->armor + 1); respawntime = 20; } break; @@ -1110,6 +1312,15 @@ void powerup::tick() } } break; + case POWERUP_TYPE_NINJA: + { + // activate ninja on target player + pplayer->ninjaactivationtick = server_tick(); + pplayer->weapons[WEAPON_NINJA].got = true; + pplayer->active_weapon = WEAPON_NINJA; + respawntime = 20; + break; + } default: break; }; @@ -1191,6 +1402,14 @@ void create_smoke(vec2 p) ev->y = (int)p.y; } +void create_spawn(vec2 p) +{ + // create the event + ev_spawn *ev = (ev_spawn *)events.create(EVENT_SPAWN, sizeof(ev_spawn)); + ev->x = (int)p.x; + ev->y = (int)p.y; +} + void create_sound(vec2 pos, int sound, int loopingflags) { if (sound < 0) @@ -1265,7 +1484,7 @@ void mods_client_input(int client_id, void *input) { if(!world.paused) { - players[client_id].previnput = players[client_id].input; + //players[client_id].previnput = players[client_id].input; players[client_id].input = *(player_input*)input; } } @@ -1323,6 +1542,7 @@ void mods_message(int msg, int client_id) void mods_init() { + data = load_data_container("data/server.dat"); col_init(32); int start, num; diff --git a/src/game/server/game_server.h b/src/game/server/game_server.h index ec3d597a..46b451e1 100644 --- a/src/game/server/game_server.h +++ b/src/game/server/game_server.h @@ -112,6 +112,7 @@ class gameobject : public entity int sudden_death; public: + int gametype; gameobject(); virtual void post_reset(); virtual void tick(); @@ -190,11 +191,21 @@ class player : public entity public: static const int phys_size = 28; + enum // what are these? + { + MODIFIER_RETURNFLAGS_OVERRIDEVELOCITY = 1 << 0, + MODIFIER_RETURNFLAGS_OVERRIDEPOSITION = 1 << 1, + MODIFIER_RETURNFLAGS_OVERRIDEGRAVITY = 1 << 2, + }; + // weapon info + entity* hitobjects[10]; + int numobjectshit; struct weaponstat { - bool got; + int ammoregenstart; int ammo; + bool got; } weapons[NUM_WEAPONS]; int active_weapon; int reload_timer; @@ -219,6 +230,14 @@ public: int health; int armor; + // ninja + baselib::vec2 activationdir; + int ninjaactivationtick; + int extrapowerflags; + int currentcooldown; + int currentactivation; + int currentmovetime; + int score; bool dead; @@ -251,7 +270,8 @@ public: void release_hooked(); void release_hooks(); - void handle_weapons(); + int handle_weapons(); + int handle_ninja(); virtual void tick(); virtual void tick_defered(); |