class SerpentGod_MagicSkull: Actor
{
	default
	{
		-NOGRAVITY
		+SEEKERMISSILE
		projectile;
		height 6;
		radius 5;
		speed 13;
		gravity 0.5;
		scale 0.7;
		ProjectileKickBack 60;
		damage 80;
		damagetype "explosion";
		deathsound "Skull/Explode";
	}
	states
	{
	spawn:
		PAN1 ABCDEFGH 3
		{
			double maxvelocity = 20.0;
			if (self.vel.length() < maxvelocity)
			{
				double velovertime = 0.5;
				self.vel.x += velovertime * cos(self.angle);
				self.vel.y += velovertime * sin(self.angle);
			}
			A_SpawnItemEx("FireEffect_HorizontalSmall", -8.0, 0.0, 12.0);
			A_SeekerMissile(0, 15, SMF_PRECISE|SMF_CURSPEED);
		}
		loop;
	death:
		NULL A 6
		{
			int range = 100;
			A_Quake(5, 6, 0, range*2);
			A_Explode(damage, range);
			A_SpawnItemEx("ExplosionEffect");
		}
		stop;
	}
}

class SerpentGod_Fireball: Actor
{
	default
	{
		projectile;
		radius 6;
		height 8;
		speed 20;
		damage 5;
		scale 1.0;
		deathsound "EXPL2";
		damagetype "explosion";
		renderstyle "add";
	}
	states
	{
	spawn:
		RPFB ABCD 4 BRIGHT NODELAY
		{
			double velovertime = 0.5;
			self.vel.x += velovertime * cos(self.angle);
			self.vel.y += velovertime * sin(self.angle);
		}
		Loop;
	death:
		---- A 0
		{
			int explosiondamage = 30;
			int range           = 100;
			A_Quake(5, 6, 0, range*2);
			A_Explode(explosiondamage, range);
			A_SpawnItemEx("ExplosionEffect_Green");
		}
		SRKG NMNMNMNMNMNMNMNMNMNMNMNM 2
		{
			alpha -= 0.05;
		}
		Stop;
	}
}

class SerpentGod: Actor
{
	int melee_didflipsprite;

	int sign(int x)
	{
		if (x > 0.0)
			return 1.0;
		else if (x < 0.0)
			return -1.0;
		return 0.0;
	}

	override string GetObituary (Actor victim, Actor inflictor, name mod, bool playerattack)
	{
		string hitobituaries[] =
		{
			"Serpent God decapitated %o",
			"%o was executed before Serpent God"
		};
		string obituaries[] =
		{
			"Serpent God exploded %o into little pieces."
		};

		if (mod == damagetype)
			return hitobituaries[Random(0, hitobituaries.Size() - 1)];
		else
			return obituaries[Random(0, obituaries.Size() - 1)];
	}

	// TODO: Just use seeking missle or something...
	// Q:    How do you retrive actor's velocity?
	int aproximateFireAngle(int sx, int sy, int tx, int ty, vector2 velocity)
	{
		int len = sqrt(velocity.Length());
		if (len > 15.0)
			len = 15.0;
		vector2 v0;
		v0.x = sx - tx;
		v0.y = sy - ty;
		vector2 v1;
		v1.x = sx - (tx + velocity.x);
		v1.y = sy - (ty + velocity.y);
		int b0 = atan2(v0.y, v0.x);
		int b1 = atan2(v1.y, v1.x);
		int alpha = len * 8 * sign(b1 - b0);
		return alpha;
	}

	default
	{
		monster;
		health 4000;
		radius 30;
		height 64;
		mass 500;
		speed 5;
		painchance 32;
		scale 1.0;
		meleethreshold 200;
		meleerange 70;
		damage 100;
		damagetype  "decapitate";
		seeSound    "Snake/Allert";
		painSound   "Snake/Pain";
		deathSound  "Snake/Scream";
		activeSound "Snake/Amblent";
	}

