Merge branch 'master' into martin-t/mg-solidpen
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / weapons / csqcprojectile.qc
1 #include "csqcprojectile.qh"
2
3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
5 #include <common/t_items.qh>
6
7 #include "../command/common.qh"
8
9 #include <common/constants.qh>
10 #include <common/net_linked.qh>
11 #include <common/weapons/_all.qh>
12
13 .float csqcprojectile_type;
14
15 bool CSQCProjectile_SendEntity(entity this, entity to, int sf)
16 {
17         float ft, fr;
18
19         // note: flag 0x08 = no trail please (teleport bit)
20         sf = sf & 0x0F;
21
22         if(this.csqcprojectile_clientanimate)
23                 sf |= 0x80; // client animated, not interpolated
24
25         if(IS_ONGROUND(this))
26                 sf |= 0x40;
27
28         ft = fr = 0;
29         if(this.fade_time != 0 || this.fade_rate != 0)
30         {
31                 ft = (this.fade_time - time) / sys_frametime;
32                 fr = (1 / this.fade_rate) / sys_frametime;
33                 if(ft <= 255 && fr <= 255 && fr >= 1)
34                         sf |= 0x20;
35         }
36
37         if(this.gravity != 0)
38                 sf |= 0x10;
39
40         WriteHeader(MSG_ENTITY, ENT_CLIENT_PROJECTILE);
41         WriteByte(MSG_ENTITY, sf);
42
43         if(sf & 1)
44         {
45                 WriteVector(MSG_ENTITY, this.origin);
46
47                 if(sf & 0x80)
48                 {
49                         WriteVector(MSG_ENTITY, this.velocity);
50                         if(sf & 0x10)
51                                 WriteCoord(MSG_ENTITY, this.gravity);
52                 }
53
54                 if(sf & 0x20)
55                 {
56                         WriteByte(MSG_ENTITY, ft);
57                         WriteByte(MSG_ENTITY, fr);
58                 }
59
60                 if(teamplay)
61                         WriteByte(MSG_ENTITY, this.realowner.team);
62                 else
63                         WriteByte(MSG_ENTITY, this.realowner.clientcolors); // NOTE: doesn't work on non-clients
64         }
65
66         if(sf & 2)
67                 WriteByte(MSG_ENTITY, this.csqcprojectile_type); // TODO maybe put this into sf?
68
69         return true;
70 }
71
72 .vector csqcprojectile_oldorigin;
73 void CSQCProjectile_Check(entity e)
74 {
75         if(e.csqcprojectile_clientanimate)
76         if(IS_ONGROUND(e))
77         if(e.origin != e.csqcprojectile_oldorigin)
78                 UpdateCSQCProjectile(e);
79         e.csqcprojectile_oldorigin = e.origin;
80 }
81
82 void CSQCProjectile(entity e, float clientanimate, int type, float docull)
83 {
84         Net_LinkEntity(e, docull, 0, CSQCProjectile_SendEntity);
85
86         e.csqcprojectile_clientanimate = clientanimate;
87
88         if(e.move_movetype == MOVETYPE_TOSS || e.move_movetype == MOVETYPE_BOUNCE)
89         {
90                 if(e.gravity == 0)
91                         e.gravity = 1;
92         }
93         else
94                 e.gravity = 0;
95
96         if(!sound_allowed(MSG_BROADCAST, e))
97                 type |= 0x80;
98         e.csqcprojectile_type = type;
99 }
100
101 void UpdateCSQCProjectile(entity e)
102 {
103         if(getSendEntity(e) == CSQCProjectile_SendEntity)
104         {
105                 // send new origin data
106                 e.SendFlags |= 0x01;
107         }
108 // FIXME HACK
109         else if(getSendEntity(e) == ItemSend)
110         {
111                 ItemUpdate(e);
112         }
113 // END HACK
114 }
115
116 void UpdateCSQCProjectileAfterTeleport(entity e)
117 {
118         if(getSendEntity(e) == CSQCProjectile_SendEntity)
119         {
120                 // send new origin data
121                 e.SendFlags |= 0x01;
122                 // mark as teleported
123                 e.SendFlags |= 0x08;
124         }
125 }