initial commit
This commit is contained in:
462
classes/server/duplimode/boxselect.cs
Normal file
462
classes/server/duplimode/boxselect.cs
Normal 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);
|
||||
}
|
59
classes/server/duplimode/boxselectprogress.cs
Normal file
59
classes/server/duplimode/boxselectprogress.cs
Normal 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);
|
||||
}
|
48
classes/server/duplimode/cutprogress.cs
Normal file
48
classes/server/duplimode/cutprogress.cs
Normal 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);
|
||||
}
|
128
classes/server/duplimode/fillcolor.cs
Normal file
128
classes/server/duplimode/fillcolor.cs
Normal 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);
|
||||
}
|
41
classes/server/duplimode/fillcolorprogress.cs
Normal file
41
classes/server/duplimode/fillcolorprogress.cs
Normal 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);
|
||||
}
|
76
classes/server/duplimode/loadprogress.cs
Normal file
76
classes/server/duplimode/loadprogress.cs
Normal 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);
|
||||
}
|
268
classes/server/duplimode/plantcopy.cs
Normal file
268
classes/server/duplimode/plantcopy.cs
Normal 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);
|
||||
}
|
62
classes/server/duplimode/plantcopyprogress.cs
Normal file
62
classes/server/duplimode/plantcopyprogress.cs
Normal 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);
|
||||
}
|
43
classes/server/duplimode/saveprogress.cs
Normal file
43
classes/server/duplimode/saveprogress.cs
Normal 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);
|
||||
}
|
210
classes/server/duplimode/stackselect.cs
Normal file
210
classes/server/duplimode/stackselect.cs
Normal 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);
|
||||
}
|
43
classes/server/duplimode/stackselectprogress.cs
Normal file
43
classes/server/duplimode/stackselectprogress.cs
Normal 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);
|
||||
}
|
50
classes/server/duplimode/supercutprogress.cs
Normal file
50
classes/server/duplimode/supercutprogress.cs
Normal 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);
|
||||
}
|
45
classes/server/duplimode/wrenchprogress.cs
Normal file
45
classes/server/duplimode/wrenchprogress.cs
Normal 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);
|
||||
}
|
38
classes/server/ghostgroup.cs
Normal file
38
classes/server/ghostgroup.cs
Normal 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);
|
||||
}
|
112
classes/server/highlightbox.cs
Normal file
112
classes/server/highlightbox.cs
Normal 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
4494
classes/server/selection.cs
Normal file
File diff suppressed because it is too large
Load Diff
496
classes/server/selectionbox.cs
Normal file
496
classes/server/selectionbox.cs
Normal 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;
|
||||
}
|
75
classes/server/undogrouppaint.cs
Normal file
75
classes/server/undogrouppaint.cs
Normal 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);
|
||||
}
|
61
classes/server/undogroupplant.cs
Normal file
61
classes/server/undogroupplant.cs
Normal 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);
|
||||
}
|
197
classes/server/undogroupwrench.cs
Normal file
197
classes/server/undogroupwrench.cs
Normal 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);
|
||||
}
|
Reference in New Issue
Block a user