+ this.nade_show_particles = 0;
+}
+
+entity nades_spawn_orb(entity own, entity realown, vector org, float orb_ltime, float orb_rad)
+{
+ // NOTE: this function merely places an orb
+ // you must add a custom touch function to the returned entity if desired
+ // also set .colormod if you wish to have it colorized
+ entity orb = spawn(); // Net_LinkEntity sets the classname (TODO)
+ orb.owner = own;
+ orb.realowner = realown;
+ setorigin(orb, org);
+
+ orb.orb_lifetime = orb_ltime; // required for timers
+ orb.ltime = time + orb.orb_lifetime;
+ orb.bot_dodge = false;
+ orb.team = realown.team;
+ orb.solid = SOLID_TRIGGER;
+
+ setmodel(orb, MDL_NADE_ORB);
+ orb.skin = 1;
+ orb.orb_radius = orb_rad; // required for fading
+ vector size = '1 1 1' * orb.orb_radius / 2;
+ setsize(orb, -size, size);
+
+ Net_LinkEntity(orb, true, 0, orb_send);
+ orb.SendFlags |= 1;
+
+ setthink(orb, nades_orb_think);
+ orb.nextthink = time;
+
+ return orb;
+}
+
+void nade_entrap_touch(entity this, entity toucher)
+{
+ if(DIFF_TEAM(toucher, this.realowner)) // TODO: what if realowner changes team or disconnects?
+ {
+ if (!isPushable(toucher))
+ return;
+
+ float pushdeltatime = time - toucher.lastpushtime;
+ if (pushdeltatime > 0.15) pushdeltatime = 0;
+ toucher.lastpushtime = time;
+ if(!pushdeltatime) return;
+
+ // div0: ticrate independent, 1 = identity (not 20)
+ toucher.velocity = toucher.velocity * pow(autocvar_g_nades_entrap_strength, pushdeltatime);
+
+ #ifdef SVQC
+ UpdateCSQCProjectile(toucher);
+ #endif
+ }
+
+ if ( IS_REAL_CLIENT(toucher) || IS_VEHICLE(toucher) || IS_MONSTER(toucher) )
+ {
+ entity show_tint = (IS_VEHICLE(toucher)) ? toucher.owner : toucher;
+ STAT(ENTRAP_ORB, show_tint) = time + 0.1;
+
+ float tint_alpha = 0.75;
+ if(SAME_TEAM(toucher, this.realowner))
+ tint_alpha = 0.45;
+ STAT(ENTRAP_ORB_ALPHA, show_tint) = tint_alpha * (this.ltime - time) / this.orb_lifetime;
+ }