a8dfafc874299f81758e7671f276d581da325490
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / conveyor.qc
1 void conveyor_think()
2 {SELFPARAM();
3 #ifdef CSQC
4         // TODO: check if this is what is causing the glitchiness when switching between them
5         float dt = time - self.move_time;
6         self.move_time = time;
7         if(dt <= 0) { return; }
8 #endif
9         entity e;
10
11         // set myself as current conveyor where possible
12         for(e = world; (e = findentity(e, conveyor, self)); )
13                 e.conveyor = world;
14
15         if(self.state)
16         {
17                 for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
18                         if(!e.conveyor.state)
19                                 if(isPushable(e))
20                                 {
21                                         vector emin = e.absmin;
22                                         vector emax = e.absmax;
23                                         if(self.solid == SOLID_BSP)
24                                         {
25                                                 emin -= '1 1 1';
26                                                 emax += '1 1 1';
27                                         }
28                                         if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
29                                                 if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
30                                                         e.conveyor = self;
31                                 }
32
33                 for(e = world; (e = findentity(e, conveyor, self)); )
34                 {
35                         if(IS_CLIENT(e)) // doing it via velocity has quite some advantages
36                                 continue; // done in SV_PlayerPhysics   continue;
37
38                         setorigin(e, e.origin + self.movedir * PHYS_INPUT_FRAMETIME);
39                         move_out_of_solid(e);
40 #ifdef SVQC
41                         UpdateCSQCProjectile(e);
42 #endif
43                         /*
44                         // stupid conveyor code
45                         tracebox(e.origin, e.mins, e.maxs, e.origin + self.movedir * sys_frametime, MOVE_NORMAL, e);
46                         if(trace_fraction > 0)
47                                 setorigin(e, trace_endpos);
48                         */
49                 }
50         }
51
52 #ifdef SVQC
53         self.nextthink = time;
54 #endif
55 }
56
57 #ifdef SVQC
58
59 void conveyor_use()
60 {SELFPARAM();
61         self.state = !self.state;
62
63         self.SendFlags |= 2;
64 }
65
66 void conveyor_reset()
67 {SELFPARAM();
68         self.state = (self.spawnflags & 1);
69
70         self.SendFlags |= 2;
71 }
72
73 bool conveyor_send(entity this, entity to, int sf)
74 {
75         WriteHeader(MSG_ENTITY, ENT_CLIENT_CONVEYOR);
76         WriteByte(MSG_ENTITY, sf);
77
78         if(sf & 1)
79         {
80                 WriteByte(MSG_ENTITY, self.warpzone_isboxy);
81                 WriteCoord(MSG_ENTITY, self.origin_x);
82                 WriteCoord(MSG_ENTITY, self.origin_y);
83                 WriteCoord(MSG_ENTITY, self.origin_z);
84
85                 WriteCoord(MSG_ENTITY, self.mins_x);
86                 WriteCoord(MSG_ENTITY, self.mins_y);
87                 WriteCoord(MSG_ENTITY, self.mins_z);
88                 WriteCoord(MSG_ENTITY, self.maxs_x);
89                 WriteCoord(MSG_ENTITY, self.maxs_y);
90                 WriteCoord(MSG_ENTITY, self.maxs_z);
91
92                 WriteCoord(MSG_ENTITY, self.movedir_x);
93                 WriteCoord(MSG_ENTITY, self.movedir_y);
94                 WriteCoord(MSG_ENTITY, self.movedir_z);
95
96                 WriteByte(MSG_ENTITY, self.speed);
97                 WriteByte(MSG_ENTITY, self.state);
98
99                 WriteString(MSG_ENTITY, self.targetname);
100                 WriteString(MSG_ENTITY, self.target);
101         }
102
103         if(sf & 2)
104                 WriteByte(MSG_ENTITY, self.state);
105
106         return true;
107 }
108
109 void conveyor_init()
110 {SELFPARAM();
111         if (!self.speed)
112                 self.speed = 200;
113         self.movedir = self.movedir * self.speed;
114         self.think = conveyor_think;
115         self.nextthink = time;
116         IFTARGETED
117         {
118                 self.use = conveyor_use;
119                 self.reset = conveyor_reset;
120                 conveyor_reset();
121         }
122         else
123                 self.state = 1;
124
125         FixSize(self);
126
127         Net_LinkEntity(self, 0, false, conveyor_send);
128
129         self.SendFlags |= 1;
130 }
131
132 spawnfunc(trigger_conveyor)
133 {
134         SetMovedir(self);
135         EXACTTRIGGER_INIT;
136         conveyor_init();
137 }
138
139 spawnfunc(func_conveyor)
140 {
141         SetMovedir(self);
142         InitMovingBrushTrigger();
143         self.movetype = MOVETYPE_NONE;
144         conveyor_init();
145 }
146
147 #elif defined(CSQC)
148
149 void conveyor_draw(entity this) { WITH(entity, self, this, conveyor_think()); }
150
151 void conveyor_init()
152 {SELFPARAM();
153         self.draw = conveyor_draw;
154         self.drawmask = MASK_NORMAL;
155
156         self.movetype = MOVETYPE_NONE;
157         self.model = "";
158         self.solid = SOLID_TRIGGER;
159         self.move_origin = self.origin;
160         self.move_time = time;
161 }
162
163 void ent_conveyor()
164 {SELFPARAM();
165         float sf = ReadByte();
166
167         if(sf & 1)
168         {
169                 self.warpzone_isboxy = ReadByte();
170                 self.origin_x = ReadCoord();
171                 self.origin_y = ReadCoord();
172                 self.origin_z = ReadCoord();
173                 setorigin(self, self.origin);
174
175                 self.mins_x = ReadCoord();
176                 self.mins_y = ReadCoord();
177                 self.mins_z = ReadCoord();
178                 self.maxs_x = ReadCoord();
179                 self.maxs_y = ReadCoord();
180                 self.maxs_z = ReadCoord();
181                 setsize(self, self.mins, self.maxs);
182
183                 self.movedir_x = ReadCoord();
184                 self.movedir_y = ReadCoord();
185                 self.movedir_z = ReadCoord();
186
187                 self.speed = ReadByte();
188                 self.state = ReadByte();
189
190                 self.targetname = strzone(ReadString());
191                 self.target = strzone(ReadString());
192
193                 conveyor_init();
194         }
195
196         if(sf & 2)
197                 self.state = ReadByte();
198 }
199 #endif