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