initial commit

This commit is contained in:
Redo
2022-10-05 16:02:11 -06:00
commit 93d385e859
51 changed files with 11722 additions and 0 deletions

View File

@ -0,0 +1,462 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch to this mode
function NDM_BoxSelect::onStartMode(%this, %client, %lastMode)
{
if(%lastMode == $NDM::StackSelect)
{
if(isObject(%client.ndSelection) && %client.ndSelection.brickCount)
{
//Create selection box from the size of the previous selection
%root = %client.ndSelection.rootPosition;
%min = vectorAdd(%root, %client.ndSelection.minSize);
%max = vectorAdd(%root, %client.ndSelection.maxSize);
if(%client.isAdmin)
%limit = $Pref::Server::ND::MaxBoxSizeAdmin;
else
%limit = $Pref::Server::ND::MaxBoxSizePlayer;
if((getWord(%max, 0) - getWord(%min, 0) <= %limit)
&& (getWord(%max, 1) - getWord(%min, 1) <= %limit)
&& (getWord(%max, 2) - getWord(%min, 2) <= %limit))
{
%name = %client.name;
if(getSubStr(%name, strLen(%name - 1), 1) $= "s")
%shapeName = %name @ "' Selection Box";
else
%shapeName = %name @ "'s Selection Box";
%client.ndSelectionBox = ND_SelectionBox(%shapeName);
%client.ndSelectionBox.setSizeAligned(%min, %max, %client.getControlObject());
}
else
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Oops!\n<font:Verdana:17>" @
"\c6Your selection box is limited to \c3" @ mFloor(%limit * 2) @ " \c6studs.", 5);
%client.ndSelection.deleteData();
}
%client.ndSelectionAvailable = false;
}
else if(%lastMode == $NDM::BoxSelectProgress && %client.ndSelection.brickCount > 0)
{
%client.ndSelectionBox.setDisabledMode();
%client.ndSelectionAvailable = true;
}
else if(%lastMode != $NDM::FillColor && %lastMode != $NDM::WrenchProgress)
%client.ndSelectionAvailable = false;
%client.ndLastSelectMode = %this;
%client.ndUpdateBottomPrint();
}
//Switch away from this mode
function NDM_BoxSelect::onChangeMode(%this, %client, %nextMode)
{
if(%nextMode == $NDM::StackSelect)
{
//Clear selection
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
else if(%nextMode == $NDM::PlantCopy)
{
//Start de-highlighting the bricks
%client.ndSelection.deHighlight();
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
else if(%nextMode == $NDM::CutProgress)
{
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
else if(%nextMode == $NDM::FillColor)
{
//Start de-highlighting the bricks
%client.ndSelection.deHighlight();
}
else if(%nextMode == $NDM::WrenchProgress)
{
//Start de-highlighting the bricks
%client.ndSelection.deHighlight();
}
else if(%nextMode == $NDM::LoadProgress)
{
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
}
//Kill this mode
function NDM_BoxSelect::onKillMode(%this, %client)
{
//Destroy selection
if(isObject(%client.ndSelection))
%client.ndSelection.delete();
//Delete the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
//Duplicator image callbacks
///////////////////////////////////////////////////////////////////////////
//Selecting an object with the duplicator
function NDM_BoxSelect::onSelectObject(%this, %client, %obj, %pos, %normal)
{
if((%obj.getType() & $TypeMasks::FxBrickAlwaysObjectType) == 0)
return;
if(!ndTrustCheckMessage(%obj, %client))
return;
if(%client.ndSelectionAvailable)
{
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Selection canceled! " @
"You can now edit the box again.", 5);
%client.ndSelectionAvailable = false;
%client.ndSelection.deleteData();
%client.ndSelectionBox.setNormalMode();
%client.ndUpdateBottomPrint();
}
if(isObject(%client.ndSelectionBox))
{
if(%client.ndMultiSelect)
{
%box1 = %client.ndSelectionBox.getWorldBox();
//%box2 = ndGetPlateBoxFromRayCast(%pos, %normal);
%box2 = %obj.getWorldBox();
%p1 = getMin(getWord(%box1, 0), getWord(%box2, 0))
SPC getMin(getWord(%box1, 1), getWord(%box2, 1))
SPC getMin(getWord(%box1, 2), getWord(%box2, 2));
%p2 = getMax(getWord(%box1, 3), getWord(%box2, 3))
SPC getMax(getWord(%box1, 4), getWord(%box2, 4))
SPC getMax(getWord(%box1, 5), getWord(%box2, 5));
}
else
{
%box = %obj.getWorldBox();
%p1 = getWords(%box, 0, 2);
%p2 = getWords(%box, 3, 5);
}
}
else
{
%name = %client.name;
if(getSubStr(%name, strLen(%name - 1), 1) $= "s")
%shapeName = %name @ "' Selection Box";
else
%shapeName = %name @ "'s Selection Box";
%client.ndSelectionBox = ND_SelectionBox(%shapeName);
// if(%client.ndMultiSelect)
// %box = ndGetPlateBoxFromRayCast(%pos, %normal);
// else
%box = %obj.getWorldBox();
%p1 = getWords(%box, 0, 2);
%p2 = getWords(%box, 3, 5);
}
%client.ndSelectionBox.setSizeAligned(%p1, %p2, %client.getControlObject());
%client.ndUpdateBottomPrint();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Light key
function NDM_BoxSelect::onLight(%this, %client)
{
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(lightOffSound);
%client.ndSetMode(NDM_StackSelect);
}
//Prev Seat
function NDM_BoxSelect::onPrevSeat(%this, %client)
{
%client.ndLimited = !%client.ndLimited;
%client.ndUpdateBottomPrint();
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(%client.ndLimited ? lightOnSound : lightOffSound);
}
//Shift Brick
function NDM_BoxSelect::onShiftBrick(%this, %client, %x, %y, %z)
{
if(!isObject(%client.ndSelectionBox))
return;
//If we have a selection, enter plant mode!
if(%client.ndSelectionAvailable)
{
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onShiftBrick(%client, %x, %y, %z);
return;
}
//Move the corner
switch(getAngleIDFromPlayer(%client.getControlObject()))
{
case 0: %newX = %x; %newY = %y;
case 1: %newX = -%y; %newY = %x;
case 2: %newX = -%x; %newY = -%y;
case 3: %newX = %y; %newY = -%x;
}
%newX = mFloor(%newX) / 2;
%newY = mFloor(%newY) / 2;
%z = mFloor(%z ) / 5;
if(!%client.ndMultiSelect)
{
if(%client.isAdmin)
%limit = $Pref::Server::ND::MaxBoxSizeAdmin;
else
%limit = $Pref::Server::ND::MaxBoxSizePlayer;
if(%client.ndSelectionBox.shiftCorner(%newX SPC %newY SPC %z, %limit))
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Oops!\n<font:Verdana:17>" @
"\c6Your selection box is limited to \c3" @ mFloor(%limit * 2) @ " \c6studs.", 5);
%client.ndUpdateBottomPrint();
}
else
{
%client.ndSelectionBox.shift(%newX SPC %newY SPC %z);
}
}
//Super Shift Brick
function NDM_BoxSelect::onSuperShiftBrick(%this, %client, %x, %y, %z)
{
//If we have a selection, enter plant mode!
if(%client.ndSelectionAvailable)
{
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onSuperShiftBrick(%client, %x, %y, %z);
return;
}
%this.onShiftBrick(%client, %x * 8, %y * 8, %z * 20);
}
//Rotate Brick
function NDM_BoxSelect::onRotateBrick(%this, %client, %direction)
{
if(!isObject(%client.ndSelectionBox))
return;
//If we have a selection, enter plant mode!
if(%client.ndSelectionAvailable)
{
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onRotateBrick(%client, %direction);
return;
}
if(!%client.ndMultiSelect)
%client.ndSelectionBox.switchCorner();
else
{
%client.ndSelectionBox.rotate(%direction);
%client.ndUpdateBottomPrint();
}
}
//Plant Brick
function NDM_BoxSelect::onPlantBrick(%this, %client)
{
if(!isObject(%client.ndSelectionBox))
return;
//If we have a selection, enter plant mode!
if(%client.ndSelectionAvailable)
{
%client.ndSetMode(NDM_PlantCopy);
return;
}
//Check timeout
if(!%client.isAdmin && %client.ndLastSelectTime + ($Pref::Server::ND::SelectTimeoutMS / 1000) > $Sim::Time)
{
%remain = mCeil(%client.ndLastSelectTime + ($Pref::Server::ND::SelectTimeoutMS / 1000) - $Sim::Time);
if(%remain != 1)
%s = "s";
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6You need to wait\c3 " @
%remain @ "\c6 second" @ %s @ " before selecting again!", 5);
return;
}
%client.ndLastSelectTime = $Sim::Time;
//Prepare a selection to copy the bricks
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
else
%client.ndSelection = ND_Selection(%client);
//Start selection
%box = %client.ndSelectionBox.getWorldBox();
%client.ndSetMode(NDM_BoxSelectProgress);
%client.ndSelection.startBoxSelection(%box, %client.ndLimited);
}
//Cancel Brick
function NDM_BoxSelect::onCancelBrick(%this, %client)
{
if(!isObject(%client.ndSelectionBox))
return;
if(%client.ndSelectionAvailable)
{
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Selection canceled! " @
"You can now edit the box again.", 5);
%client.ndSelectionAvailable = false;
%client.ndSelection.deleteData();
%client.ndSelectionBox.setNormalMode();
%client.ndUpdateBottomPrint();
return;
}
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
%client.ndSelectionBox.delete();
%client.ndSelectionAvailable = false;
%client.ndUpdateBottomPrint();
}
//Copy Selection
function NDM_BoxSelect::onCopy(%this, %client)
{
%this.onPlantBrick(%client);
}
//Cut Selection
function NDM_BoxSelect::onCut(%this, %client)
{
if(!isObject(%client.ndSelectionBox))
return;
if(!%client.ndSelectionAvailable)
{
%this.onPlantBrick(%client);
return;
}
%client.ndSetMode(NDM_CutProgress);
%client.ndSelection.startCutting();
}
//Supercut selection
function NDM_BoxSelect::onSuperCut(%this, %client)
{
if(!isObject(%client.ndSelectionBox))
return;
//Prepare a selection to handle the callback
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
else
%client.ndSelection = ND_Selection(%client);
if(!$ND::SimpleBrickTableCreated)
ndCreateSimpleBrickTable();
//Start supercut
%box = %client.ndSelectionBox.getWorldBox();
%client.ndSetMode(NDM_SuperCutProgress);
%client.ndSelection.startSuperCut(%box);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_BoxSelect::getBottomPrint(%this, %client)
{
if(isObject(%client.ndSelection) && %client.ndSelection.brickCount)
{
%count = %client.ndSelection.brickCount;
%title = "Selection Mode (\c3" @ %count @ "\c6 Brick" @ (%count > 1 ? "s)" : ")");
}
else
%title = "Selection Mode";
%l0 = "Type: \c3Box \c6[Light]";
%l1 = "Limited: " @ (%client.ndLimited ? "\c3Yes" : "\c0No") @ " \c6[Prev Seat]";
if(isObject(%client.ndSelectionBox))
{
%size = %client.ndSelectionBox.getSize();
%x = mFloatLength(getWord(%size, 0) * 2, 0);
%y = mFloatLength(getWord(%size, 1) * 2, 0);
%z = mFloatLength(getWord(%size, 2) * 5, 0);
%l2 = "Size: \c3" @ %x @ "\c6 x \c3" @ %y @ "\c6 x \c3" @ %z @ "\c6 Plates";
}
if(!isObject(%client.ndSelectionBox))
{
%r0 = "Click Brick: Place selection box";
%r1 = "";
%r2 = "";
}
else if(!%client.ndSelectionAvailable)
{
%r0 = "[Shift Brick]: Move corner";
%r1 = "[Rotate Brick]: Switch corner";
}
else
{
%r0 = "[Cancel Brick]: Adjust box";
%r1 = "[Plant Brick]: Duplicate";
}
return ndFormatMessage(%title, %l0, %r0, %l1, %r1, %l2, %r2);
}

View File

@ -0,0 +1,59 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_BoxSelectProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
//Remove selection box
%client.ndSelectionBox.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_BoxSelectProgress::onCancelBrick(%this, %client)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Selection canceled!", 4);
%client.ndSelection.cancelBoxSelection();
%client.ndSetMode(NDM_BoxSelect);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_BoxSelectProgress::getBottomPrint(%this, %client)
{
%qCount = %client.ndSelection.queueCount;
%bCount = %client.ndSelection.brickCount;
if(%bCount <= 0)
{
%curr = %client.ndSelection.currChunk + 1;
%num = %client.ndSelection.numChunks;
%percent = mFloor(%curr * 100 / %num);
%title = "Searching... (\c3" @ %percent @ "%\c6, \c3" @ %qCount @ "\c6 Bricks)";
}
else
{
%percent = mFloor(%bCount * 100 / %qCount);
%title = "Processing... (\c3" @ %percent @ "%\c6)";
}
%l0 = "[Cancel Brick]: Cancel selection";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,48 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch away from this mode
function NDM_CutProgress::onChangeMode(%this, %client, %nextMode)
{
if(%nextMode != $NDM::PlantCopy)
%client.ndSelection.deleteData();
}
//Kill this mode
function NDM_CutProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_CutProgress::onCancelBrick(%this, %client)
{
%client.ndSelection.cancelCutting();
%client.ndSetMode(%client.ndLastSelectMode);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_CutProgress::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%percent = mFloor(%client.ndSelection.cutIndex * 100 / %count);
%title = "Cutting... (\c3" @ %percent @ "%\c6)";
%l0 = "[Cancel Brick]: Cancel cut";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,128 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch to this mode
function NDM_FillColor::onStartMode(%this, %client, %lastMode)
{
%client.ndUpdateBottomPrint();
cancel(%client.ndToolSchedule);
}
//Switch away from this mode
function NDM_FillColor::onChangeMode(%this, %client, %nextMode)
{
//Hide paint gui
if(%nextMode != $NDM::FillColorProgress)
{
%client.ndLastEquipTime = $Sim::Time;
if(%client.ndEquippedFromItem)
commandToClient(%client, 'setScrollMode', 2);
else
commandToClient(%client, 'setScrollMode', 3);
}
}
//Kill this mode
function NDM_FillColor::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Plant Brick
function NDM_FillColor::onPlantBrick(%this, %client)
{
//Admin limit
if($Pref::Server::ND::PaintAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Paint Mode is admin only. Ask an admin for help.");
return;
}
//Normal colors
if(%client.currentFxColor $= "")
{
%client.ndSetMode(NDM_FillColorProgress);
%client.ndSelection.startFillColor(0, %client.currentColor);
return;
}
//Admin limit
if($Pref::Server::ND::PaintFxAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Paint Fx Mode is admin only. Ask an admin for help.");
return;
}
%client.ndSetMode(NDM_FillColorProgress);
if(%client.currentFxColor < 7)
%client.ndSelection.startFillColor(1, %client.currentFxColor);
else
%client.ndSelection.startFillColor(2, %client.currentFxColor - 7);
}
//Cancel Brick
function NDM_FillColor::onCancelBrick(%this, %client)
{
%client.ndSetMode(%client.ndLastSelectMode);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_FillColor::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%title = "Paint Mode (\c3" @ %count @ "\c6 Brick" @ (%count > 1 ? "s)" : ")");
if(%client.currentFxColor !$= "")
{
switch(%client.currentFxColor)
{
case 0: %color = "\c3Fx - None";
case 1: %color = "\c3Fx - Pearl";
case 2: %color = "\c3Fx - Chrome";
case 3: %color = "\c3Fx - Glow";
case 4: %color = "\c3Fx - Blink";
case 5: %color = "\c3Fx - Swirl";
case 6: %color = "\c3Fx - Rainbow";
case 7: %color = "\c3Fx - Stable";
case 8: %color = "\c3Fx - Undulo";
}
}
else
{
%color = "<font:impact:20>" @ ndGetPaintColorCode(%client.currentColor) @ "|||||<font:Verdana:16>\c3";
%alpha = mFloor(100 * getWord(getColorIdTable(%client.currentColor), 3));
if(%alpha != 100)
%color = %color SPC %alpha @ "%";
}
%l0 = "Select paint can to chose color";
%l1 = "Color: " @ %color;
%r0 = "[Plant Brick]: Paint bricks";
%r1 = "[Cancel Brick]: Exit mode";
return ndFormatMessage(%title, %l0, %r0, %l1, %r1, %l2);
}

View File

@ -0,0 +1,41 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_FillColorProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_FillColorProgress::onCancelBrick(%this, %client)
{
%client.ndSelection.cancelFillColor();
%client.ndSetMode(NDM_FillColor);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_FillColorProgress::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%percent = mFloor(%client.ndSelection.paintIndex * 100 / %count);
%title = "Painting... (\c3" @ %percent @ "%\c6)";
%l0 = "[Cancel Brick]: Cancel painting";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,76 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch to this mode
function NDM_LoadProgress::onStartMode(%this, %client, %lastMode)
{
//Prepare selection to load data into
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
else
%client.ndSelection = ND_Selection(%client);
}
//Kill this mode
function NDM_LoadProgress::onKillMode(%this, %client)
{
//Destroy selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_LoadProgress::onCancelBrick(%this, %client)
{
%client.ndSelection.cancelLoading();
%client.ndSelection.delete();
%client.ndSetMode(%client.ndLastSelectMode);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_LoadProgress::getBottomPrint(%this, %client)
{
if(%client.ndSelection.loadStage == 0)
{
%count = %client.ndSelection.loadExpectedBrickCount;
if(%count != 0)
{
%percent = mFloor(%client.ndSelection.brickCount * 100 / %count);
%title = "Loading Bricks... (\c3" @ %percent @ "%\c6)";
}
else
%title = "Loading Bricks... (\c3" @ %client.ndSelection.brickCount @ "\c6 Bricks)";
}
else
{
%count = %client.ndSelection.loadExpectedConnectionCount;
if(%count != 0)
{
%percent = mFloor(%client.ndSelection.connectionCount * 100 / %count);
%title = "Loading Connections... (\c3" @ %percent @ "%\c6)";
}
else
%title = "Loading Connections... (\c3" @ %client.ndSelection.connectionCount @ "\c6 Connections)";
}
%l0 = "[Cancel Brick]: Cancel loading";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,268 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch to this mode
function NDM_PlantCopy::onStartMode(%this, %client, %lastMode)
{
if(%lastMode == $NDM::StackSelect
|| %lastMode == $NDM::BoxSelect
|| %lastMode == $NDM::CutProgress
|| %lastMode == $NDM::LoadProgress)
{
%client.ndSelection.spawnGhostBricks(%client.ndSelection.rootPosition, 0);
%client.ndSelection.angleIdReference = getAngleIDFromPlayer(%client.getControlObject());
}
%client.ndUpdateBottomPrint();
}
//Switch away from this mode
function NDM_PlantCopy::onChangeMode(%this, %client, %nextMode)
{
if(%nextMode == $NDM::StackSelect || %nextMode == $NDM::BoxSelect)
{
%client.ndSelection.deleteData();
}
}
//Kill this mode
function NDM_PlantCopy::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
}
//Duplicator image callbacks
///////////////////////////////////////////////////////////////////////////
//Selecting an object with the duplicator
function NDM_PlantCopy::onSelectObject(%this, %client, %obj, %pos, %normal)
{
%this.moveBricksTo(%client, %pos, %normal);
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Prev Seat
function NDM_PlantCopy::onPrevSeat(%this, %client)
{
%client.ndPivot = !%client.ndPivot;
%client.ndUpdateBottomPrint();
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(%client.ndPivot ? lightOnSound : lightOffSound);
}
//Shift Brick
function NDM_PlantCopy::onShiftBrick(%this, %client, %x, %y, %z)
{
switch(getAngleIDFromPlayer(%client.getControlObject()))
{
case 0: %newX = %x; %newY = %y;
case 1: %newX = -%y; %newY = %x;
case 2: %newX = -%x; %newY = -%y;
case 3: %newX = %y; %newY = -%x;
}
%client.ndSelection.shiftGhostBricks(%newX / 2 SPC %newY / 2 SPC %z / 5);
}
//Super Shift Brick
function NDM_PlantCopy::onSuperShiftBrick(%this, %client, %x, %y, %z)
{
switch(getAngleIDFromPlayer(%client.getControlObject()))
{
case 0: %newX = %x; %newY = %y;
case 1: %newX = -%y; %newY = %x;
case 2: %newX = -%x; %newY = -%y;
case 3: %newX = %y; %newY = -%x;
}
if(%client.ndPivot)
%box = %client.ndSelection.getGhostWorldBox();
else
%box = %client.ndSelection.ghostGroup.getObject(0).getWorldBox();
%newX *= (getWord(%box, 3) - getWord(%box, 0));
%newy *= (getWord(%box, 4) - getWord(%box, 1));
%z *= (getWord(%box, 5) - getWord(%box, 2));
%client.ndSelection.shiftGhostBricks(%newX SPC %newY SPC %z);
}
//Rotate Brick
function NDM_PlantCopy::onRotateBrick(%this, %client, %direction)
{
%client.ndSelection.rotateGhostBricks(%direction, %client.ndPivot);
}
//Plant Brick
function NDM_PlantCopy::onPlantBrick(%this, %client)
{
//Check force plant
if(%client.ndForcePlant)
{
if($Pref::Server::ND::FloatAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Force Plant has been disabled because it is admin only. Ask an admin for help.");
%client.ndForcePlant = false;
}
}
%this.conditionalPlant(%client, %client.ndForcePlant);
}
//Cancel Brick
function NDM_PlantCopy::onCancelBrick(%this, %client)
{
if(%client.ndEquipped)
%client.ndSetMode(%client.ndLastSelectMode);
else
%client.ndKillMode();
}
//Paste Selection
function NDM_PlantCopy::onPaste(%this, %client)
{
%this.onPlantBrick(%client);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_PlantCopy::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%size = vectorSub(%client.ndSelection.maxSize, %client.ndSelection.minSize);
%x = mFloor(getWord(%size, 0) * 2);
%y = mFloor(getWord(%size, 1) * 2);
%z = mFloor(getWord(%size, 2) * 5);
if(%count == 1)
%title = "Plant Mode (\c31\c6 Brick)";
else if(%count <= $Pref::Server::ND::MaxGhostBricks)
%title = "Plant Mode (\c3" @ %count @ "\c6 Bricks)";
else
%title = "Plant Mode (\c3" @ %count @ "\c6 Bricks, \c3" @ mFloor($Pref::Server::ND::MaxGhostBricks * 100 / %count) @ "%\c6 Ghosted)";
%l0 = "Pivot: \c3" @ (%client.ndPivot ? "Whole Selection" : "Start Brick") @ "\c6 [Prev Seat]";
if(isObject(%client.ndSelection.targetGroup))
%l1 = "Planting as: \c3" @ %client.ndSelection.targetGroup.name;
else
%l1 = "Size: \c3" @ %x @ "\c6 x \c3" @ %y @ "\c6 x \c3" @ %z @ "\c6 Plates";
%r0 = "Use normal ghost brick controls";
%r1 = "[Cancel Brick] to exit plant mode";
return ndFormatMessage(%title, %l0, %r0, %l1, %r1);
}
//Functions
///////////////////////////////////////////////////////////////////////////
//Move the bricks to a specific location, like with the brick tool
function NDM_PlantCopy::moveBricksTo(%his, %client, %pos, %normal)
{
//Get half size of world box for offset
if(%client.ndPivot)
%box = %client.ndSelection.getGhostWorldBox();
else
%box = %client.ndSelection.ghostGroup.getObject(0).getWorldBox();
%halfSize = vectorScale(vectorSub(getWords(%box, 3, 5), getWords(%box, 0, 2)), 0.5);
//Point offset in correct direction based on normal
%offX = getWord(%halfSize, 0) * mFloatLength(getWord(%normal, 0), 0);
%offY = getWord(%halfSize, 1) * mFloatLength(getWord(%normal, 1), 0);
%offZ = getWord(%halfSize, 2) * mFloatLength(getWord(%normal, 2), 0);
%offset = %offX SPC %offY SPC %offZ;
//Get shift vector
%pos = vectorSub(vectorAdd(%pos, %offset), %client.ndSelection.ghostPosition);
if(%client.ndPivot)
{
%toCenter = %client.ndSelection.rootToCenter;
//Apply mirror
if(%client.ndSelection.ghostMirrorX)
%toCenter = -firstWord(%toCenter) SPC restWords(%toCenter);
else if(%client.ndSelection.ghostMirrorY)
%toCenter = getWord(%toCenter, 0) SPC -getWord(%toCenter, 1) SPC getWord(%toCenter, 2);
if(%client.ndSelection.ghostMirrorZ)
%toCenter = getWord(%toCenter, 0) SPC getWord(%toCenter, 1) SPC -getWord(%toCenter, 2);
%pos = vectorSub(%pos, ndRotateVector(%toCenter, %client.ndSelection.ghostAngleID));
}
%client.ndSelection.shiftGhostBricks(%pos);
//Offset required for New Brick Tool to display the tracer shape correctly
if(%client.ndPivot)
return vectorSub(%client.ndSelection.getGhostCenter(), %offset);
else
return vectorSub(%client.ndSelection.ghostGroup.getObject(0).getWorldBoxCenter(), %offset);
}
//Check time limit and attempt to plant bricks
function NDM_PlantCopy::conditionalPlant(%this, %client, %force)
{
//Check timeout
if(!%client.isAdmin && %client.ndLastPlantTime + ($Pref::Server::ND::PlantTimeoutMS / 1000) > $Sim::Time)
{
%remain = mCeil(%client.ndLastPlantTime + ($Pref::Server::ND::PlantTimeoutMS / 1000) - $Sim::Time);
if(%remain != 1)
%s = "s";
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6You need to wait\c3 " @ %remain @ "\c6 second" @ %s @ " before planting again!", 5);
return;
}
//Check too far distance
%offset = vectorSub(%client.ndSelection.getGhostCenter(), %client.getControlObject().position);
if(vectorLen(%offset) > $Pref::Server::TooFarDistance)
{
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6You can't plant so far away!", 5);
return;
}
//Validate target group
if(isObject(%client.ndSelection.targetGroup) &&
getTrustLevel(%client, %client.ndSelection.targetGroup) < 1 &&
(!%client.isAdmin || !$Pref::Server::ND::AdminTrustBypass2))
{
messageClient(%client, '', "\c6You need build trust with \c3"
@ %client.ndSelection.targetGroup.name @ "\c6 to plant bricks in their group.");
return;
}
%client.ndLastPlantTime = $Sim::Time;
%pos = %client.ndSelection.ghostPosition;
%ang = %client.ndSelection.ghostAngleID;
%client.ndSetMode(NDM_PlantCopyProgress);
%client.ndSelection.startPlant(%pos, %ang, %force);
}

View File

@ -0,0 +1,62 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_PlantCopyProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_PlantCopyProgress::onCancelBrick(%this, %client)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Planting canceled!", 4);
%client.ndSelection.cancelPlanting();
%client.ndSetMode(NDM_PlantCopy);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_PlantCopyProgress::getBottomPrint(%this, %client)
{
%qIndex = %client.ndSelection.plantQueueIndex;
%qCount = %client.ndSelection.plantQueueCount;
%count = %client.ndSelection.brickCount;
%planted = %client.ndSelection.plantSuccessCount;
if(%qIndex == %qCount)
{
//Searching for a brick
%pIndex = %client.ndSelection.plantSearchIndex;
%percent = mFloor(%client.ndSelection.plantSearchIndex * 100 / %count);
%title = "Finding Next Brick... (\c3" @ %percent @ "%\c6, \c3" @ %planted @ "\c6 planted)";
}
else
{
//Planting bricks
%failed = %client.ndSelection.plantTrustFailCount + %client.ndSelection.plantBlockedFailCount;
%percent = mFloor(%planted * 100 / %count);
%title = "Planting... (\c3" @ %percent @ "%\c6, \c3" @ %failed @ "\c6 failed)";
}
%l0 = "[Cancel Brick]: Cancel planting";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,43 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_SaveProgress::onKillMode(%this, %client)
{
//Destroy selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_SaveProgress::onCancelBrick(%this, %client)
{
%client.ndSelection.cancelSaving();
%client.ndSetMode(NDM_PlantCopy);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_SaveProgress::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%index = %client.ndSelection.saveIndex / 2 + %client.ndSelection.saveStage * %count / 2;
%percent = mFloor(%index * 100 / %count);
%title = "Saving Selection... (\c3" @ %percent @ "%\c6)";
%l0 = "[Cancel Brick]: Cancel saving";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,210 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Switch to this mode
function NDM_StackSelect::onStartMode(%this, %client, %lastMode)
{
%client.ndLastSelectMode = %this;
%client.ndUpdateBottomPrint();
}
//Switch away from this mode
function NDM_StackSelect::onChangeMode(%this, %client, %nextMode)
{
if(%nextMode == $NDM::FillColor
|| %nextMode == $NDM::PlantCopy
|| %nextMode == $NDM::WrenchProgress)
{
//Start de-highlighting the bricks
%client.ndSelection.deHighlight();
}
//The transition to box select mode will be
//handled in NDM_BoxSelect::onStartMode
}
//Kill this mode
function NDM_StackSelect::onKillMode(%this, %client)
{
//Destroy selection
if(isObject(%client.ndSelection))
%client.ndSelection.delete();
}
//Duplicator image callbacks
///////////////////////////////////////////////////////////////////////////
//Selecting an object with the duplicator
function NDM_StackSelect::onSelectObject(%this, %client, %obj, %pos, %normal)
{
if((%obj.getType() & $TypeMasks::FxBrickAlwaysObjectType) == 0)
return;
//Check timeout
if(!%client.isAdmin && %client.ndLastSelectTime + ($Pref::Server::ND::SelectTimeoutMS / 1000) > $Sim::Time)
{
%remain = mCeil(%client.ndLastSelectTime + ($Pref::Server::ND::SelectTimeoutMS / 1000) - $Sim::Time);
if(%remain != 1)
%s = "s";
messageClient(%client, 'MsgError', "");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6You need to wait\c3 " @
%remain @ "\c6 second" @ %s @ " before selecting again!", 5);
return;
}
%client.ndLastSelectTime = $Sim::Time;
if(!ndTrustCheckMessage(%obj, %client))
return;
//Prepare selection to copy the bricks
if(!isObject(%client.ndSelection))
%client.ndSelection = ND_Selection(%client);
//Start selection
%client.ndSetMode(NDM_StackSelectProgress);
if(%client.ndMultiSelect)
%client.ndSelection.startStackSelectionAdditive(%obj, %client.ndDirection, %client.ndLimited);
else
%client.ndSelection.startStackSelection(%obj, %client.ndDirection, %client.ndLimited);
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Light key
function NDM_StackSelect::onLight(%this, %client)
{
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(lightOnSound);
%client.ndSetMode(NDM_BoxSelect);
}
//Next Seat
function NDM_StackSelect::onNextSeat(%this, %client)
{
%client.ndDirection = !%client.ndDirection;
%client.ndUpdateBottomPrint();
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(%client.ndDirection ? lightOnSound : lightOffSound);
}
//Prev Seat
function NDM_StackSelect::onPrevSeat(%this, %client)
{
%client.ndLimited = !%client.ndLimited;
%client.ndUpdateBottomPrint();
if($Pref::Server::ND::PlayMenuSounds)
%client.play2d(%client.ndLimited ? lightOnSound : lightOffSound);
}
//Shift Brick
function NDM_StackSelect::onShiftBrick(%this, %client, %x, %y, %z)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
return;
//Change to plant mode and apply the shift
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onShiftBrick(%client, %x, %y, %z);
}
//Super Shift Brick
function NDM_StackSelect::onSuperShiftBrick(%this, %client, %x, %y, %z)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
return;
//Change to plant mode and apply the shift
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onSuperShiftBrick(%client, %x, %y, %z);
}
//Rotate Brick
function NDM_StackSelect::onRotateBrick(%this, %client, %dir)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
return;
//Change to plant mode and apply the shift
%client.ndSetMode(NDM_PlantCopy);
NDM_PlantCopy.onRotateBrick(%client, %dir);
}
//Plant Brick
function NDM_StackSelect::onPlantBrick(%this, %client)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
return;
%client.ndSetMode(NDM_PlantCopy);
}
//Cancel Brick
function NDM_StackSelect::onCancelBrick(%this, %client)
{
if(isObject(%client.ndSelection))
%client.ndSelection.deleteData();
%client.ndUpdateBottomPrint();
}
//Copy Selection
function NDM_StackSelect::onCopy(%this, %client)
{
%this.onPlantBrick(%client);
}
//Cut Selection
function NDM_StackSelect::onCut(%this, %client)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
return;
%client.ndSetMode(NDM_CutProgress);
%client.ndSelection.startCutting();
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_StackSelect::getBottomPrint(%this, %client)
{
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
{
%title = "Selection Mode";
%r0 = "Click Brick: Select stack " @ (%client.ndDirection ? "up" : "down");
%r1 = "";
}
else
{
%count = %client.ndSelection.brickCount;
%title = "Selection Mode (\c3" @ %count @ "\c6 Brick" @ (%count > 1 ? "s)" : ")");
%r0 = "Ctrl-Click Brick: Multiselect";
%r1 = "[Plant Brick]: Duplicate";
}
%l0 = "Type: \c3" @ (%client.ndMultiSelect ? "Multi-" : "") @ "Stack \c6[Light]";
%l1 = "Limited: " @ (%client.ndLimited ? "\c3Yes" : "\c0No") @ " \c6[Prev Seat]";
%l2 = "Direction: \c3" @ (%client.ndDirection ? "Up" : "Down") @ " \c6[Next Seat]";
return ndFormatMessage(%title, %l0, %r0, %l1, %r1, %l2);
}

View File

@ -0,0 +1,43 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_StackSelectProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_StackSelectProgress::onCancelBrick(%this, %client)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Selection canceled!", 4);
%client.ndSelection.cancelStackSelection();
%client.ndSetMode(NDM_StackSelect);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_StackSelectProgress::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%qCount = %client.ndSelection.queueCount - %count;
%title = "Selecting... (\c3" @ %count @ "\c6 Bricks, \c3" @ %qCount @ "\c6 in Queue)";
%l0 = "[Cancel Brick]: Cancel selection";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,50 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_SuperCutProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
//Remove selection box
%client.ndSelectionBox.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_SuperCutProgress::onCancelBrick(%this, %client)
{
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Supercut canceled!", 4);
%client.ndSelection.cancelSuperCut();
%client.ndSetMode(NDM_BoxSelect);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_SuperCutProgress::getBottomPrint(%this, %client)
{
%curr = %client.ndSelection.currChunk + 1;
%num = %client.ndSelection.numChunks;
%percent = mFloor(%curr * 100 / %num);
%deleted = %client.ndSelection.superCutCount;
%planted = %client.ndSelection.superCutPlacedCount;
%title = "Supercut in progress... (\c3" @ %percent @ "%\c6, \c3" @ %deleted @ "\c6 deleted, \c3" @ %planted @ "\c6 planted)";
%l0 = "[Cancel Brick]: Cancel supercut";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,45 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Changing modes
///////////////////////////////////////////////////////////////////////////
//Kill this mode
function NDM_WrenchProgress::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
//Remove the selection box
if(isObject(%client.ndSelectionBox))
%client.ndSelectionBox.delete();
}
//Generic inputs
///////////////////////////////////////////////////////////////////////////
//Cancel Brick
function NDM_WrenchProgress::onCancelBrick(%this, %client)
{
%client.ndSelection.cancelFillWrench();
%client.ndSetMode(%client.ndLastSelectMode);
}
//Interface
///////////////////////////////////////////////////////////////////////////
//Create bottomprint for client
function NDM_WrenchProgress::getBottomPrint(%this, %client)
{
%count = %client.ndSelection.brickCount;
%percent = mFloor(%client.ndSelection.wrenchIndex * 100 / %count);
%title = "Applying... (\c3" @ %percent @ "%\c6)";
%l0 = "[Cancel Brick]: Cancel";
return ndFormatMessage(%title, %l0);
}

View File

@ -0,0 +1,38 @@
// Deletes large numbers of ghost bricks without causing lag.
// -------------------------------------------------------------------
//Create a new ghost group
function ND_GhostGroup()
{
ND_ServerGroup.add(
%this = new ScriptGroup(ND_GhostGroup)
);
return %this;
}
//Delete some of the bricks in this group
function ND_GhostGroup::tickDelete(%this)
{
%max = $Pref::Server::ND::ProcessPerTick;
%bricks = getBrickCount();
//Deleting objects causes increasing lag with more bricks in total
if(%bricks > 450000)
%max /= 6;
else if(%bricks > 300000)
%max /= 4;
else if(%bricks > 150000)
%max /= 2;
if(%this.getCount() <= %max)
{
%this.delete();
return;
}
for(%i = 0; %i < %max; %i++)
%this.getObject(0).delete();
%this.schedule(30, tickDelete);
}

View File

@ -0,0 +1,112 @@
// Resizable highlight box to visualize the size of the selection.
// -------------------------------------------------------------------
//Create a new highlight box
function ND_HighlightBox()
{
ND_ServerGroup.add(
%this = new ScriptObject(ND_HighlightBox)
);
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_y[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_z[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_x[%i].setScopeAlways();
%this.border_y[%i].setScopeAlways();
%this.border_z[%i].setScopeAlways();
}
%this.color = "1 0.84 0 0.99";
%this.applyColors();
return %this;
}
//Destroy static shapes when highlight box is removed
function ND_HighlightBox::onRemove(%this)
{
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].delete();
%this.border_y[%i].delete();
%this.border_z[%i].delete();
}
}
//Apply color changes to the highlight box
function ND_HighlightBox::applyColors(%this)
{
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].setNodeColor("ALL", %this.color);
%this.border_y[%i].setNodeColor("ALL", %this.color);
%this.border_z[%i].setNodeColor("ALL", %this.color);
}
}
//Return current size of highlight box
function ND_HighlightBox::getSize(%this)
{
return %this.point1 SPC %this.point2;
}
//Resize the highlight box
function ND_HighlightBox::setSize(%this, %point1, %point2)
{
if(getWordCount(%point1) == 6)
{
%point2 = getWords(%point1, 3, 5);
%point1 = getWords(%point1, 0, 2);
}
%this.point1 = %point1;
%this.point2 = %point2;
%x1 = getWord(%point1, 0);
%y1 = getWord(%point1, 1);
%z1 = getWord(%point1, 2);
%x2 = getWord(%point2, 0);
%y2 = getWord(%point2, 1);
%z2 = getWord(%point2, 2);
%len_x = %x2 - %x1;
%len_y = %y2 - %y1;
%len_z = %z2 - %z1;
%center_x = (%x1 + %x2) / 2;
%center_y = (%y1 + %y2) / 2;
%center_z = (%z1 + %z2) / 2;
%rot_x = "0 1 0 1.57079";
%rot_y = "1 0 0 1.57079";
%rot_z = "0 0 1 0";
%this.border_x0.setTransform(%center_x SPC %y1 SPC %z1 SPC %rot_x);
%this.border_x1.setTransform(%center_x SPC %y2 SPC %z1 SPC %rot_x);
%this.border_x2.setTransform(%center_x SPC %y2 SPC %z2 SPC %rot_x);
%this.border_x3.setTransform(%center_x SPC %y1 SPC %z2 SPC %rot_x);
%this.border_y0.setTransform(%x1 SPC %center_y SPC %z1 SPC %rot_y);
%this.border_y1.setTransform(%x2 SPC %center_y SPC %z1 SPC %rot_y);
%this.border_y2.setTransform(%x2 SPC %center_y SPC %z2 SPC %rot_y);
%this.border_y3.setTransform(%x1 SPC %center_y SPC %z2 SPC %rot_y);
%this.border_z0.setTransform(%x1 SPC %y1 SPC %center_z SPC %rot_z);
%this.border_z1.setTransform(%x2 SPC %y1 SPC %center_z SPC %rot_z);
%this.border_z2.setTransform(%x2 SPC %y2 SPC %center_z SPC %rot_z);
%this.border_z3.setTransform(%x1 SPC %y2 SPC %center_z SPC %rot_z);
%maxLen = getMax(getMax(%len_x, %len_y), %len_z);
%width = (7 / 1280) * %maxLen + 1;
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].setScale(%width SPC %width SPC %len_x + %width * 0.05);
%this.border_y[%i].setScale(%width SPC %width SPC %len_y + %width * 0.05);
%this.border_z[%i].setScale(%width SPC %width SPC %len_z + %width * 0.05);
}
}

4494
classes/server/selection.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,496 @@
// Resizeable box to select all bricks inside a volume.
// -------------------------------------------------------------------
//Create a new selection box
function ND_SelectionBox(%shapeName)
{
ND_ServerGroup.add(
%this = new ScriptObject(ND_SelectionBox)
);
%this.innerBox = new StaticShape(){datablock = ND_SelectionBoxInner;};
%this.outerBox = new StaticShape(){datablock = ND_SelectionBoxOuter;};
%this.shapeName = new StaticShape(){datablock = ND_SelectionBoxShapeName;};
%this.corner1 = new StaticShape(){datablock = ND_SelectionBoxOuter;};
%this.corner2 = new StaticShape(){datablock = ND_SelectionBoxOuter;};
%this.selectedCorner = true;
%this.innerBox.setScopeAlways();
%this.outerBox.setScopeAlways();
%this.shapeName.setScopeAlways();
%this.corner1.setScopeAlways();
%this.corner2.setScopeAlways();
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_y[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_z[%i] = new StaticShape(){datablock = ND_SelectionBoxBorder;};
%this.border_x[%i].setScopeAlways();
%this.border_y[%i].setScopeAlways();
%this.border_z[%i].setScopeAlways();
}
%this.boxName = %shapeName;
%this.setNormalMode();
return %this;
}
//Destroy static shapes when selection box is removed
function ND_SelectionBox::onRemove(%this)
{
%this.innerBox.delete();
%this.outerBox.delete();
%this.shapeName.delete();
%this.corner1.delete();
%this.corner2.delete();
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].delete();
%this.border_y[%i].delete();
%this.border_z[%i].delete();
}
}
//Set normal color values and borders
function ND_SelectionBox::setNormalMode(%this)
{
%this.innerColor = "0 0 0 0.60";
%this.outerColor = "0 0 0 0.35";
%this.borderColor = "1 0.84 0 0.99";
%this.borderColorSelected = "0 0 1 0.99";
%this.cornerColor1 = "0.8 0.74 0 0.99";
%this.cornerColor2 = "1 0.94 0.1 0.99";
%this.cornerColorSelected1 = "0 0.2 1 0.99";
%this.cornerColorSelected2 = "0 0.1 0.9 0.99";
%this.isNormalMode = true;
//Unhide the corners and inner/outer box (hidden in disabled mode)
%this.innerBox.unHideNode("ALL");
%this.corner1.unHideNode("ALL");
%this.corner2.unHideNode("ALL");
if(%this.hasVolume())
%this.outerBox.unHideNode("ALL");
//Apply changes
%this.applyColors();
%this.setSize(%this.point1, %this.point2);
%this.shapeName.setShapeName(%this.boxName);
}
//Set grayscale color values and slightly smaller border
function ND_SelectionBox::setDisabledMode(%this)
{
%this.borderColor = "0.1 0.1 0.1 0.4";
%this.borderColorSelected = "0.1 0.1 0.1 0.4";
%this.isNormalMode = false;
//Hide the corners and inner/outer box (looks better)
%this.innerBox.hideNode("ALL");
%this.outerBox.hideNode("ALL");
%this.corner1.hideNode("ALL");
%this.corner2.hideNode("ALL");
//Apply changes
%this.applyColors();
%this.setSize(%this.point1, %this.point2);
%this.shapeName.setShapeName("");
}
//Apply color changes to the selection box
function ND_SelectionBox::applyColors(%this)
{
%this.innerBox.setNodeColor("ALL", %this.innerColor);
%this.outerBox.setNodeColor("ALL", %this.outerColor);
%this.shapeName.setShapeNameColor(%this.borderColor);
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].setNodeColor("ALL", %this.borderColor);
%this.border_y[%i].setNodeColor("ALL", %this.borderColor);
%this.border_z[%i].setNodeColor("ALL", %this.borderColor);
}
%bColor = %this.borderColorSelected;
if(%this.selectedCorner)
{
%this.border_x2.setNodeColor("ALL", %bColor);
%this.border_y2.setNodeColor("ALL", %bColor);
%this.border_z2.setNodeColor("ALL", %bColor);
%corner1 = %this.corner1;
%corner2 = %this.corner2;
}
else
{
%this.border_x0.setNodeColor("ALL", %bColor);
%this.border_y0.setNodeColor("ALL", %bColor);
%this.border_z0.setNodeColor("ALL", %bColor);
%corner1 = %this.corner2;
%corner2 = %this.corner1;
}
%corner1.setNodeColor("out+X", %this.borderColor);
%corner1.setNodeColor("out-X", %this.borderColor);
%corner1.setNodeColor("out+Y", %this.cornerColor1);
%corner1.setNodeColor("out-Y", %this.cornerColor1);
%corner1.setNodeColor("out+Z", %this.cornerColor2);
%corner1.setNodeColor("out-Z", %this.cornerColor2);
//Illusion of shaded box
%corner2.setNodeColor("out+X", %this.borderColorSelected);
%corner2.setNodeColor("out-X", %this.borderColorSelected);
%corner2.setNodeColor("out+Y", %this.cornerColorSelected1);
%corner2.setNodeColor("out-Y", %this.cornerColorSelected1);
%corner2.setNodeColor("out+Z", %this.cornerColorSelected2);
%corner2.setNodeColor("out-Z", %this.cornerColorSelected2);
}
//Return current size of selection box
function ND_SelectionBox::getSize(%this)
{
%x1 = getWord(%this.point1, 0);
%y1 = getWord(%this.point1, 1);
%z1 = getWord(%this.point1, 2);
%x2 = getWord(%this.point2, 0);
%y2 = getWord(%this.point2, 1);
%z2 = getWord(%this.point2, 2);
%min = getMin(%x1, %x2) SPC getMin(%y1, %y2) SPC getMin(%z1, %z2);
%max = getMax(%x1, %x2) SPC getMax(%y1, %y2) SPC getMax(%z1, %z2);
return vectorSub(%max, %min);
}
//Return current world box of selection box
function ND_SelectionBox::getWorldBox(%this)
{
%x1 = getWord(%this.point1, 0);
%y1 = getWord(%this.point1, 1);
%z1 = getWord(%this.point1, 2);
%x2 = getWord(%this.point2, 0);
%y2 = getWord(%this.point2, 1);
%z2 = getWord(%this.point2, 2);
%min = getMin(%x1, %x2) SPC getMin(%y1, %y2) SPC getMin(%z1, %z2);
%max = getMax(%x1, %x2) SPC getMax(%y1, %y2) SPC getMax(%z1, %z2);
return %min SPC %max;
}
//Resize the selection box
function ND_SelectionBox::setSize(%this, %point1, %point2)
{
if(getWordCount(%point1) == 6)
{
%point2 = getWords(%point1, 3, 5);
%point1 = getWords(%point1, 0, 2);
}
%this.point1 = %point1;
%this.point2 = %point2;
%x1 = getWord(%point1, 0);
%y1 = getWord(%point1, 1);
%z1 = getWord(%point1, 2);
%x2 = getWord(%point2, 0);
%y2 = getWord(%point2, 1);
%z2 = getWord(%point2, 2);
%len_x = mAbs(%x2 - %x1);
%len_y = mAbs(%y2 - %y1);
%len_z = mAbs(%z2 - %z1);
%center_x = (%x1 + %x2) / 2;
%center_y = (%y1 + %y2) / 2;
%center_z = (%z1 + %z2) / 2;
%rot_x = "0 1 0 1.57079";
%rot_y = "1 0 0 1.57079";
%rot_z = "0 0 1 0";
%this.innerBox.setTransform(%center_x SPC %center_y SPC %center_z);
%this.outerBox.setTransform(%center_x SPC %center_y SPC %center_z);
%this.shapeName.setTransform(%center_X SPC %center_y SPC %z2);
%this.border_x0.setTransform(%center_x SPC %y1 SPC %z1 SPC %rot_x);
%this.border_x1.setTransform(%center_x SPC %y2 SPC %z1 SPC %rot_x);
%this.border_x2.setTransform(%center_x SPC %y2 SPC %z2 SPC %rot_x);
%this.border_x3.setTransform(%center_x SPC %y1 SPC %z2 SPC %rot_x);
%this.border_y0.setTransform(%x1 SPC %center_y SPC %z1 SPC %rot_y);
%this.border_y1.setTransform(%x2 SPC %center_y SPC %z1 SPC %rot_y);
%this.border_y2.setTransform(%x2 SPC %center_y SPC %z2 SPC %rot_y);
%this.border_y3.setTransform(%x1 SPC %center_y SPC %z2 SPC %rot_y);
%this.border_z0.setTransform(%x1 SPC %y1 SPC %center_z SPC %rot_z);
%this.border_z1.setTransform(%x2 SPC %y1 SPC %center_z SPC %rot_z);
%this.border_z2.setTransform(%x2 SPC %y2 SPC %center_z SPC %rot_z);
%this.border_z3.setTransform(%x1 SPC %y2 SPC %center_z SPC %rot_z);
%this.corner1.setTransform(%x1 SPC %y1 SPC %z1);
%this.corner2.setTransform(%x2 SPC %y2 SPC %z2);
%this.innerBox.setScale(%len_x - 0.02 SPC %len_y - 0.02 SPC %len_z - 0.02);
%this.outerBox.setScale(%len_x + 0.02 SPC %len_y + 0.02 SPC %len_z + 0.02);
if(%this.isNormalMode)
{
//Normal mode (box with two colored corners)
%maxLen = getMax(getMax(%len_x, %len_y), %len_z);
%width = (7/1024) * %maxLen + 1;
for(%i = 0; %i < 4; %i++)
{
%this.border_x[%i].setScale(%width SPC %width SPC %len_x + %width * 0.05);
%this.border_y[%i].setScale(%width SPC %width SPC %len_y + %width * 0.05);
%this.border_z[%i].setScale(%width SPC %width SPC %len_z + %width * 0.05);
}
if(%this.selectedCorner)
{
%width1 = %width;
%width2 = %width + 0.02;
}
else
{
%width1 = %width + 0.02;
%width2 = %width;
}
//The borders touching the two corners are thicker to prevent Z fighting
//with the highlight box if it covers the same area as the selection
%this.border_x0.setScale(%width1 SPC %width1 SPC %len_x - %width * 0.05);
%this.border_y0.setScale(%width1 SPC %width1 SPC %len_y - %width * 0.05);
%this.border_z0.setScale(%width1 SPC %width1 SPC %len_z - %width * 0.05);
%this.border_x2.setScale(%width2 SPC %width2 SPC %len_x - %width * 0.05);
%this.border_y2.setScale(%width2 SPC %width2 SPC %len_y - %width * 0.05);
%this.border_z2.setScale(%width2 SPC %width2 SPC %len_z - %width * 0.05);
//Corners scale with the border width
%cs1 = 0.35 * %width1;
%cs2 = 0.35 * %width2;
%this.corner1.setScale(%cs1 SPC %cs1 SPC %cs1);
%this.corner2.setScale(%cs2 SPC %cs2 SPC %cs2);
}
else
{
//Disabled mode (transparent greyscale box)
%maxLen = getMax(getMax(%len_x, %len_y), %len_z);
%width = (21/5120) * %maxLen + 1;
for(%i = 0; %i < 4; %i++)
{
//Horizontal borders are a bit shorter to prevent z fighting
%this.border_x[%i].setScale(%width SPC %width SPC %len_x - %width * 0.05);
%this.border_y[%i].setScale(%width SPC %width SPC %len_y - %width * 0.05);
%this.border_z[%i].setScale(%width SPC %width SPC %len_z + %width * 0.05);
}
}
}
//Resize the selection box and align it to a player
function ND_SelectionBox::setSizeAligned(%this, %point1, %point2, %player)
{
//Set the selection box to correct orientation
%x1 = getWord(%point1, 0);
%y1 = getWord(%point1, 1);
%z1 = getWord(%point1, 2);
%x2 = getWord(%point2, 0);
%y2 = getWord(%point2, 1);
%z2 = getWord(%point2, 2);
switch(getAngleIDFromPlayer(%player))
{
case 0:
%p1 = %x1 SPC %y2 SPC %z1;
%p2 = %x2 SPC %y1 SPC %z2;
case 1:
%p1 = %x1 SPC %y1 SPC %z1;
%p2 = %x2 SPC %y2 SPC %z2;
case 2:
%p1 = %x2 SPC %y1 SPC %z1;
%p2 = %x1 SPC %y2 SPC %z2;
case 3:
%p1 = %x2 SPC %y2 SPC %z1;
%p2 = %x1 SPC %y1 SPC %z2;
}
//Select first corner
if(!%this.selectedCorner)
{
%this.selectedCorner = true;
%this.applyColors();
}
%this.setSize(%p1, %p2);
}
//Select one of the two corners
function ND_SelectionBox::switchCorner(%this)
{
%this.selectedCorner = !%this.selectedCorner;
if(%this.selectedCorner)
serverPlay3d(BrickRotateSound, %this.point2);
else
serverPlay3d(BrickRotateSound, %this.point1);
%this.setSize(%this.point1, %this.point2);
%this.applyColors();
}
//Move the selected corner
function ND_SelectionBox::shiftCorner(%this, %offset, %limit)
{
%oldP1 = %this.point1;
%oldP2 = %this.point2;
%limitReached = false;
//Size of a plate in TU
%unit[0] = 0.5;
%unit[1] = 0.5;
%unit[2] = 0.2;
for(%dim = 0; %dim < 3; %dim++)
{
//Copy current
%point1[%dim] = getWord(%this.point1, %dim);
%point2[%dim] = getWord(%this.point2, %dim);
//Get the size of the box in the current axis after resizing
%size = getWord(%this.point2, %dim) - getWord(%this.point1, %dim);
if(%this.selectedCorner)
{
//Update point2
%size += getWord(%offset, %dim);
%point2[%dim] += getWord(%offset, %dim);
//Check limits
if(mAbs(%size) > %limit)
{
%limitReached = true;
%point2[%dim] -= %size - %limit * (mAbs(%size) / %size);
}
}
else
{
//Update point1
%size -= getWord(%offset, %dim);
%point1[%dim] += getWord(%offset, %dim);
//Check limits
if(mAbs(%size) > %limit)
{
%limitReached = true;
%point1[%dim] += %size - %limit * (mAbs(%size) / %size);
}
}
}
//Update corner positions
%point1 = %point1[0] SPC %point1[1] SPC %point1[2];
%point2 = %point2[0] SPC %point2[1] SPC %point2[2];
%this.setSize(%point1, %point2);
//Play sounds
if(%this.selectedCorner)
%soundPoint = %point2;
else
%soundPoint = %point1;
if(%point1 !$= %oldP1 || %point2 !$= %oldP2)
serverPlay3d(BrickMoveSound, %soundPoint);
else
serverPlay3d(errorSound, %soundPoint);
//Hide outer box on selection boxes without volume
if(%this.hasVolume())
%this.outerBox.unHideNode("ALL");
else
%this.outerBox.hideNode("ALL");
return %limitReached;
}
//Move the entire box
function ND_SelectionBox::shift(%this, %offset)
{
%this.point1 = vectorAdd(%this.point1, %offset);
%this.point2 = vectorAdd(%this.point2, %offset);
%this.setSize(%this.point1, %this.point2);
//Play sounds
if(%this.selectedCorner)
serverPlay3d(BrickMoveSound, %this.point1);
else
serverPlay3d(BrickMoveSound, %this.point2);
}
//Rotate the entire box
function ND_SelectionBox::rotate(%this, %direction)
{
%point1 = %this.point1;
%point2 = %this.point2;
%center = vectorScale(vectorAdd(%point1, %point2), 0.5);
%brickSizeX = mAbs(mFloatLength((getWord(%point2, 0) - getWord(%point1, 0)) * 2, 0));
%brickSizeY = mAbs(mFloatLength((getWord(%point2, 1) - getWord(%point1, 1)) * 2, 0));
%shiftCorrect = "0 0 0";
if((%brickSizeX % 2) != (%brickSizeY % 2))
{
if(%brickSizeX % 2)
%shiftCorrect = "-0.25 -0.25 0";
else
%shiftCorrect = "0.25 0.25 0";
}
%point1 = vectorAdd(ndRotateVector(vectorSub(%point1, %center), %direction), %center);
%point2 = vectorAdd(ndRotateVector(vectorSub(%point2, %center), %direction), %center);
%this.setSize(vectorAdd(%point1, %shiftCorrect), vectorAdd(%point2, %shiftCorrect));
//Play sounds
if(%this.selectedCorner)
serverPlay3d(BrickRotateSound, %this.point1);
else
serverPlay3d(BrickRotateSound, %this.point2);
}
//Check if the box has a volume
function ND_SelectionBox::hasVolume(%this)
{
if(mAbs(getWord(%this.point1, 0) - getWord(%this.point2, 0)) < 0.05
|| mAbs(getWord(%this.point1, 1) - getWord(%this.point2, 1)) < 0.05
|| mAbs(getWord(%this.point1, 2) - getWord(%this.point2, 2)) < 0.05)
return false;
return true;
}

