
main()
{
	level endon("ex_gameover");
	scndwave = false;

	while(!level.ex_gameover)
	{
		if(scndwave)
			delay = randomInt(2) + 2;
		else
			delay = randomInt(level.ex_mortars_delay_max - level.ex_mortars_delay_min) + level.ex_mortars_delay_min;

		mortarnumber = randomInt(level.ex_mortars_max - level.ex_mortars_min) + level.ex_mortars_min / 2;

		if(mortarnumber < 2) mortarnumber = 2;

		if(delay < 20 && !scndwave) delay = 20;
		
		wait( [[level.ex_fpstime]](delay) );

		extreme\_ex_utils::playSoundOnPlayers("mortarlaunch_incoming");

		// recon report
		if(!scndwave) thread extreme\_ex_battlechatter::teamchatter("inform_incoming_mortar", "both");
		else if(randomInt(100) > 50) thread extreme\_ex_battlechatter::teamchatter("order_cover_generic", "both");

		wait( [[level.ex_fpstime]](randomfloat(4) + 0.5) );
		mortarcount = 0;

		while(mortarcount < mortarnumber && mortarnumber >= 1)
		{
			thread gomortars();
			mortarcount++;
			wait( [[level.ex_fpstime]](0.3) );
		}

		if(!scndwave)
			scndwave = true;
		else scndwave = false;
	}
}

gomortars()
{
	level endon("ex_stopfx");

	x = game["playArea_Min"][0] + randomInt(game["playArea_Width"]);
	y = game["playArea_Min"][1] + randomInt(game["playArea_Length"]);
	z = game["mapArea_Max"][2] - 200;

	// start point for mortar
	startpoint = (x, y, z);
	endorigin = (x,y,z - 2048);

	// get the impact point
	trace = bulletTrace(startpoint, endorigin, true, undefined);                   
	if(trace["fraction"] < 1) endorigin = trace["position"];
		else endorigin = (endorigin[0], endorigin[1], game["mapArea_Min"][2]);

	// show visible mortar object
	mortar = spawn("script_model", startpoint);
	mortar setModel("xmodel/prop_stuka_bomb");
	mortar.origin = startpoint;
	mortar.angles = vectortoangles(vectornormalize(mortar.origin - startpoint));

	// play the incoming sound
	mortarsfx[0] = "mortar_incoming1";
	mortarsfx[1] = "mortar_incoming2";
	mortarsfx[2] = "mortar_incoming3";
	mortarsfx[3] = "mortar_incoming4";
	mortarsfx[4] = "mortar_incoming5";
	ms = randomInt(mortarsfx.size);
	mortar playsound(mortarsfx[ms]);

	falltime = randomfloat(1) + 0.5;

	// move visible mortar
	mortar moveto(endorigin, falltime);

	// wait for it to hit
	wait( [[level.ex_fpstime]](falltime) );

	// play the explosion sound
	mortarsfx[0] = "mortar_explosion1";
	mortarsfx[1] = "mortar_explosion2";
	mortarsfx[2] = "mortar_explosion3";
	mortarsfx[3] = "mortar_explosion4";
	mortarsfx[4] = "mortar_explosion5";
	ms = randomInt(mortarsfx.size);
	mortar playsound(mortarsfx[ms]);

	// do the damage!
	surfaceFx = calcImpactSurface(mortar.origin);
	if(level.ex_mortars == 1)
		mortar thread extreme\_ex_utils::scriptedfxradiusdamage(mortar, undefined, "MOD_EXPLOSIVE", "mortar_mp", level.ex_mortar_radius, 0, 0, "generic",  surfaceFX, true, true, true);
                
	if(level.ex_mortars == 2)
		mortar thread extreme\_ex_utils::scriptedfxradiusdamage(mortar, undefined, "MOD_EXPLOSIVE", "mortar_mp", level.ex_mortar_radius, 500, 350, "generic", surfaceFX, true, true, true);

	// hide visible mortar
	mortar hide();
	wait( [[level.ex_fpstime]](1) );
	mortar delete();
}

calcImpactSurface(targetPos)
{
	startOrigin = targetPos + (0, 0, 800);
	endOrigin = targetPos + (0, 0, -2048);

	trace = bulletTrace(startOrigin, endOrigin, true, undefined);
	if(trace["fraction"] < 1.0) surface = trace["surfacetype"];
		else surface = "dirt";

	if(!isDefined(surface)) surface = "dirt";
	return surface;
}
