mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
added laser weapon
This commit is contained in:
parent
1fe3202f0b
commit
5f32f5b36f
BIN
data/game.png
BIN
data/game.png
Binary file not shown.
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 129 KiB |
|
@ -9,12 +9,9 @@ struct weapon {
|
|||
int meleereach = meleereach@1
|
||||
int ammoregentime = ammoregentime@1
|
||||
int maxammo = maxammo@1
|
||||
int costammo = costammo@1
|
||||
int duration = duration@1
|
||||
int movetime = movetime@1
|
||||
int velocity = velocity@1
|
||||
float chargetime = chargetime@1
|
||||
float overchargetime = overchargetime@1
|
||||
}
|
||||
|
||||
struct powerupinf {
|
||||
|
|
|
@ -11,13 +11,13 @@ sounds {
|
|||
"data/audio/wp_shotty_fire-03.wv"
|
||||
}
|
||||
|
||||
sniper_fire {
|
||||
laser_fire {
|
||||
"data/audio/wp_shotty_fire-01.wv"
|
||||
"data/audio/wp_shotty_fire-02.wv"
|
||||
"data/audio/wp_shotty_fire-03.wv"
|
||||
}
|
||||
|
||||
rocket_fire {
|
||||
grenade_fire {
|
||||
"data/audio/wp_flump_launch-01.wv"
|
||||
"data/audio/wp_flump_launch-02.wv"
|
||||
"data/audio/wp_flump_launch-03.wv"
|
||||
|
@ -41,7 +41,7 @@ sounds {
|
|||
"data/audio/wp_ninja_attack-03.wv"
|
||||
}
|
||||
|
||||
rocket_explode {
|
||||
grenade_explode {
|
||||
"data/audio/wp_flump_explo-01.wv"
|
||||
"data/audio/wp_flump_explo-02.wv"
|
||||
"data/audio/wp_flump_explo-03.wv"
|
||||
|
@ -153,7 +153,7 @@ sounds {
|
|||
"data/audio/sfx_pickup_arm-04.wv"
|
||||
}
|
||||
|
||||
pickup_rocket {
|
||||
pickup_grenade {
|
||||
"data/audio/sfx_pickup_launcher.wv"
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,6 @@ weapons {
|
|||
muzzleoffsetx 0.0
|
||||
muzzleoffsety 0.0
|
||||
maxammo 10
|
||||
costammo 0
|
||||
recoil 10
|
||||
firedelay 150
|
||||
muzzleduration 0
|
||||
|
@ -292,8 +291,6 @@ weapons {
|
|||
duration -1
|
||||
movetime 0
|
||||
velocity 0
|
||||
chargetime 0.0
|
||||
overchargetime 0.0
|
||||
}
|
||||
|
||||
gun {
|
||||
|
@ -310,7 +307,6 @@ weapons {
|
|||
muzzleoffsetx 50.0
|
||||
muzzleoffsety 6.0
|
||||
maxammo 10
|
||||
costammo 1
|
||||
recoil 10
|
||||
firedelay 100
|
||||
muzzleduration 5
|
||||
|
@ -323,8 +319,6 @@ weapons {
|
|||
duration -1
|
||||
movetime 0
|
||||
velocity 0
|
||||
chargetime 0.0
|
||||
overchargetime 0.0
|
||||
}
|
||||
|
||||
shotgun {
|
||||
|
@ -341,7 +335,6 @@ weapons {
|
|||
muzzleoffsetx 70.0
|
||||
muzzleoffsety 6.0
|
||||
maxammo 10
|
||||
costammo 1
|
||||
recoil 10
|
||||
firedelay 500
|
||||
muzzleduration 5
|
||||
|
@ -354,14 +347,12 @@ weapons {
|
|||
duration -1
|
||||
movetime 0
|
||||
velocity 0
|
||||
chargetime 0.0
|
||||
overchargetime 0.0
|
||||
}
|
||||
|
||||
rocket {
|
||||
sprite_body sprites.game.weapon_rocket_body
|
||||
sprite_cursor sprites.game.weapon_rocket_cursor
|
||||
sprite_proj sprites.game.weapon_rocket_proj
|
||||
grenade {
|
||||
sprite_body sprites.game.weapon_grenade_body
|
||||
sprite_cursor sprites.game.weapon_grenade_cursor
|
||||
sprite_proj sprites.game.weapon_grenade_proj
|
||||
sprite_muzzles {
|
||||
}
|
||||
|
||||
|
@ -369,7 +360,6 @@ weapons {
|
|||
muzzleoffsetx 0.0
|
||||
muzzleoffsety 0.0
|
||||
maxammo 10
|
||||
costammo 1
|
||||
recoil 10
|
||||
firedelay 600
|
||||
muzzleduration 0
|
||||
|
@ -382,29 +372,23 @@ weapons {
|
|||
duration -1
|
||||
movetime 0
|
||||
velocity 0
|
||||
chargetime 0.0
|
||||
overchargetime 0.0
|
||||
}
|
||||
|
||||
sniper {
|
||||
sprite_body sprites.game.weapon_rocket_body
|
||||
sprite_cursor sprites.game.weapon_rocket_cursor
|
||||
sprite_proj sprites.game.weapon_rocket_proj
|
||||
laser {
|
||||
sprite_body sprites.game.weapon_laser_body
|
||||
sprite_cursor sprites.game.weapon_laser_cursor
|
||||
sprite_proj sprites.game.weapon_shotgun_proj
|
||||
sprite_muzzles {
|
||||
sprites.game.weapon_shotgun_muzzle1
|
||||
sprites.game.weapon_shotgun_muzzle2
|
||||
sprites.game.weapon_shotgun_muzzle3
|
||||
}
|
||||
|
||||
nummuzzlesprites 3
|
||||
muzzleoffsetx 0.0
|
||||
muzzleoffsety 0.0
|
||||
maxammo 10
|
||||
costammo 1
|
||||
recoil 10
|
||||
firedelay 600
|
||||
muzzleduration 0
|
||||
visual_size 96
|
||||
visual_size 128
|
||||
offsetx 24.0
|
||||
offsety -2.0
|
||||
meleedamage 0
|
||||
|
@ -413,8 +397,6 @@ weapons {
|
|||
duration -1
|
||||
movetime 0
|
||||
velocity 0
|
||||
chargetime 0.5
|
||||
overchargetime 10.0
|
||||
}
|
||||
|
||||
ninja {
|
||||
|
@ -431,7 +413,6 @@ weapons {
|
|||
muzzleoffsetx 40.0
|
||||
muzzleoffsety -4.0
|
||||
maxammo 0
|
||||
costammo 0
|
||||
recoil 0
|
||||
firedelay 800
|
||||
muzzleduration 0
|
||||
|
@ -444,8 +425,6 @@ weapons {
|
|||
duration 15000
|
||||
movetime 200
|
||||
velocity 50
|
||||
chargetime 0.0
|
||||
overchargetime 0.0
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -500,9 +479,9 @@ sprites {
|
|||
weapon_shotgun_muzzle2 16 6 3 2
|
||||
weapon_shotgun_muzzle3 20 6 3 2
|
||||
|
||||
weapon_rocket_body 2 8 7 2
|
||||
weapon_rocket_cursor 0 8 2 2
|
||||
weapon_rocket_proj 10 8 2 2
|
||||
weapon_grenade_body 2 8 7 2
|
||||
weapon_grenade_cursor 0 8 2 2
|
||||
weapon_grenade_proj 10 8 2 2
|
||||
|
||||
weapon_hammer_body 2 1 4 3
|
||||
weapon_hammer_cursor 0 0 2 2
|
||||
|
@ -512,6 +491,9 @@ sprites {
|
|||
weapon_ninja_cursor 0 10 2 2
|
||||
weapon_ninja_proj 0 0 0 0
|
||||
|
||||
weapon_laser_body 2 12 9 3
|
||||
weapon_laser_cursor 0 12 2 2
|
||||
|
||||
hook_chain 2 0 1 1
|
||||
hook_head 3 0 2 1
|
||||
|
||||
|
|
|
@ -947,7 +947,7 @@ static void client_update()
|
|||
int new_pred_tick = prev_pred_tick+1;
|
||||
static float last_predintra = 0;
|
||||
|
||||
intratick = (now - prevtick_start) / (float)(curtick_start-prevtick_start);
|
||||
intratick = (now - curtick_start) / (float)(curtick_start-prevtick_start);
|
||||
ticktime = (now - curtick_start) / (freq/(float)SERVER_TICK_SPEED);
|
||||
|
||||
graph_add(&intra_graph, intratick*0.25f);
|
||||
|
|
|
@ -1117,7 +1117,7 @@ void render_game()
|
|||
for (int i = 0; i < local_character->weaponstage; i++)
|
||||
gfx_quads_drawTL(x+local_character->ammocount * 12 -i*12, y+22, 11, 11);
|
||||
select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_proj);
|
||||
for (int i = 0; i < local_character->ammocount; i++)
|
||||
for (int i = 0; i < min(local_character->ammocount, 10); i++)
|
||||
gfx_quads_drawTL(x+i*12,y+24,10,10);
|
||||
|
||||
gfx_quads_end();
|
||||
|
|
|
@ -341,6 +341,10 @@ static void render_items()
|
|||
if(prev)
|
||||
render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
|
||||
}
|
||||
else if(item.type == OBJTYPE_LASER)
|
||||
{
|
||||
render_laser((const obj_laser *)data);
|
||||
}
|
||||
else if(item.type == OBJTYPE_FLAG)
|
||||
{
|
||||
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
||||
|
|
|
@ -57,6 +57,7 @@ void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 di
|
|||
void render_flag(const struct obj_flag *prev, const struct obj_flag *current);
|
||||
void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current);
|
||||
void render_projectile(const struct obj_projectile *current, int itemid);
|
||||
void render_laser(const struct obj_laser *current);
|
||||
void render_player(
|
||||
const struct obj_player_character *prev_char, const struct obj_player_character *player_char,
|
||||
const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
|
||||
|
|
|
@ -26,7 +26,7 @@ void render_projectile(const obj_projectile *current, int itemid)
|
|||
|
||||
// get positions
|
||||
float gravity = -400;
|
||||
if(current->type != WEAPON_ROCKET)
|
||||
if(current->type != WEAPON_GRENADE)
|
||||
gravity = -100;
|
||||
|
||||
float ct = (client_tick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime()*1/(float)SERVER_TICK_SPEED;
|
||||
|
@ -41,7 +41,7 @@ void render_projectile(const obj_projectile *current, int itemid)
|
|||
|
||||
|
||||
// add particle for this projectile
|
||||
if(current->type == WEAPON_ROCKET)
|
||||
if(current->type == WEAPON_GRENADE)
|
||||
{
|
||||
effect_smoketrail(pos, vel*-1);
|
||||
flow_add(pos, vel*1000*client_frametime(), 10.0f);
|
||||
|
@ -136,6 +136,72 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
|
|||
}
|
||||
|
||||
|
||||
void render_laser(const struct obj_laser *current)
|
||||
{
|
||||
|
||||
vec2 pos = vec2(current->x, current->y);
|
||||
vec2 from = vec2(current->from_x, current->from_y);
|
||||
vec2 dir = normalize(pos-from);
|
||||
|
||||
|
||||
|
||||
float ticks = client_tick() + client_intratick() - current->eval_tick;
|
||||
float ms = (ticks/50.0f) * 1000.0f;
|
||||
float a = ms / tuning.laser_bounce_delay;
|
||||
a = clamp(a, 0.0f, 1.0f);
|
||||
float ia = 1-a;
|
||||
|
||||
|
||||
|
||||
vec2 out(dir.y, -dir.x);
|
||||
|
||||
out = out * (4.0f*ia);
|
||||
|
||||
gfx_blend_normal();
|
||||
gfx_texture_set(-1);
|
||||
gfx_quads_begin();
|
||||
|
||||
vec4 start_color(0.25f,0.25f,0.5f,1.0f);
|
||||
vec4 end_color(0.85f,0.85f,1.0f,1.0f);
|
||||
start_color = end_color;
|
||||
|
||||
gfx_setcolorvertex(0, start_color.r, start_color.g, start_color.b, start_color.a);
|
||||
gfx_setcolorvertex(1, start_color.r, start_color.g, start_color.b, start_color.a);
|
||||
gfx_setcolorvertex(2, end_color.r, end_color.g, end_color.b, end_color.a);
|
||||
gfx_setcolorvertex(3, end_color.r, end_color.g, end_color.b, end_color.a);
|
||||
|
||||
from = mix(from, pos, a);
|
||||
|
||||
gfx_quads_draw_freeform(
|
||||
from.x-out.x, from.y-out.y,
|
||||
from.x+out.x, from.y+out.y,
|
||||
pos.x-out.x, pos.y-out.y,
|
||||
pos.x+out.x, pos.y+out.y
|
||||
);
|
||||
|
||||
gfx_quads_end();
|
||||
|
||||
// render head
|
||||
{
|
||||
gfx_blend_normal();
|
||||
gfx_texture_set(data->images[IMAGE_PARTICLES].id);
|
||||
gfx_quads_begin();
|
||||
|
||||
gfx_setcolor(end_color.r, end_color.g, end_color.b, end_color.a);
|
||||
|
||||
int sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
|
||||
select_sprite(sprites[client_tick()%3]);
|
||||
gfx_quads_setrotation(client_tick());
|
||||
gfx_quads_draw(pos.x, pos.y, 32,32);
|
||||
gfx_quads_end();
|
||||
}
|
||||
|
||||
gfx_blend_normal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset)
|
||||
{
|
||||
|
@ -416,7 +482,7 @@ void render_player(
|
|||
{
|
||||
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(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
|
||||
case WEAPON_ROCKET: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
|
||||
case WEAPON_GRENADE: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ void editor_load_old(DATAFILE *df)
|
|||
else if(t == MAPRES_ITEM)
|
||||
{
|
||||
if(e->data[0] == ITEM_WEAPON_SHOTGUN) id = ENTITY_WEAPON_SHOTGUN;
|
||||
else if(e->data[0] == ITEM_WEAPON_ROCKET) id = ENTITY_WEAPON_ROCKET;
|
||||
else if(e->data[0] == ITEM_WEAPON_ROCKET) id = ENTITY_WEAPON_GRENADE;
|
||||
else if(e->data[0] == ITEM_NINJA) id = ENTITY_POWERUP_NINJA;
|
||||
else if(e->data[0] == ITEM_ARMOR) id = ENTITY_ARMOR_1;
|
||||
else if(e->data[0] == ITEM_HEALTH) id = ENTITY_HEALTH_1;
|
||||
|
|
|
@ -43,8 +43,6 @@ bool tuning_params::get(const char *name, float *value)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: OPT: rewrite this smarter!
|
||||
void move_point(vec2 *inout_pos, vec2 *inout_vel, float elasticity, int *bounces)
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ enum
|
|||
ENTITY_ARMOR_1,
|
||||
ENTITY_HEALTH_1,
|
||||
ENTITY_WEAPON_SHOTGUN,
|
||||
ENTITY_WEAPON_ROCKET,
|
||||
ENTITY_WEAPON_GRENADE,
|
||||
ENTITY_POWERUP_NINJA,
|
||||
NUM_ENTITIES,
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ enum
|
|||
OBJTYPE_PLAYER_INFO,
|
||||
OBJTYPE_PLAYER_CHARACTER, // use this if you are searching for the player entity
|
||||
OBJTYPE_PROJECTILE,
|
||||
OBJTYPE_LASER,
|
||||
OBJTYPE_POWERUP,
|
||||
OBJTYPE_FLAG,
|
||||
EVENT_EXPLOSION,
|
||||
|
@ -136,12 +137,19 @@ struct obj_game
|
|||
|
||||
struct obj_projectile
|
||||
{
|
||||
int type;
|
||||
int x, y;
|
||||
int vx, vy; // should be an angle instead
|
||||
int type;
|
||||
int start_tick;
|
||||
};
|
||||
|
||||
struct obj_laser
|
||||
{
|
||||
int x, y;
|
||||
int from_x, from_y;
|
||||
int eval_tick;
|
||||
};
|
||||
|
||||
struct obj_powerup
|
||||
{
|
||||
int x, y;
|
||||
|
|
|
@ -15,3 +15,15 @@ MACRO_TUNING_PARAM(gravity, 0.5f)
|
|||
MACRO_TUNING_PARAM(terminal_velocity, 1000.0f / ticks_per_second)
|
||||
|
||||
/* weapon tuning */
|
||||
MACRO_TUNING_PARAM(gun_speed, 30.0f)
|
||||
|
||||
MACRO_TUNING_PARAM(shotgun_speed_center, 40.0f)
|
||||
MACRO_TUNING_PARAM(shotgun_speed_wide, 30.0f)
|
||||
|
||||
MACRO_TUNING_PARAM(grenade_speed, 15.0f)
|
||||
|
||||
MACRO_TUNING_PARAM(laser_reach, 800.0f)
|
||||
MACRO_TUNING_PARAM(laser_bounce_delay, 150)
|
||||
MACRO_TUNING_PARAM(laser_bounce_num, 2)
|
||||
MACRO_TUNING_PARAM(laser_bounce_cost, 32)
|
||||
MACRO_TUNING_PARAM(laser_damage, 8)
|
||||
|
|
|
@ -213,6 +213,27 @@ public:
|
|||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
class laser : public entity
|
||||
{
|
||||
vec2 from;
|
||||
vec2 dir;
|
||||
float energy;
|
||||
int bounces;
|
||||
int eval_tick;
|
||||
player *owner;
|
||||
|
||||
bool hit_player(vec2 from, vec2 to);
|
||||
void do_bounce();
|
||||
|
||||
public:
|
||||
|
||||
laser(vec2 pos, vec2 direction, float start_energy, player *owner);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
// player entity
|
||||
class player : public entity
|
||||
{
|
||||
|
|
|
@ -60,10 +60,10 @@ bool gameobject::on_entity(int index, vec2 pos)
|
|||
type = POWERUP_WEAPON;
|
||||
subtype = WEAPON_SHOTGUN;
|
||||
}
|
||||
else if(index == ENTITY_WEAPON_ROCKET)
|
||||
else if(index == ENTITY_WEAPON_GRENADE)
|
||||
{
|
||||
type = POWERUP_WEAPON;
|
||||
subtype = WEAPON_ROCKET;
|
||||
subtype = WEAPON_GRENADE;
|
||||
}
|
||||
else if(index == ENTITY_POWERUP_NINJA)
|
||||
{
|
||||
|
|
|
@ -406,7 +406,7 @@ void projectile::reset()
|
|||
void projectile::tick()
|
||||
{
|
||||
float gravity = -400;
|
||||
if(type != WEAPON_ROCKET)
|
||||
if(type != WEAPON_GRENADE)
|
||||
gravity = -100;
|
||||
|
||||
float pt = (server_tick()-start_tick-1)/(float)server_tickspeed();
|
||||
|
@ -423,7 +423,7 @@ void projectile::tick()
|
|||
|
||||
if(targetplayer || collide || lifespan < 0)
|
||||
{
|
||||
if (lifespan >= 0 || weapon == WEAPON_ROCKET)
|
||||
if (lifespan >= 0 || weapon == WEAPON_GRENADE)
|
||||
create_sound(pos, sound_impact);
|
||||
|
||||
if (flags & PROJECTILE_FLAGS_EXPLODE)
|
||||
|
@ -454,6 +454,110 @@ void projectile::snap(int snapping_client)
|
|||
proj->type = type;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// laser
|
||||
//////////////////////////////////////////////////
|
||||
laser::laser(vec2 pos, vec2 direction, float start_energy, player *owner)
|
||||
: entity(OBJTYPE_LASER)
|
||||
{
|
||||
this->pos = pos;
|
||||
this->owner = owner;
|
||||
energy = start_energy;
|
||||
dir = direction;
|
||||
bounces = 0;
|
||||
do_bounce();
|
||||
|
||||
world->insert_entity(this);
|
||||
}
|
||||
|
||||
|
||||
bool laser::hit_player(vec2 from, vec2 to)
|
||||
{
|
||||
vec2 at;
|
||||
player *hit = intersect_player(pos, to, at, owner);
|
||||
if(!hit)
|
||||
return false;
|
||||
|
||||
this->from = from;
|
||||
pos = at;
|
||||
energy = -1;
|
||||
hit->take_damage(vec2(0,0), tuning.laser_damage, owner->client_id, WEAPON_LASER);
|
||||
return true;
|
||||
}
|
||||
|
||||
void laser::do_bounce()
|
||||
{
|
||||
eval_tick = server_tick();
|
||||
|
||||
if(energy < 0)
|
||||
{
|
||||
//dbg_msg("laser", "%d removed", server_tick());
|
||||
world->destroy_entity(this);
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 to = pos + dir*energy;
|
||||
|
||||
if(col_intersect_line(pos, to, &to))
|
||||
{
|
||||
if(!hit_player(pos, to))
|
||||
{
|
||||
// intersected
|
||||
from = pos;
|
||||
pos = to - dir*2;
|
||||
vec2 temp_pos = pos;
|
||||
vec2 temp_dir = dir*4.0f;
|
||||
|
||||
move_point(&temp_pos, &temp_dir, 1.0f, 0);
|
||||
dir = normalize(temp_dir);
|
||||
|
||||
energy -= distance(from, pos) + tuning.laser_bounce_cost;
|
||||
bounces++;
|
||||
|
||||
if(bounces > tuning.laser_bounce_num)
|
||||
energy = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!hit_player(pos, to))
|
||||
{
|
||||
from = pos;
|
||||
pos = to;
|
||||
energy = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//dbg_msg("laser", "%d done %f %f %f %f", server_tick(), from.x, from.y, pos.x, pos.y);
|
||||
}
|
||||
|
||||
void laser::reset()
|
||||
{
|
||||
world->destroy_entity(this);
|
||||
}
|
||||
|
||||
void laser::tick()
|
||||
{
|
||||
if(server_tick() > eval_tick+(server_tickspeed()*tuning.laser_bounce_delay)/1000.0f)
|
||||
do_bounce();
|
||||
|
||||
}
|
||||
|
||||
void laser::snap(int snapping_client)
|
||||
{
|
||||
if(distance(players[snapping_client].pos, pos) > 1000.0f)
|
||||
return;
|
||||
|
||||
obj_laser *obj = (obj_laser *)snap_new_item(OBJTYPE_LASER, id, sizeof(obj_laser));
|
||||
obj->x = (int)pos.x;
|
||||
obj->y = (int)pos.y;
|
||||
obj->from_x = (int)from.x;
|
||||
obj->from_y = (int)from.y;
|
||||
obj->eval_tick = eval_tick;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// player
|
||||
//////////////////////////////////////////////////
|
||||
|
@ -714,8 +818,9 @@ void player::try_respawn()
|
|||
weapons[WEAPON_GUN].got = true;
|
||||
weapons[WEAPON_GUN].ammo = data->weapons[WEAPON_GUN].maxammo;
|
||||
|
||||
//weapons[WEAPON_SNIPER].got = true;
|
||||
//weapons[WEAPON_SNIPER].ammo = data->weapons[WEAPON_SNIPER].maxammo;
|
||||
weapons[WEAPON_LASER].got = true;
|
||||
weapons[WEAPON_LASER].ammo = 100000; //data->weapons[WEAPON_LASER].maxammo;
|
||||
|
||||
active_weapon = WEAPON_GUN;
|
||||
last_weapon = WEAPON_HAMMER;
|
||||
wanted_weapon = WEAPON_GUN;
|
||||
|
@ -909,7 +1014,7 @@ int player::handle_weapons()
|
|||
if(reload_timer == 0)
|
||||
{
|
||||
bool fullauto = false;
|
||||
if(active_weapon == WEAPON_ROCKET || active_weapon == WEAPON_SHOTGUN)
|
||||
if(active_weapon == WEAPON_GRENADE || active_weapon == WEAPON_SHOTGUN)
|
||||
fullauto = true;
|
||||
|
||||
if(count_input(latest_previnput.fire, latest_input.fire).presses || ((fullauto && latest_input.fire&1) && weapons[active_weapon].ammo))
|
||||
|
@ -932,23 +1037,23 @@ int player::handle_weapons()
|
|||
new projectile(WEAPON_GUN,
|
||||
client_id,
|
||||
pos+vec2(0,0),
|
||||
direction*30.0f,
|
||||
direction*tuning.gun_speed,
|
||||
server_tickspeed(),
|
||||
this,
|
||||
1, 0, 0, -1, WEAPON_GUN);
|
||||
create_sound(pos, SOUND_GUN_FIRE);
|
||||
break;
|
||||
}
|
||||
case WEAPON_ROCKET:
|
||||
case WEAPON_GRENADE:
|
||||
{
|
||||
new projectile(WEAPON_ROCKET,
|
||||
new projectile(WEAPON_GRENADE,
|
||||
client_id,
|
||||
pos+vec2(0,0),
|
||||
direction*15.0f,
|
||||
direction*tuning.grenade_speed,
|
||||
100,
|
||||
this,
|
||||
1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_ROCKET_EXPLODE, WEAPON_ROCKET);
|
||||
create_sound(pos, SOUND_ROCKET_FIRE);
|
||||
1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
|
||||
create_sound(pos, SOUND_GRENADE_FIRE);
|
||||
break;
|
||||
}
|
||||
case WEAPON_SHOTGUN:
|
||||
|
@ -960,11 +1065,11 @@ int player::handle_weapons()
|
|||
float a = get_angle(direction);
|
||||
float v = 1.0f-fabs(i/(float)shotspread);
|
||||
a += spreading[i+2];
|
||||
float speed = mix((float)tuning.shotgun_speed_wide, (float)tuning.shotgun_speed_center, v);
|
||||
new projectile(WEAPON_SHOTGUN,
|
||||
client_id,
|
||||
pos+vec2(0,0),
|
||||
vec2(cosf(a), sinf(a))*(28.0f + 12.0f*v),
|
||||
//vec2(cosf(a), sinf(a))*20.0f,
|
||||
vec2(cosf(a), sinf(a))*speed,
|
||||
(int)(server_tickspeed()*0.25f),
|
||||
this,
|
||||
1, 0, 0, -1, WEAPON_SHOTGUN);
|
||||
|
@ -973,16 +1078,10 @@ int player::handle_weapons()
|
|||
break;
|
||||
}
|
||||
|
||||
case WEAPON_SNIPER:
|
||||
case WEAPON_LASER:
|
||||
{
|
||||
new projectile(WEAPON_SNIPER,
|
||||
client_id,
|
||||
pos+vec2(0,0),
|
||||
direction*300.0f,
|
||||
100,
|
||||
this,
|
||||
1, 0, 0, -1, WEAPON_SNIPER);
|
||||
create_sound(pos, SOUND_SNIPER_FIRE);
|
||||
new laser(pos, direction, tuning.laser_reach, this);
|
||||
create_sound(pos, SOUND_LASER_FIRE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1476,8 +1575,8 @@ void powerup::tick()
|
|||
respawntime = data->powerupinfo[type].respawntime;
|
||||
|
||||
// TODO: data compiler should take care of stuff like this
|
||||
if(subtype == WEAPON_ROCKET)
|
||||
create_sound(pos, SOUND_PICKUP_ROCKET);
|
||||
if(subtype == WEAPON_GRENADE)
|
||||
create_sound(pos, SOUND_PICKUP_GRENADE);
|
||||
else if(subtype == WEAPON_SHOTGUN)
|
||||
create_sound(pos, SOUND_PICKUP_SHOTGUN);
|
||||
|
||||
|
@ -1656,10 +1755,82 @@ void create_sound_global(int sound, int target)
|
|||
server_send_msg(target);
|
||||
}
|
||||
|
||||
float closest_point_on_line(vec2 line_point0, vec2 line_point1, vec2 target_point)
|
||||
{
|
||||
vec2 c = target_point - line_point0;
|
||||
vec2 v = (line_point1 - line_point0);
|
||||
v = normalize(v);
|
||||
float d = length(line_point0-line_point1);
|
||||
float t = dot(v, c);
|
||||
|
||||
if (t < 0) return 0;
|
||||
if (t > d) return 1;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// TODO: should be more general
|
||||
player *intersect_player(vec2 pos0, vec2 pos1, vec2& new_pos, entity *notthis)
|
||||
{
|
||||
// Find other players
|
||||
float closest_time = distance(pos0, pos1) * 100.0f;
|
||||
vec2 line_dir = normalize(pos1-pos0);
|
||||
player *closest = 0;
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(players[i].client_id < 0 || (entity *)&players[i] == notthis)
|
||||
continue;
|
||||
|
||||
if(!(players[i].flags&entity::FLAG_PHYSICS))
|
||||
continue;
|
||||
|
||||
float t = closest_point_on_line(pos0, pos1, players[i].pos);
|
||||
vec2 intersect_pos = pos0 + line_dir*t;
|
||||
float len = distance(players[i].pos, intersect_pos);
|
||||
if(len < player::phys_size)
|
||||
{
|
||||
if(t < closest_time)
|
||||
{
|
||||
new_pos = intersect_pos;
|
||||
closest_time = t;
|
||||
closest = &players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
|
||||
/*
|
||||
entity *ents[64];
|
||||
vec2 dir = pos1 - pos0;
|
||||
float radius = length(dir * 0.5f);
|
||||
vec2 center = pos0 + dir * 0.5f;
|
||||
const int types[] = {OBJTYPE_PLAYER_CHARACTER};
|
||||
int num = world->find_entities(center, radius, ents, 64, types, 1);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
// Check if entity is a player
|
||||
if (ents[i] != notthis)
|
||||
{
|
||||
new_pos = ents[i]->pos;
|
||||
return (player*)ents[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: should be more general
|
||||
|
||||
/*
|
||||
player* intersect_player(vec2 pos0, vec2 pos1, vec2& new_pos, entity* notthis)
|
||||
{
|
||||
// Find other players
|
||||
|
||||
|
||||
entity *ents[64];
|
||||
vec2 dir = pos1 - pos0;
|
||||
float radius = length(dir * 0.5f);
|
||||
|
@ -1678,6 +1849,7 @@ player* intersect_player(vec2 pos0, vec2 pos1, vec2& new_pos, entity* notthis)
|
|||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// Server hooks
|
||||
void mods_tick()
|
||||
|
|
Loading…
Reference in a new issue