View File

@ -0,0 +1,75 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Delete this undo group
function ND_UndoGroupPaint::onRemove(%this)
{
if(%this.brickCount)
deleteVariables("$NU" @ %this.client @ "_" @ %this @ "_*");
}
//Start undo paint
function ND_UndoGroupPaint::ndStartUndo(%this, %client)
{
%client.ndUndoInProgress = true;
%client.ndLastMessageTime = $Sim::Time;
%this.ndTickUndo(%this.paintType, 0, %client);
}
//Tick undo paint
function ND_UndoGroupPaint::ndTickUndo(%this, %mode, %start, %client)
{
%end = %start + $Pref::Server::ND::ProcessPerTick;
if(%end > %this.brickCount)
%end = %this.brickCount;
for(%i = %start; %i < %end; %i++)
{
%brick = $NU[%client, %this, "B", %i];
if(!isObject(%brick))
continue;
%colorID = $NU[%client, %this, "V", %i];
switch(%mode)
{
case 0:
//Check whether brick is highlighted
%brick.setColor(%colorID);
case 1:
//Check whether brick is highlighted
if($NDHN[%brick])
$NDHF[%brick] = %colorID;
else
%brick.setColorFx(%colorID);
case 2:
%brick.setShapeFx(%colorID);
}
}
//If undo is taking long, tell the client how far we get
if(%client.ndLastMessageTime + 0.1 < $Sim::Time)
{
%client.ndLastMessageTime = $Sim::Time;
%percent = mFloor(%end * 100 / %this.brickCount);
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo in progress...\n<font:Verdana:17>\c3" @ %percent @ "%\c6 finished.", 10);
}
if(%end >= %this.brickcount)
{
%this.delete();
%client.ndUndoInProgress = false;
if(%start != 0)
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo finished.", 2);
return;
}
%this.schedule(30, ndTickUndo, %mode, %end, %client);
}

