extend class Actor
{
	
	virtual void ApplyKickback(Actor inflictor, Actor source, int damage, double angle, Name mod, int flags)
	{
		double ang;
		int kickback;
		double thrust;

		if (inflictor && inflictor.projectileKickback)
			kickback = inflictor.projectileKickback;
		else if (!source || !source.player || !source.player.ReadyWeapon)
			kickback = gameinfo.defKickback;
		else
			kickback = source.player.ReadyWeapon.Kickback;

		kickback = int(kickback * G_SkillPropertyFloat(SKILLP_KickbackFactor));
		if (kickback)
		{
			Actor origin = (source && (flags & DMG_INFLICTOR_IS_PUFF)) ? source : inflictor;

			if (flags & DMG_USEANGLE)
			{
				ang = angle;
			}
			else if (origin.pos.xy == pos.xy)
			{
				// If the origin and target are in exactly the same spot, choose a random direction.
				// (Most likely cause is from telefragging somebody during spawning because they
				// haven't moved from their spawn spot at all.)
				ang = frandom[Kickback](0., 360.);
			}
			else
			{
				ang = origin.AngleTo(self);
			}

			thrust = mod == 'MDK' ? 10 : 32;
			if (Mass > 0)
			{
				thrust = clamp((damage * 0.125 * kickback) / Mass, 0., thrust);
			}

			// Don't apply ultra-small damage thrust
			if (thrust < 0.01) thrust = 0;

			// make fall forwards sometimes
			if ((damage < 40) && (damage > health)
				&& (pos.Z - origin.pos.Z > 64)
				&& random[Kickback](0, 1)
				// [RH] But only if not too fast and not flying
				&& thrust < 10
				&& !bNoGravity
				&& !bNoForwardFall
				&& (inflictor == NULL || !inflictor.bNoForwardFall)
				)
			{
				ang += 180.;
				thrust *= 4;
			}
			if (source && source.player && (flags & DMG_INFLICTOR_IS_PUFF)
				&& source.player.ReadyWeapon != NULL &&	(source.player.ReadyWeapon.bSTAFF2_KICKBACK))
			{
				// Staff power level 2
				Thrust(10, ang);
				if (!bNoGravity)
				{
					Vel.Z += 5.;
				}
			}
			else
			{
				Thrust(thrust, ang);
			}
		}
	}

	
}