	states
	{
	spawn:
		PANG A 1 A_Look;
		loop;
	see:
		PANG AAAAAA 1 A_Chase;
		PANG BBBBBB 1 A_Chase;
		PANG CCCCCC 1 A_Chase;
		loop;
	melee:
		---- A 0
		{
			melee_didflipsprite = random(0, 1);
			if (melee_didflipsprite)
				A_SetScale(scale.x * (-1), scale.y);
		}
		PANG F 4 A_FaceTarget;
		PANG D 1 A_FaceTarget;
		PANG E 6 A_FaceTarget;
		PANG F 2
		{
			if (target)
			{
				int oldhp = target.health;
				
				A_CustomMeleeAttack(damage, "Snake/Sword", "Snake/Sword", damagetype);
				if (target.health != oldhp)
				{
					A_PlaySound("Melee/Flesh", CHAN_ITEM);
				}
			}
		}
		PANG G 3 A_FaceTarget;
		PANG H 6
		{
			A_FaceTarget();
			if (melee_didflipsprite)
				A_SetScale(scale.x * (-1), scale.y);
		}
		goto see;
	missile:
		// Decide what to do...
		---- A 0
		{
			A_Log("Missile decision");
			switch (random(0, 1))
			{
			case 0:
				A_Log("-> missile_fireball");
				setstatelabel("missile_fireball");
				break;
			}
		}
		// Falls through, skull attack.
		PANG K 10 A_FaceTarget;
		PANG J 6  A_FaceTarget;
		PANG I 10
		{
			A_FaceTarget();
			A_SpawnProjectile("SerpentGod_MagicSkull", 75, 0, alpha);
		}
		PANG J 10 A_FaceTarget;
		goto see;
	missile_fireball:
		PANG K 10 A_FaceTarget;
		PANG J 6  A_FaceTarget;
	missile_fireball_now:
		PANG I 5;
		PANG I 5
		{
			if (target)
			{
				vector2 targetvelocity;
				targetvelocity.x = target.vel.x;
				targetvelocity.y = target.vel.y;
				int alpha = aproximateFireAngle(self.x, self.y, target.x, target.y, targetvelocity);
				A_FaceTarget();
				A_SpawnProjectile("SerpentGod_Fireball", 75, +17, alpha+random(-2, 2));
				A_SpawnProjectile("SerpentGod_Fireball", 75, -17, alpha+random(-2, 2));
				if (random(1, 10) > 2)
					setstatelabel("missile_fireball_now");
			}
		}
		PANG I 5  A_FaceTarget;
		PANG J 5  A_FaceTarget;
		goto see;
	/*
	ring:
		PANG K 10 A_FaceTarget
		PANG J 6 A_FaceTarget
		PANG I 10 A_FaceTarget
		TNT1 A 0 A_PlaySound("Snake/Heads")
		TNT1 A 0 A_CustomMissile("OrbitSkull_1",32,0,0,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_2",32,0,30,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_3",32,0,60,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_4",32,0,90,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_5",32,0,120,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_6",32,0,150,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_7",32,0,180,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_8",32,0,210,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_9",32,0,240,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_10",32,0,270,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_11",32,0,300,2)
		TNT1 A 0 A_CustomMissile("OrbitSkull_12",32,0,330,2)
		PANG I 0 A_TakeInventory("Ring12", 12)
		PANG I 5 A_FaceTarget
		PANG J 6 A_FaceTarget
		goto see
	*/
	pain:
		PANG A 8 A_Pain;
		goto see;
	death:
		TNT1 A   0 A_Scream;
		PANG MN  5;
		PANG O   6;
		PANG P   7;
		PANG QR  5;
		PANG S   7;
		PANG T   5;
		PANG U   6;
		PANG VWX 2;
		TNT1 A 0 A_NoBlocking;
		PANG X -1;
		Stop;
	}
}
