1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#include <engine/e_server_interface.h>
#include <game/generated/g_protocol.hpp>
#include <game/server/gamecontext.hpp>
#include "projectile.hpp"
//////////////////////////////////////////////////
// projectile
//////////////////////////////////////////////////
PROJECTILE::PROJECTILE(int type, int owner, vec2 pos, vec2 dir, int span,
int damage, int flags, float force, int sound_impact, int weapon)
: ENTITY(NETOBJTYPE_PROJECTILE)
{
this->type = type;
this->pos = pos;
this->direction = dir;
this->lifespan = span;
this->owner = owner;
this->flags = flags;
this->force = force;
this->damage = damage;
this->sound_impact = sound_impact;
this->weapon = weapon;
this->bounce = 0;
this->start_tick = server_tick();
game.world.insert_entity(this);
}
void PROJECTILE::reset()
{
game.world.destroy_entity(this);
}
vec2 PROJECTILE::get_pos(float time)
{
float curvature = 0;
float speed = 0;
if(type == WEAPON_GRENADE)
{
curvature = tuning.grenade_curvature;
speed = tuning.grenade_speed;
}
else if(type == WEAPON_SHOTGUN)
{
curvature = tuning.shotgun_curvature;
speed = tuning.shotgun_speed;
}
else if(type == WEAPON_GUN)
{
curvature = tuning.gun_curvature;
speed = tuning.gun_speed;
}
return calc_pos(pos, direction, curvature, speed, time);
}
void PROJECTILE::tick()
{
float pt = (server_tick()-start_tick-1)/(float)server_tickspeed();
float ct = (server_tick()-start_tick)/(float)server_tickspeed();
vec2 prevpos = get_pos(pt);
vec2 curpos = get_pos(ct);
lifespan--;
int collide = col_intersect_line(prevpos, curpos, &curpos);
//int collide = col_check_point((int)curpos.x, (int)curpos.y);
CHARACTER *ownerchar = game.get_player_char(owner);
CHARACTER *targetchr = game.world.intersect_character(prevpos, curpos, 6.0f, curpos, ownerchar);
if(targetchr || collide || lifespan < 0)
{
if(lifespan >= 0 || weapon == WEAPON_GRENADE)
game.create_sound(curpos, sound_impact);
if(flags & PROJECTILE_FLAGS_EXPLODE)
game.create_explosion(curpos, owner, weapon, false);
else if(targetchr)
targetchr->take_damage(direction * max(0.001f, force), damage, owner, weapon);
game.world.destroy_entity(this);
}
}
void PROJECTILE::fill_info(NETOBJ_PROJECTILE *proj)
{
proj->x = (int)pos.x;
proj->y = (int)pos.y;
proj->vx = (int)(direction.x*100.0f);
proj->vy = (int)(direction.y*100.0f);
proj->start_tick = start_tick;
proj->type = type;
}
void PROJECTILE::snap(int snapping_client)
{
float ct = (server_tick()-start_tick)/(float)server_tickspeed();
if(networkclipped(snapping_client, get_pos(ct)))
return;
NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
fill_info(proj);
}
|