
main()
{
	level endon("ex_gameover");
	self endon("disconnect");
	self endon("ex_spawned");

	if(self.ex_sinbin) return;

	if(isPlayer(self) && self.sessionstate == "playing")
	{
		self.ex_sinbin = true;

		if(randomInt(100) < 50 && extreme\_ex_utils::isOutside(self.origin)) self sinSplat();
		else self sinFreeze();
		
		if(isPlayer(self)) self.ex_sinbin = false;
	}
}

sinFreeze()
{
	level endon("ex_gameover");
	self endon("disconnect");
	self endon("ex_dead");

	if(isPlayer(self))
	{
		self.ex_freezeme = true;
		self thread sinTimer(level.ex_sinfrztime);

		msg1 = &"SINBIN_FREEZE";
		msg2 = extreme\_ex_utils::time_convert(level.ex_sinfrztime);

		switch(level.ex_sinbinmsg)
		{
			case 0: self iprintln(msg1); self iprintln(msg2); break;
			case 1: self iprintlnbold(msg1); self iprintlnbold(msg2); break;
			default:
			{
				self thread extreme\_ex_utils::ex_hud_announce(msg1, 0);
				self thread extreme\_ex_utils::ex_hud_announce(msg2, 1);
				break;
			}
		}
	}

	if(isPlayer(self)) self thread extreme\_ex_utils::punishment("random", "freeze");

	self waittill("sinbin_timer_done");

	if(isPlayer(self)) self thread extreme\_ex_utils::punishment("enable", "release");
}

sinSplat()
{
	level endon("ex_gameover");
	self endon("disconnect");
	self endon("ex_dead");
	self endon("ex_spawned");
	self notify("ex_freefall");

	if(isPlayer(self))
	{
		self.ex_upndown = true;

		// if the gametype is flag based and they are the flag carrier, drop the flag!
		if(level.ex_flagbased && isDefined(self.flag))
		{
			switch(level.ex_currentgt)
			{
				case "ctf":
				self thread maps\mp\gametypes\ctf::dropflag();
				break;
				
				case "htf":
//				self thread maps\mp\gametypes\htf::dropflag();
				break;
			}
		}
	}

	while(isPlayer(self) && self.ex_upndown)
	{
		msg1 = &"SINBIN_FREEFALL";

		switch(level.ex_sinbinmsg)
		{
			case 0: self iprintln(msg1); break;
			case 1: self iprintlnbold(msg1); break;
			default:
			{
				self thread extreme\_ex_utils::ex_hud_announce(msg1, 0);
				break;
			}
		}

		if(isPlayer(self))
		{
			ix = self.origin[0];
			iy = self.origin[1];
		
			// override height on maps with bad skyboxes
			if(	level.ex_currentmap == "mp_carentan" || level.ex_currentmap == "mp_decoy" ||
				level.ex_currentmap == "mp_railyard" || level.ex_currentmap == "mp_toujane") iz = level.ex_mapArea_PlaneZ - randomInt(250);
				else iz = level.ex_mapArea_Max[2] - randomInt(250);

			startpoint = self.origin + ( 0, 0, 24);
			endpoint = ( ix, iy, iz);	

			distance = distance(startpoint, endpoint);
		
			self.ex_anchor = spawn ("script_model",(0,0,0));
			self.ex_anchor.origin = self.origin;
			self.ex_anchor.angles = self.angles;
			
			self linkto (self.ex_anchor);
		
			lifttime = distance/100 + randomint(6);
			
			self.ex_anchor.origin = startpoint;
			self.ex_anchor moveto (endpoint, lifttime);
		
			self thread sinTimer(int(lifttime) + 5);
			self waittill("sinbin_timer_done");

			if(isPlayer(self))
			{
				self.health = 1;
				self unlink();
				if(isDefined(self.ex_anchor)) self.ex_anchor delete();
			}
		}
	}

	wait 10;

	// still here?, stupid map!.....blow them up
	if(isPlayer(self) && self.sessionstate == "playing")
	{
		playfx(level.ex_effect["plane_bomb"], self.origin);
		self playsound("mortar_explosion1");
		wait 0.05;
		self.ex_forcedsuicide = true;
		self suicide();
	}
}

sinTimer(time)
{
	self endon("disconnect");
	self endon("ex_spawned");
	level endon("ex_gameover");

	// make them drop their grenades
	if(isPlayer(self)) self thread maps\mp\gametypes\_weapons::dropOffhand(true);

	while(isPlayer(self) && time > 0)
	{
		wait 1;
		time--;

		// if up and down stop thread
		if(isPlayer(self) && self.ex_upndown) self thread extreme\_ex_weapons::dropCurrentWeapon();
	}

	self notify("sinbin_timer_done");

	// if freefall, drop them like a stone!
	if(isPlayer(self) && self.ex_upndown)
	{
		self.ex_upndown = false;
		self.ex_sbsplat = true;
	}

	// if frozen on the spot, release them now
	if(isPlayer(self) && self.ex_freezeme) self.ex_freezeme = false;

	if(isPlayer(self))
	{
		if(isDefined(self.ex_sintimer)) self.ex_sintimer destroy();
		if(isDefined(self.ex_sintimertxt)) self.ex_sintimertxt destroy();
	}
}
