+
+void conveyor_think()
+{
+ entity e;
+
+ // set myself as current conveyor where possible
+ for(e = world; (e = findentity(e, conveyor, self)); )
+ e.conveyor = world;
+
+ if(self.state)
+ {
+ for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
+ if(!e.conveyor.state)
+ if(isPushable(e))
+ {
+ vector emin = e.absmin;
+ vector emax = e.absmax;
+ if(self.solid == SOLID_BSP)
+ {
+ emin -= '1 1 1';
+ emax += '1 1 1';
+ }
+ if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
+ if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
+ e.conveyor = self;
+ }
+
+ for(e = world; (e = findentity(e, conveyor, self)); )
+ {
+ if(e.flags & FL_CLIENT) // doing it via velocity has quite some advantages
+ continue; // done in SV_PlayerPhysics
+
+ setorigin(e, e.origin + self.movedir * sys_frametime);
+ move_out_of_solid(e);
+ UpdateCSQCProjectile(e);
+ /*
+ // stupid conveyor code
+ tracebox(e.origin, e.mins, e.maxs, e.origin + self.movedir * sys_frametime, MOVE_NORMAL, e);
+ if(trace_fraction > 0)
+ setorigin(e, trace_endpos);
+ */
+ }
+ }
+
+ self.nextthink = time;
+}
+
+void conveyor_use()
+{
+ self.state = !self.state;
+}
+
+void conveyor_reset()
+{
+ self.state = (self.spawnflags & 1);
+}
+
+void conveyor_init()
+{
+ if (!self.speed)
+ self.speed = 200;
+ self.movedir = self.movedir * self.speed;
+ self.think = conveyor_think;
+ self.nextthink = time;
+ IFTARGETED
+ {
+ self.use = conveyor_use;
+ self.reset = conveyor_reset;
+ conveyor_reset();
+ }
+ else
+ self.state = 1;
+}
+
+void spawnfunc_trigger_conveyor()
+{
+ SetMovedir();
+ EXACTTRIGGER_INIT;
+ conveyor_init();
+}
+
+void spawnfunc_func_conveyor()
+{
+ SetMovedir();
+ InitMovingBrushTrigger();
+ self.movetype = MOVETYPE_NONE;
+ conveyor_init();
+}