Didn't change anything.
datablock ProjectileData(SkeletonKeyProjectile)
{
projectileShapeName = "base/data/shapes/empty.dts";
directDamage = 0;
directDamageType = $DamageType::Default;
radiusDamageType = $DamageType::Default;
brickExplosionRadius = 0;
brickExplosionImpact = 0; //destroy a brick if we hit it directly?
brickExplosionForce = 0;
brickExplosionMaxVolume = 0; //max volume of bricks that we can destroy
brickExplosionMaxVolumeFloating = 0; //max volume of bricks that we can destroy if they aren't connected to the ground
impactImpulse = 0;
verticalImpulse = 0;
explosion = 0;
bloodExplosion = 0;
particleEmitter = 0;
explodeOnPlayerImpact = false;
explodeOnDeath = false;
muzzleVelocity = 1;
velInheritFactor = 1;
armingDelay = 3000;
lifetime = 1;
fadeDelay = 3500;
bounceElasticity = 0.99;
bounceFriction = 0.20;
isBallistic = true;
gravityMod = 0.0;
hasLight = false;
lightRadius = 3.0;
lightColor = "0 0 0.5";
uiName = "Skeleton Key Projectile";
};
datablock ItemData(SkeletonKeyItem)
{
// Basic Item Properties
shapeFile = "Add-Ons/Item_Skeleton_Key/skele_key.dts";
mass = 1;
density = 0.2;
elasticity = 0.2;
friction = 0.6;
emap = true;
//gui properties
uiName = "Key Skeleton";
iconName = "Add-Ons/Item_Skeleton_Key/skele_key_icon";
doColorShift = false;
colorShiftColor = "0.0 0.0 0.0 1.0";
// Dynamic properties defined by the scripts
image = SkeletonKeyImage;
canDrop = true;
};
datablock ShapeBaseImageData(SkeletonKeyImage)
{
// Basic Item properties
shapeFile = "Add-Ons/Item_Skeleton_Key/skele_key.dts";
emap = true;
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
offset = "0 0.25 0";
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = false;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
className = "WeaponImage";
// Projectile && Ammo.
item = SkeletonKeyItem;
ammo = " ";
projectile = "SkeletonKeyProjectile";
projectileType = "projectile";
//melee particles shoot from eye node for consistancy
melee = true;
doRetraction = false;
//raise your arm up or not
armReady = true;
showBricks = false;
//casing = " ";
doColorShift = true;
colorShiftColor = SkeletonKeyItem.colorShiftColor;
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
// Initial start up state
stateName[0] = "Activate";
stateTimeoutValue[0] = 0.0;
stateTransitionOnTimeout[0] = "Ready";
stateName[1] = "Ready";
stateTransitionOnTriggerDown[1] = "PreFire";
stateAllowImageChange[1] = true;
stateName[2] = "PreFire";
stateScript[2] = "onPreFire";
stateAllowImageChange[2] = true;
stateTimeoutValue[2] = 0.01;
stateTransitionOnTimeout[2] = "Fire";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "CheckFire";
stateTimeoutValue[3] = 0.15;
stateFire[3] = true;
stateAllowImageChange[3] = true;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateWaitForTimeout[3] = true;
stateSequence[3] = "Fire";
stateName[4] = "CheckFire";
stateTransitionOnTriggerUp[4] = "StopFire";
stateName[5] = "StopFire";
stateTransitionOnTimeout[5] = "Ready";
stateTimeoutValue[5] = 0.01;
stateAllowImageChange[5] = true;
stateWaitForTimeout[5] = true;
stateSequence[5] = "StopFire";
stateScript[5] = "onStopFire";
};
function SkeletonKeyImage::onPreFire(%this, %obj, %slot)
{
%obj.playthread(2, shiftLeft);
}
function SkeletonKeyImage::onStopFire(%this, %obj, %slot)
{
%obj.playthread(2, root);
}
function SkeletonKeyImage::onFire(%this, %player, %slot)
{
%start = %player.getEyePoint();
%vec = vectorScale(%player.getMuzzleVector(%slot), 10 * getWord(%player.getScale(), 2) );
%end = vectorAdd(%start, %vec);
%mask = $TypeMasks::FxBrickObjectType;
%rayCast = containerRayCast(%start,%end,%mask);
if(!%rayCast)
return;
%hitObj = getWord(%rayCast, 0);
%hitPos = getWords(%rayCast, 1, 3);
%hitNormal = getWords(%rayCast, 4, 6);
%this.onHitObject(%player, %slot, %hitObj, %hitPos, %hitNormal);
}
// r,g,b values are from 0 to 1
// h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)
function RGBtoHSV(%r, %g, %b)
{
%min = getMin(%r, getMin(%g, %b));
%max = getMax(%r, getMax(%g, %b));
%delta = %max - %min;
%v = %max;
if(%max != 0)
{
%s = %delta / %max;
if(%delta == 0)
{
%h = -12;
}
else
{
if(%r == %max)
%h = (%g - %b) / %delta;
else if(%g == %max)
%h = 2 + ( %b - %r ) / %delta;
else
%h = 4 + ( %r - %g ) / %delta;
}
%h *= 60;
if(%h < 0)
%h += 360;
}
else
{
%s = 0;
%h = 0;
%v = 0;
}
%h = %h / 360;
return (%h SPC %s SPC %v);
}
function SkeletonKeyImage::onHitObject(%this, %player, %slot, %hitObj, %hitPos, %hitNormal)
{
%client = %player.client;
if(%hitObj.getType() & $TypeMasks::FxBrickAlwaysObjectType)
{
//determine if color matches or not via hue comparison
//get brick color
%brickRGBA = getColorIDTable(%hitObj.getColorId());
%r = getWord(%brickRGBA, 3);
%g = getWord(%brickRGBA, 3);
%b = getWord(%brickRGBA, 3);
//echo("brick rgb = " @ %r SPC %g SPC %b);
//echo("brick hsv " @ RGBtoHSV(%r,%g,%b));
%brickH = getWord(RGBtoHSV(%r,%g,%b), 0);
%brickRGB = %r SPC %g SPC %b;
%brickRGB = vectorNormalize(%brickRGB);
//get key color
%keyRGBA = %this.colorShiftColor;
%r = getWord(%keyRGBA, 3);
%g = getWord(%keyRGBA, 3);
%b = getWord(%keyRGBA, 3);
//echo("key rgb = " @ %r SPC %g SPC %b);
//echo("key hsv " @ RGBtoHSV(%r,%g,%b));
%keyH = getWord(RGBtoHSV(%r,%g,%b), 0);
%keyRGB = %r SPC %g SPC %b;
%keyRGB = vectorNormalize(%keyRGB);
//compare
%hDiff = mAbs(%keyH - %brickH);
if(%hDiff > 0.5)
%hDiff = 1 - %hDiff;
//echo("hDiff = " @ %hDiff);
%rgbDiff = vectorSub(%brickRGB, %keyRGB);
%rgbDiffLen = vectorLen(%rgbDiff);
//echo("rgbDiffLen = " @ %rgbDiffLen);
if(%hDiff > 0.1 || (%keyH >= 0 && %brickH < 0) || (%keyH < 0 && %brickH >= 0))
{
//echo("NO MATCH");
%hitObj.onKeyMismatch(%player);
}
else
{
//echo("MATCH");
%hitObj.onKeyMatch(%player);
}
}
}
function fxDTSBrick::OnKeyMatch(%obj, %player)
{
%client = %player.client;
$InputTarget_["Self"] = %obj;
$InputTarget_["Player"] = %player;
$InputTarget_["Client"] = %client;
if($Server::LAN)
{
$InputTarget_["MiniGame"] = getMiniGameFromObject(%client);
}
else
{
if(getMiniGameFromObject(%obj) == getMiniGameFromObject(%client))
$InputTarget_["MiniGame"] = getMiniGameFromObject(%obj);
else
$InputTarget_["MiniGame"] = 0;
}
%obj.processInputEvent("OnKeyMatch", %client);
}
function fxDTSBrick::OnKeyMismatch(%obj, %player)
{
%client = %player.client;
$InputTarget_["Self"] = %obj;
$InputTarget_["Player"] = %player;
$InputTarget_["Client"] = %client;
if($Server::LAN)
{
$InputTarget_["MiniGame"] = getMiniGameFromObject(%client);
}
else
{
if(getMiniGameFromObject(%obj) == getMiniGameFromObject(%client))
$InputTarget_["MiniGame"] = getMiniGameFromObject(%obj);
else
$InputTarget_["MiniGame"] = 0;
}
%obj.processInputEvent("OnKeyMismatch", %client);
}
registerInputEvent("fxDTSBrick", "onKeyMatch", "Self fxDTSBrick" TAB
"Player Player" TAB
"Client GameConnection" TAB
"MiniGame MiniGame");
registerInputEvent("fxDTSBrick", "onKeyMismatch", "Self fxDTSBrick" TAB
"Player Player" TAB
"Client GameConnection" TAB
"MiniGame MiniGame");