View File

@ -0,0 +1,61 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Start undo bricks
function SimSet::ndStartUndo(%this, %client)
{
if(!%this.brickCount)
{
%this.delete();
return;
}
%client.ndUndoInProgress = true;
%client.ndLastMessageTime = $Sim::Time;
%this.ndTickUndo(%this.brickCount, %client);
}
//Tick undo bricks
function SimSet::ndTickUndo(%this, %count, %client)
{
if(%count > %this.getCount())
%start = %this.getCount();
else
%start = %count;
if(%start > $Pref::Server::ND::ProcessPerTick)
%end = %start - $Pref::Server::ND::ProcessPerTick;
else
%end = 0;
for(%i = %start - 1; %i >= %end; %i--)
{
%brick = %this.getObject(%i);
%brick.killBrick();
if(%start > 1024)
%brick.delete();
}
//If undo is taking long, tell the client how far we get
if(%client.ndLastMessageTime + 0.1 < $Sim::Time)
{
%client.ndLastMessageTime = $Sim::Time;
%percent = mFloor(100 - (%end * 100 / %this.brickCount));
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo in progress...\n<font:Verdana:17>\c3" @ %percent @ "%\c6 finished.", 10);
}
if(%end <= 0)
{
%this.delete();
%client.ndUndoInProgress = false;
if(%start != 0)
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo finished.", 2);
return;
}
%this.schedule(30, ndTickUndo, %end, %client);
}

