I have a somewhat working killcam. Problems are that it doesn't rotate the camera to face the player who killed you, the position isn't exactly perfectly infront of the player, and for some reason I can't figure out, it crashes the server when the add-on is enabled, regardless if anyone died. Also, it doesn't show a quick move to the player (can't figure that out, cameras aren't a strong point of mine) and a freezeframe like TF2 (don't think its possible) , just a delayed instant move to the player, with a freely rotatable camera.
If anyone wants to fix it up, go ahead, I've lost interest. Just give me some credit if you release it.
//Some portions of this work are copyright Jack Coady, aka Space Guy
if(isFile("Add-Ons/System_ReturnToBlockland/server.cs"))
{
if(!$RTB::RTBR_ServerControl_Hook)
exec("Add-Ons/System_ReturnToBlockland/RTBR_ServerControl_Hook.cs");
RTB_registerPref("Use Kill Cam", "Kill Cam", "$Pref::Server::KillCam", "bool", "Script_KillCam", 1, 0, 0);
RTB_registerPref("Kill Cam Delay", "Kill Cam", "$Pref::Server::KillCamDelay", "int 0 3000", "Script_KillCam", 1000, 0, 0);
RTB_registerPref("Kill Cam Time", "Kill Cam", "$Pref::Server::KillCamTime", "int 1000 10000", "Script_KillCam", 2000, 0, 0);
}
package KillCam
{
function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc)
{
Parent::onDeath(%this,%sourceObject,%sourceClient,%damageType,%damLoc);
if($Pref::Server::KillCam && isObject(%sourceClient.player))
{
%this.schedule($Pref::Server::KillCamDelay,killCam,%sourceClient);
if(%this.minigame.respawnTime >= 3000)
%this.schedule(%this.minigame.respawnTime-$Pref::Server::KillCamDelay,spawnPlayer);
else
%this.schedule(3000,spawnPlayer);
}
}
};
function GameConnection::killCam(%this,%sourceClient)
{
if(isObject(%sourceClient.player))
{
%this.setControlObject(%this.camera);
%this.camera.setClampMode(%sourceClient.player,VectorAdd(VectorScale(%sourceClient.player.getMuzzleVector(0),1),"0 5 2.5"));
%this.camera.setTransform(%this.camera.getPosition() SPC eulerToAxis(vectorAdd(getFireAimVector(%this.camera.getPosition(),%sourceClient.player.getPosition(),0,999999999),"0 0 180")));
}
}
ActivatePackage(KillCam);
//-------------------------------
//Found these in a post by Trader
//-------------------------------
function eulerToAxis(%euler)
{
%euler = VectorScale(%euler,$pi / 180);
%matrix = MatrixCreateFromEuler(%euler);
return getWords(%matrix,3,6);
}
function axisToEuler(%axis)
{
%angleOver2 = getWord(%axis,3) * 0.5;
%angleOver2 = -%angleOver2;
%sinThetaOver2 = mSin(%angleOver2);
%cosThetaOver2 = mCos(%angleOver2);
%q0 = %cosThetaOver2;
%q1 = getWord(%axis,0) * %sinThetaOver2;
%q2 = getWord(%axis,1) * %sinThetaOver2;
%q3 = getWord(%axis,2) * %sinThetaOver2;
%q0q0 = %q0 * %q0;
%q1q2 = %q1 * %q2;
%q0q3 = %q0 * %q3;
%q1q3 = %q1 * %q3;
%q0q2 = %q0 * %q2;
%q2q2 = %q2 * %q2;
%q2q3 = %q2 * %q3;
%q0q1 = %q0 * %q1;
%q3q3 = %q3 * %q3;
%m13 = 2.0 * (%q1q3 - %q0q2);
%m21 = 2.0 * (%q1q2 - %q0q3);
%m22 = 2.0 * %q0q0 - 1.0 + 2.0 * %q2q2;
%m23 = 2.0 * (%q2q3 + %q0q1);
%m33 = 2.0 * %q0q0 - 1.0 + 2.0 * %q3q3;
return mRadToDeg(mAsin(%m23)) SPC mRadToDeg(mAtan(-%m13, %m33)) SPC mRadToDeg(mAtan(-%m21, %m22));
}
//-------------------------------------------------------
//Took this from Space Guys' fireHomingProjectile event.
//-------------------------------------------------------
function getFireAimVector(%start,%end,%g,%u)
{
%vec = vectorSub(%end,%start);
//If the projectile isn't actually affected by gravity, then return the direct vector
if(%g <= 0)
return vectorNormalize(%vec);
%xx = getWord(%vec,0);
%yy = getWord(%vec,1);
//Convert the 3-space vector to (xy, z)
%sx = mSqrt(%xx*%xx + %yy*%yy);
%sy = getWord(%vec,2);
if(%sx == 0 && %sy > 0)
{
return "0 0 1";
}
%a = (-0.5*%g*%sx*%sx) / (%u*%u);
%b = %sx;
%c = ((-0.5*%g*%sx*%sx) / (%u*%u)) - %sy;
//This seems to be badly implemented and returns negative versions of the answers
//%str = mSolveQuadratic(%a,%b,%c);
%d = %b*%b - 4*%a*%c;
if(%d > 0)
{
%s1 = mATan((-%b+mSqrt(%d)) / (2*%a),1);
%s2 = mATan((-%b-mSqrt(%d)) / (2*%a),1);
//A lower angle is more direct and will hit the target quicker, so it's preferable
if(%s1 < %s2)
%ang = %s1;
else
%ang = %s2;
}
if(%d == 0)
{
%ang = mATan((-%b) / (2*%a),1);
}
if(%d < 0)
{
//No solution when sqrt(%d < 0).
return "0 0 1";
}
//retVec must be normalized as it will return (0 0 -sin45) when directly below the point
%nVec = vectorNormalize(%xx SPC %yy);
%retVec = vectorNormalize(getWord(%nVec,0) * mCos(%ang) SPC getWord(%nVec,1) * mCos(%ang) SPC mSin(%ang));
return %retVec;
}
As for zelda style item recieve animations, I'd just use bottom print. Otherwise you'd have to have a clientside add-on, and not everyone will have it.
Though you could use a gui for players who have it, and just bottom print to those who don't.
For the animation, if you're not too picky, you could just use the preexisting armReadyBoth