]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/func/conveyor.qc
acb6529ff3c196a1853b3213f500b47e29eb5c54
[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.active)
21         {
22                 FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, !it.conveyor.active && 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_setactive(entity this, int act)
67 {
68         int old_status = this.active;
69         if(act == ACTIVE_TOGGLE)
70         {
71                 if(this.active == ACTIVE_ACTIVE)
72                 {
73                         this.active = ACTIVE_NOT;
74                 }
75                 else
76                 {
77                         this.active = ACTIVE_ACTIVE;
78                 }
79         }
80         else
81         {
82                 this.active = act;
83         }
84
85         if (this.active != old_status)
86         {
87                 this.SendFlags |= SF_TRIGGER_UPDATE;
88         }
89 }
90
91 // Compatibility with old maps
92 void conveyor_use(entity this, entity actor, entity trigger)
93 {
94         conveyor_setactive(this, ACTIVE_TOGGLE);
95 }
96
97 void conveyor_reset(entity this)
98 {
99         IFTARGETED
100         {
101                 if(this.spawnflags & CONVEYOR_START_ENABLED)
102                 {
103                         this.active = ACTIVE_ACTIVE;
104                 }
105         }
106         else
107         {
108                 this.active = ACTIVE_ACTIVE;
109         }
110
111         this.SendFlags |= SF_TRIGGER_UPDATE;
112 }
113
114 bool conveyor_send(entity this, entity to, int sendflags)
115 {
116         WriteHeader(MSG_ENTITY, ENT_CLIENT_CONVEYOR);
117         WriteByte(MSG_ENTITY, sendflags);
118
119         if(sendflags & SF_TRIGGER_INIT)
120         {
121                 WriteByte(MSG_ENTITY, this.warpzone_isboxy);
122                 WriteVector(MSG_ENTITY, this.origin);
123
124                 WriteVector(MSG_ENTITY, this.mins);
125                 WriteVector(MSG_ENTITY, this.maxs);
126
127                 WriteVector(MSG_ENTITY, this.movedir);
128
129                 WriteByte(MSG_ENTITY, this.speed);
130                 WriteByte(MSG_ENTITY, this.active);
131
132                 WriteString(MSG_ENTITY, this.targetname);
133                 WriteString(MSG_ENTITY, this.target);
134         }
135
136         if(sendflags & SF_TRIGGER_UPDATE)
137                 WriteByte(MSG_ENTITY, this.active);
138
139         return true;
140 }
141
142 void conveyor_init(entity this)
143 {
144         if (!this.speed) this.speed = 200;
145         this.movedir *= this.speed;
146         setthink(this, conveyor_think);
147         this.nextthink = time;
148         this.setactive = conveyor_setactive;
149         IFTARGETED
150         {
151                 // backwards compatibility
152                 this.use = conveyor_use;
153         }
154         this.reset = conveyor_reset;
155         this.reset(this);
156
157         FixSize(this);
158
159         Net_LinkEntity(this, 0, false, conveyor_send);
160
161         this.SendFlags |= SF_TRIGGER_INIT;
162 }
163
164 spawnfunc(trigger_conveyor)
165 {
166         SetMovedir(this);
167         EXACTTRIGGER_INIT;
168         conveyor_init(this);
169 }
170
171 spawnfunc(func_conveyor)
172 {
173         SetMovedir(this);
174         InitMovingBrushTrigger(this);
175         set_movetype(this, MOVETYPE_NONE);
176         conveyor_init(this);
177 }
178
179 #elif defined(CSQC)
180
181 void conveyor_draw(entity this) { conveyor_think(this); }
182
183 void conveyor_init(entity this, bool isnew)
184 {
185         if(isnew)
186                 IL_PUSH(g_drawables, this);
187         this.draw = conveyor_draw;
188         this.drawmask = MASK_NORMAL;
189
190         set_movetype(this, MOVETYPE_NONE);
191         this.model = "";
192         this.solid = SOLID_TRIGGER;
193         this.move_time = time;
194 }
195
196 NET_HANDLE(ENT_CLIENT_CONVEYOR, bool isnew)
197 {
198         int sendflags = ReadByte();
199
200         if(sendflags & SF_TRIGGER_INIT)
201         {
202                 this.warpzone_isboxy = ReadByte();
203                 this.origin = ReadVector();
204                 setorigin(this, this.origin);
205
206                 this.mins = ReadVector();
207                 this.maxs = ReadVector();
208                 setsize(this, this.mins, this.maxs);
209
210                 this.movedir = ReadVector();
211
212                 this.speed = ReadByte();
213                 this.active = ReadByte();
214
215                 this.targetname = strzone(ReadString());
216                 this.target = strzone(ReadString());
217
218                 conveyor_init(this, isnew);
219         }
220
221         if(sendflags & SF_TRIGGER_UPDATE)
222                 this.active = ReadByte();
223
224         return true;
225 }
226 #endif