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