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