csqcprojectiles: do not network gravity if at default value (instead use a sendflags...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / csqcprojectile.qc
1 .float csqcprojectile_type;
2
3 float CSQCProjectile_SendEntity(entity to, float sf)
4 {
5         float ft, fr;
6
7         // note: flag 0x08 = no trail please (teleport bit)
8         sf = sf & 0x0F;
9
10         if(self.csqcprojectile_clientanimate)
11                 sf |= 0x80; // client animated, not interpolated
12
13         if(self.flags & FL_ONGROUND)
14                 sf |= 0x40;
15
16         if(self.fade_time != 0 && self.fade_rate != 0)
17         {
18                 ft = (self.fade_time - time) / sys_frametime;
19                 fr = (1 / self.fade_rate) / sys_frametime;
20                 if(ft <= 255 && fr <= 255 && fr >= 1)
21                         sf |= 0x20;
22         }
23
24         if(self.gravity != 0 && self.gravity != 1)
25                 sf |= 0x10;
26
27         WriteByte(MSG_ENTITY, ENT_CLIENT_PROJECTILE);
28         WriteByte(MSG_ENTITY, sf);
29
30         if(sf & 1)
31         {
32                 WriteCoord(MSG_ENTITY, self.origin_x);
33                 WriteCoord(MSG_ENTITY, self.origin_y);
34                 WriteCoord(MSG_ENTITY, self.origin_z);
35
36                 if(sf & 0x80)
37                 {
38                         WriteCoord(MSG_ENTITY, self.velocity_x);
39                         WriteCoord(MSG_ENTITY, self.velocity_y);
40                         WriteCoord(MSG_ENTITY, self.velocity_z);
41                         if(sf & 0x10)
42                                 WriteCoord(MSG_ENTITY, self.gravity);
43                 }
44
45                 if(sf & 0x20)
46                 {
47                         WriteByte(MSG_ENTITY, ft);
48                         WriteByte(MSG_ENTITY, fr);
49                 }
50         }
51
52         if(sf & 2)
53                 WriteByte(MSG_ENTITY, self.csqcprojectile_type); // TODO maybe put this into sf?
54         
55         return 1;
56 }
57
58 .vector csqcprojectile_oldorigin;
59 void CSQCProjectile_Check(entity e)
60 {
61         if(e.csqcprojectile_clientanimate)
62         if(e.flags & FL_ONGROUND)
63         if(e.origin != e.csqcprojectile_oldorigin)
64                 UpdateCSQCProjectile(e);
65         e.csqcprojectile_oldorigin = e.origin;
66 }
67
68 void CSQCProjectile(entity e, float clientanimate, float type, float docull)
69 {
70         Net_LinkEntity(e, docull, 0, CSQCProjectile_SendEntity);
71         
72         e.csqcprojectile_clientanimate = clientanimate;
73         
74         if(e.movetype == MOVETYPE_TOSS || e.movetype == MOVETYPE_BOUNCE)
75         {
76                 if(e.gravity == 0)
77                         e.gravity = 1;
78         }
79         else
80                 e.gravity = 0;
81
82         e.csqcprojectile_type = type;
83         if(!sound_allowed(MSG_BROADCAST, e))
84                 type |= 0x80;
85 }
86
87 void UpdateCSQCProjectile(entity e)
88 {
89         if(e.SendEntity == CSQCProjectile_SendEntity)
90         {
91                 // send new origin data
92                 e.SendFlags |= 0x01;
93         }
94 }
95
96 void UpdateCSQCProjectileAfterTeleport(entity e)
97 {
98         if(e.SendEntity == CSQCProjectile_SendEntity)
99         {
100                 // send new origin data
101                 e.SendFlags |= 0x01;
102                 // mark as teleported
103                 e.SendFlags |= 0x08;
104         }
105 }
106
107 .void(void) csqcprojectile_oldthink;
108 .float csqcprojectile_oldnextthink;
109
110 void CSQCProjectile_Update_Think()
111 {
112         UpdateCSQCProjectile(self);
113         self.think = self.csqcprojectile_oldthink;
114         self.nextthink = max(time, self.csqcprojectile_oldnextthink);
115 }
116
117 void UpdateCSQCProjectileNextFrame(entity e)
118 {
119         if(e.SendEntity == CSQCProjectile_SendEntity)
120         if(e.think != CSQCProjectile_Update_Think)
121         {
122                 e.csqcprojectile_oldthink = e.think;
123                 e.csqcprojectile_oldnextthink = e.nextthink;
124                 e.think = CSQCProjectile_Update_Think;
125                 e.nextthink = time;
126         }
127 }