View File

@ -0,0 +1,197 @@
// This file should not exist. Fix later...
// -------------------------------------------------------------------
//Delete this undo group
function ND_UndoGroupWrench::onRemove(%this)
{
if(%this.brickCount)
deleteVariables("$NU" @ %this.client @ "_" @ %this @ "_*");
}
//Start undo wrench
function ND_UndoGroupWrench::ndStartUndo(%this, %client)
{
%client.ndUndoInProgress = true;
%client.ndLastMessageTime = $Sim::Time;
%this.ndTickUndo(0, %client);
}
//Tick undo wrench
function ND_UndoGroupWrench::ndTickUndo(%this, %start, %client)
{
%end = %start + $Pref::Server::ND::ProcessPerTick;
if(%end > %this.brickCount)
%end = %this.brickCount;
setCurrentQuotaObject(getQuotaObjectFromClient(%client));
%fillWrenchName = %this.fillWrenchName;
%fillWrenchLight = %this.fillWrenchLight;
%fillWrenchEmitter = %this.fillWrenchEmitter;
%fillWrenchEmitterDir = %this.fillWrenchEmitterDir;
%fillWrenchItem = %this.fillWrenchItem;
%fillWrenchItemPos = %this.fillWrenchItemPos;
%fillWrenchItemDir = %this.fillWrenchItemDir;
%fillWrenchItemTime = %this.fillWrenchItemTime;
%fillWrenchRaycasting = %this.fillWrenchRaycasting;
%fillWrenchCollision = %this.fillWrenchCollision;
%fillWrenchRendering = %this.fillWrenchRendering;
for(%i = %start; %i < %end; %i++)
{
%brick = $NU[%client, %this, "B", %i];
if(!isObject(%brick))
continue;
//Revert wrench settings
if(%fillWrenchName)
{
%curr = getSubStr(%brick.getName(), 1, 254);
%fillWrenchNameValue = $NU[%client, %this, "N", %i];
if(%curr !$= %fillWrenchNameValue)
%brick.setNTObjectName(%fillWrenchNameValue);
}
if(%fillWrenchLight)
{
if(%tmp = %brick.light | 0)
%curr = %tmp.getDatablock();
else
%curr = 0;
%fillWrenchLightValue = $NU[%client, %this, "LDB", %i];
if(%curr != %fillWrenchLightValue)
%brick.setLight(%fillWrenchLightValue);
}
if(%fillWrenchEmitter)
{
if(%tmp = %brick.emitter | 0)
%curr = %tmp.getEmitterDatablock();
else if(%tmp = %brick.oldEmitterDB | 0)
%curr = %tmp;
else
%curr = 0;
%fillWrenchEmitterValue = $NU[%client, %this, "EDB", %i];
if(%curr != %fillWrenchEmitterValue)
%brick.setEmitter(%fillWrenchEmitterValue);
}
if(%fillWrenchEmitterDir)
{
%curr = %brick.emitterDirection;
%fillWrenchEmitterDirValue = $NU[%client, %this, "EDIR", %i];
if(%curr != %fillWrenchEmitterDirValue)
%brick.setEmitterDirection(%fillWrenchEmitterDirValue);
}
if(%fillWrenchItem)
{
if(%tmp = %brick.item | 0)
%curr = %tmp.getDatablock();
else
%curr = 0;
%fillWrenchItemValue = $NU[%client, %this, "IDB", %i];
if(%curr != %fillWrenchItemValue)
%brick.setItem(%fillWrenchItemValue);
}
if(%fillWrenchItemPos)
{
%curr = %brick.itemPosition;
%fillWrenchItemPosValue = $NU[%client, %this, "IPOS", %i];
if(%curr != %fillWrenchItemPosValue)
%brick.setItemPosition(%fillWrenchItemPosValue);
}
if(%fillWrenchItemDir)
{
%curr = %brick.itemPosition;
%fillWrenchItemDirValue = $NU[%client, %this, "IDIR", %i];
if(%curr != %fillWrenchItemDirValue)
%brick.setItemDirection(%fillWrenchItemDirValue);
}
if(%fillWrenchItemTime)
{
%curr = %brick.itemRespawnTime;
%fillWrenchItemTimeValue = $NU[%client, %this, "IRT", %i];
if(%curr != %fillWrenchItemTimeValue)
%brick.setItemRespawnTime(%fillWrenchItemTimeValue);
}
if(%fillWrenchRaycasting)
{
%curr = %brick.isRaycasting();
%fillWrenchRaycastingValue = $NU[%client, %this, "RC", %i];
if(%curr != %fillWrenchRaycastingValue)
%brick.setRaycasting(%fillWrenchRaycastingValue);
}
if(%fillWrenchCollision)
{
%curr = %brick.isColliding();
%fillWrenchCollisionValue = $NU[%client, %this, "C", %i];
if(%curr != %fillWrenchCollisionValue)
%brick.setColliding(%fillWrenchCollisionValue);
}
if(%fillWrenchRendering)
{
%curr = %brick.isRendering();
%fillWrenchRenderingValue = $NU[%client, %this, "R", %i];
if(%curr != %fillWrenchRenderingValue)
{
//Copy emitter ...?
if(!%fillWrenchRenderingValue && (%tmp = %brick.emitter | 0))
%emitter = %tmp.getEmitterDatablock();
else
%emitter = 0;
%brick.setRendering(%fillWrenchRenderingValue);
if(!%fillWrenchRenderingValue && %emitter)
%brick.setEmitter(%emitter);
}
}
}
clearCurrentQuotaObject();
//If undo is taking long, tell the client how far we get
if(%client.ndLastMessageTime + 0.1 < $Sim::Time)
{
%client.ndLastMessageTime = $Sim::Time;
%percent = mFloor(%end * 100 / %this.brickCount);
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo in progress...\n<font:Verdana:17>\c3" @ %percent @ "%\c6 finished.", 10);
}
if(%end >= %this.brickcount)
{
%this.delete();
%client.ndUndoInProgress = false;
if(%start != 0)
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Undo finished.", 2);
return;
}
%this.schedule(30, ndTickUndo, %end, %client);
}