2022-10-05 16:02:11 -06:00

298 lines
6.9 KiB
C#

// Handles interactions with the handheld duplicator item.
// -------------------------------------------------------------------
//Set which image a client should use
function GameConnection::ndSetImage(%this, %image)
{
%image = %image.getId();
if(%image != %this.ndImage)
{
%this.ndImage = %image;
if(%this.ndEquipped)
{
%this.ndIgnoreNextMount = true;
%this.player.schedule(0, updateArm, %image);
%this.player.schedule(0, mountImage, %image, 0);
}
}
}
//Mount the correct image when the item is equipped
function ND_Item::onUse(%this, %player, %slot)
{
%image = %player.client.ndImage;
if(!isObject(%image))
%image = ND_Image;
%player.updateArm(%image);
%player.mountImage(%image, 0);
%player.client.ndEquippedFromItem = true;
}
package NewDuplicator_Server
{
//Start select mode when duplicator is equipped
function ND_Image::onMount(%this, %player, %slot)
{
parent::onMount(%this, %player, %slot);
%player.ndEquipped();
}
function ND_Image_Blue::onMount(%this, %player, %slot)
{
parent::onMount(%this, %player, %slot);
%player.ndEquipped();
}
function ND_Image_Box::onMount(%this, %player, %slot)
{
parent::onMount(%this, %player, %slot);
%player.ndEquipped();
}
//Cancel mode when duplicator is unequipped
function ND_Image::onUnMount(%this, %player, %slot)
{
parent::onUnMount(%this, %player, %slot);
%player.ndUnEquipped();
}
function ND_Image_Blue::onUnMount(%this, %player, %slot)
{
parent::onUnMount(%this, %player, %slot);
%player.ndUnEquipped();
}
function ND_Image_Box::onUnMount(%this, %player, %slot)
{
parent::onUnMount(%this, %player, %slot);
%player.ndUnEquipped();
}
};
//Start the swinging animation
function ND_Image::onPreFire(%this, %player, %slot)
{
%player.playThread(2, shiftTo);
}
function ND_Image_Blue::onPreFire(%this, %player, %slot)
{
%player.playThread(2, shiftTo);
}
function ND_Image_Box::onPreFire(%this, %player, %slot)
{
%player.playThread(2, shiftTo);
}
//Handle selecting things
function ND_Image::onFire(%this, %player, %slot)
{
%player.ndFired();
}
function ND_Image_Blue::onFire(%this, %player, %slot)
{
%player.ndFired();
}
function ND_Image_Box::onFire(%this, %player, %slot)
{
%player.ndFired();
}
//Duplicator was equipped
function Player::ndEquipped(%this)
{
%client = %this.client;
if(%this.isHoleBot || %this.isSlayerBot || !isObject(%client))
return;
if(%client.ndIgnoreNextMount)
{
%client.ndIgnoreNextMount = false;
return;
}
if($Pref::Server::ND::AdminOnly && !%client.isAdmin)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Oops! The duplicator is admin only.", 5);
return;
}
%client.ndEquipped = true;
//Remove temp brick so it doesn't overlap the selection box
if(isObject(%this.tempBrick))
%this.tempBrick.delete();
//Should resume last used select mode
if(!%client.ndModeIndex)
%client.ndSetMode(%client.ndLastSelectMode);
}
//Duplicator was unequipped
function Player::ndUnEquipped(%this)
{
%client = %this.client;
if(%this.isHoleBot || %this.isSlayerBot || !isObject(%client))
return;
if(%client.ndIgnoreNextMount)
return;
if(%client.ndModeIndex && !%client.ndMode.allowUnMount)
%client.ndKillMode();
%client.ndEquipped = false;
}
//Duplicator was fired
function Player::ndFired(%this)
{
%client = %this.client;
if(!isObject(%client) || !%client.ndModeIndex || !%client.ndMode.allowSelecting)
return;
if(isObject(%client.minigame) && !%client.minigame.enablebuilding)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Oops! Building is disabled.", 5);
return;
}
//Support for Script_RaycastOffTools by Conan
if(%this.isRaycastTool)
%mask = $TypeMasks::FxBrickObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType;
else
%mask = $TypeMasks::FxBrickAlwaysObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType;
%start = %this.getEyePoint();
%dir = %this.getEyeVector();
//Octree::Raycast fails to detect close bricks (~1TU) with a long raycast, so we'll do 3.
//First a very short one of 1 TU to detect very close bricks, then a slightly longer one
//of 10 TU, and finally the long range one of 1000.
%len[0] = 1;
%len[1] = 10;
%len[2] = 1000;
for(%i = 0; %i < 3; %i++)
{
%end = vectorAdd(%start, vectorScale(%dir, %len[%i]));
%ray = containerRaycast(%start, %end, %mask, %this);
if(isObject(%obj = firstWord(%ray)))
break;
}
if(!isObject(%obj))
return;
%position = posFromRaycast(%ray);
%normal = normalFromRaycast(%ray);
//Can't directly spawn an explosion, must use a projectile
%data = %client.ndImage.projectile;
if(!isObject(%data))
%data = ND_HitProjectile;
%proj = new Projectile()
{
datablock = %data;
initialPosition = %position;
initialVelocity = %normal;
};
//Pass on the selected object to the dupli mode
%client.ndMode.onSelectObject(%client, %obj, %position, %normal);
}
package NewDuplicator_Server
{
//Automatically start the "ambient" animation on duplicator items
function ND_Item::onAdd(%this, %obj)
{
parent::onAdd(%this, %obj);
%obj.playThread(0, ambient);
//Fix colorshift bullshit
%obj.schedule(100, setNodeColor, "ALL", %this.colorShiftColor);
}
//Prevent accidently unequipping the duplicator
function serverCmdUnUseTool(%client)
{
if(%client.ndLastEquipTime + 1.5 > $Sim::Time)
return;
if(%client.ndModeIndex == $NDM::StackSelect || %client.ndModeIndex == $NDM::BoxSelect)
{
%client.ndToolSchedule = %client.schedule(100, ndUnUseTool);
return;
}
parent::serverCmdUnUseTool(%client);
}
//Prevent creating ghost bricks in modes that allow un-mount
function BrickDeployProjectile::onCollision(%this, %obj, %col, %fade, %pos, %normal)
{
%client = %obj.client;
if(isObject(%client) && %client.ndModeIndex)
%client.ndMode.onSelectObject(%client, %col, %pos, %normal);
else
parent::onCollision(%this, %obj, %col, %fade, %pos, %normal);
}
//Handle ghost brick movements from New Brick Tool
function placeNewGhostBrick(%client, %pos, %normal, %noOrient)
{
if(!isObject(%client) || !%client.ndModeIndex)
return parent::placeNewGhostBrick(%client, %pos, %normal, %noOrient);
if(%client.ndModeIndex == $NDM::PlantCopy)
{
if(!%noOrient)
{
%angleID = getAngleIDFromPlayer(%client.getControlObject()) - %client.ndSelection.angleIDReference;
%rotation = ((4 - %angleID) - %client.ndSelection.ghostAngleID) % 4;
if(%rotation != 0)
%client.ndSelection.rotateGhostBricks(%rotation, %client.ndPivot);
}
return NDM_PlantCopy.moveBricksTo(%client, %pos, %normal);
}
%client.ndMode.onSelectObject(%client, 0, %pos, %normal);
}
};
//Fix for equipping paint can calling unUseTool
function GameConnection::ndUnUseTool(%this)
{
%player = %this.player;
if(%this.isTalking)
serverCmdStopTalking(%this);
if(!isObject(%player))
return;
%player.currTool = -1;
%this.currInv = -1;
%this.currInvSlot = -1;
%player.unmountImage(0);
%player.playThread(1, "root");
}