add box features

This commit is contained in:
Redo 2025-02-26 17:36:12 -07:00
parent cd5b46cc3b
commit dd049be341
21 changed files with 1510 additions and 339 deletions

View File

@ -1,3 +1,5 @@
//bls 4
// This file should not exist. Fix later...
// -------------------------------------------------------------------
@ -200,6 +202,21 @@ function NDM_BoxSelect::onSelectObject(%this, %client, %obj, %pos, %normal)
%client.ndUpdateBottomPrint();
}
function ndRound(%v, %step) {
return mFloor(%v/%step + 0.5)*%step;
}
function ndCorrectBox(%box) {
%xl = ndRound(getWord(%box, 0), 0.5);
%yl = ndRound(getWord(%box, 1), 0.5);
%zl = ndRound(getWord(%box, 2), 0.2);
%xh = ndRound(getWord(%box, 3), 0.5);
%yh = ndRound(getWord(%box, 4), 0.5);
%zh = ndRound(getWord(%box, 5), 0.2);
%box2 = %xl SPC %yl SPC %zl SPC %xh SPC %yh SPC %zh;
return %box2;
}
function ndGetBoxFromRom(%b) {
%db = %b.getDatablock();
%box = %b.getWorldBox();
@ -207,7 +224,7 @@ function ndGetBoxFromRom(%b) {
%bh = getWords(%box, 3, 5);
%bl = vectorAdd(%bl, "0 0 " SPC (%db.brickSizeZ * 0.2));
%bh = vectorAdd(%bh, "0 0 " SPC (%db.logicRomZ * 0.2));
return %bl SPC %bh;
return ndCorrectBox(%bl SPC %bh);
}
function ndGetBoxFromZone(%b) {
@ -216,7 +233,7 @@ function ndGetBoxFromZone(%b) {
%scale = %z.getScale(); %sx = getWord(%scale, 0); %sy = getWord(%scale, 1); %sz = getWord(%scale, 2);
%bl = %pos;
%bh = vectorAdd(%pos, %sx SPC (-%sy) SPC %sz);
return %bl SPC %bh;
return ndCorrectBox(%bl SPC %bh);
}

View File

@ -48,7 +48,7 @@ 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.");
ndmessageClient(%client, '', "\c6Paint Mode is admin only. Ask an admin for help.");
return;
}
@ -63,7 +63,7 @@ function NDM_FillColor::onPlantBrick(%this, %client)
//Admin limit
if($Pref::Server::ND::PaintFxAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Paint Fx Mode is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Paint Fx Mode is admin only. Ask an admin for help.");
return;
}

View File

@ -1,3 +1,5 @@
//bls 4
// This file should not exist. Fix later...
// -------------------------------------------------------------------
@ -26,6 +28,7 @@ function NDM_PlantCopy::onChangeMode(%this, %client, %nextMode)
{
%client.ndSelection.deleteData();
}
%client.ndOwnership = false;
}
//Kill this mode
@ -33,6 +36,7 @@ function NDM_PlantCopy::onKillMode(%this, %client)
{
//Destroy the selection
%client.ndSelection.delete();
%client.ndOwnership = false;
}
@ -112,12 +116,21 @@ function NDM_PlantCopy::onPlantBrick(%this, %client)
{
if($Pref::Server::ND::FloatAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Force Plant has been disabled because it is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Force Plant has been disabled because it is admin only. Ask an admin for help.");
%client.ndForcePlant = false;
}
}
%this.conditionalPlant(%client, %client.ndForcePlant);
if(%client.ndOwnership) {
if(!%client.isAdmin) {
%client.ndOwnership = false;
ndmessageClient(%client, '', "\c6Ownership plant has been disabled because it is admin only.");
}
}
%this.conditionalPlant(%client, %client.ndForcePlant, %client.ndOwnership);
%client.ndOwnership = false;
}
//Cancel Brick
@ -160,7 +173,9 @@ function NDM_PlantCopy::getBottomPrint(%this, %client)
%l0 = "Pivot: \c3" @ (%client.ndPivot ? "Whole Selection" : "Start Brick") @ "\c6 [Prev Seat]";
if(isObject(%client.ndSelection.targetGroup))
if(%client.ndOwnership)
%l1 = "Planting as: Original Owner";
else 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";
@ -222,7 +237,7 @@ function NDM_PlantCopy::moveBricksTo(%his, %client, %pos, %normal)
}
//Check time limit and attempt to plant bricks
function NDM_PlantCopy::conditionalPlant(%this, %client, %force)
function NDM_PlantCopy::conditionalPlant(%this, %client, %force, %ownership)
{
//Check timeout
if(!%client.isAdmin && %client.ndLastPlantTime + ($Pref::Server::ND::PlantTimeoutMS / 1000) > $Sim::Time)
@ -252,7 +267,7 @@ function NDM_PlantCopy::conditionalPlant(%this, %client, %force)
getTrustLevel(%client, %client.ndSelection.targetGroup) < 1 &&
(!%client.isAdmin || !$Pref::Server::ND::AdminTrustBypass2))
{
messageClient(%client, '', "\c6You need build trust with \c3"
ndmessageClient(%client, '', "\c6You need build trust with \c3"
@ %client.ndSelection.targetGroup.name @ "\c6 to plant bricks in their group.");
return;
@ -264,5 +279,5 @@ function NDM_PlantCopy::conditionalPlant(%this, %client, %force)
%ang = %client.ndSelection.ghostAngleID;
%client.ndSetMode(NDM_PlantCopyProgress);
%client.ndSelection.startPlant(%pos, %ang, %force);
%client.ndSelection.startPlant(%pos, %ang, %force, %ownership);
}

View File

@ -1,3 +1,5 @@
//bls 4
// This file should not exist. Fix later...
// -------------------------------------------------------------------
@ -72,7 +74,12 @@ function NDM_StackSelect::onSelectObject(%this, %client, %obj, %pos, %normal)
//Start selection
%client.ndSetMode(NDM_StackSelectProgress);
if(%client.ndMultiSelect)
if(%client.ndSelection.brickCount==0)
%client.ndInitialMultiSelect = %client.ndMultiSelect;
if(%client.ndInitialMultiSelect)
%client.ndSelection.startStackSelectionAdditive(%obj, 2, %client.ndLimited);
else if(%client.ndMultiSelect)
%client.ndSelection.startStackSelectionAdditive(%obj, %client.ndDirection, %client.ndLimited);
else
%client.ndSelection.startStackSelection(%obj, %client.ndDirection, %client.ndLimited);

View File

@ -1,3 +1,5 @@
//bls 3
// This file is way too big. Fix later...
// -------------------------------------------------------------------
@ -11,6 +13,7 @@
// $NS[%s, "P", %i] - Position
// $NS[%s, "R", %i] - Rotation
// $NS[%s, "O", %i] - Owner BL_ID
// $NS[%s, "NT", %i] - Brick name
// $NS[%s, "HN", %n] - Name exists in selection
// $NS[%s, "PR", %i] - Print
@ -123,6 +126,50 @@ function ND_Selection::onRemove(%this)
//Stack Selection
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ndBoxSearchAdjacentBricks(%brick, %boxadd, %limited){
%box = %brick.getWorldBox();
%boxsize = vectorSub(getWords(%box, 3, 5), getWords(%box, 0, 2));
%boxsize = vectorAdd(%boxsize, %boxadd);
//%mask = %limited ? $TypeMasks::FxBrickObjectType : $TypeMasks::FxBrickAlwaysObjectType;
%mask = $TypeMasks::FxBrickAlwaysObjectType;
initContainerBoxSearch(%brick.getPosition(), %boxsize, %mask);
}
function ndGetNextAdjacentBrick(%brick, %limited) {
if($ND_boxSearchDir$="" || $ND_boxSearchBrick!=%brick) {
$ND_boxSearchDir = 1;
$ND_boxSearchBrick = %brick;
ndBoxSearchAdjacentBricks(%brick, "0.2 -0.2 -0.2", %limited);
}
for(%i=0; %i<100; %i++) {
//while(true) {
%brick2 = containerSearchNext();
//echo(%i SPC %brick2);
if(%brick2) {
//if(%brick2.colorId==%brick.colorId && %brick2!=%brick) {
if(
(!%limited || %brick2.colorId==%brick.colorId) &&
%brick2!=%brick
) {
//echo("hit");
return %brick2;
}
} else {
if($ND_boxSearchDir==1) {
$ND_boxSearchDir = 2;
ndBoxSearchAdjacentBricks(%brick, "-0.2 0.2 -0.2", %limited);
} else if($ND_boxSearchDir==2) {
$ND_boxSearchDir = 3;
ndBoxSearchAdjacentBricks(%brick, "-0.2 -0.2 0.2", %limited);
} else {
$ND_boxSearchDir = "";
$ND_boxSearchBrick = "";
return 0;
}
}
}
}
//Begin stack selection
function ND_Selection::startStackSelection(%this, %brick, %direction, %limited)
{
@ -158,7 +205,27 @@ function ND_Selection::startStackSelection(%this, %brick, %direction, %limited)
%bl_id = %this.client.bl_id;
//Add bricks connected to the first brick to queue (do not register connections yet)
if(%direction == 1)
if(%direction==2) {
while(%nextBrick = ndGetNextAdjacentBrick(%brick, %limited)) {
//If the brick is not in the list yet, add it to the queue
if($NS[%this, "I", %nextBrick] $= "")
{
if(%queueCount >= %brickLimit)
continue;
//Check trust
if(!ndTrustCheckSelect(%nextBrick, %group, %bl_id, %admin))
{
%trustFailCount++;
continue;
}
$NS[%this, "B", %queueCount] = %nextBrick;
$NS[%this, "I", %nextBrick] = %queueCount;
%queueCount++;
}
}
} else if(%direction == 1)
{
//Set lower height limit
%heightLimit = %this.minZ - 0.01;
@ -167,7 +234,6 @@ function ND_Selection::startStackSelection(%this, %brick, %direction, %limited)
for(%i = 0; %i < %upCount; %i++)
{
%nextBrick = %brick.getUpBrick(%i);
//If the brick is not in the list yet, add it to the queue
if($NS[%this, "I", %nextBrick] $= "")
{
@ -287,6 +353,32 @@ function ND_Selection::startStackSelectionAdditive(%this, %brick, %direction, %l
%group = %this.client.brickGroup.getId();
%bl_id = %this.client.bl_id;
if(%direction==2) {
%conns = 0;
while(%nextBrick = ndGetNextAdjacentBrick(%brick, %limited)) {
//If the brick is not in the list yet, add it to the queue
%nId = $NS[%this, "I", %nextBrick];
if(%nId $= "")
{
if(%queueCount >= %brickLimit)
continue;
//Check trust
if(!ndTrustCheckSelect(%nextBrick, %group, %bl_id, %admin))
{
%trustFailCount++;
continue;
}
$NS[%this, "B", %queueCount] = %nextBrick;
$NS[%this, "I", %nextBrick] = %queueCount;
%queueCount++;
}
}
} else {
//Add bricks connected to the first brick to queue (do not register connections yet)
if(%direction == 1)
{
@ -392,6 +484,7 @@ function ND_Selection::startStackSelectionAdditive(%this, %brick, %direction, %l
%this.connectionCount++;
}
}
}
$NS[%this, "N", %brickIndex] = %conns;
@ -455,7 +548,8 @@ function ND_Selection::tickStackSelection(%this, %direction, %limited, %heightLi
if(!%brick)
{
messageClient(%this.client, 'MsgError', "\c0Error: \c6Queued brick does not exist anymore. Do not modify the build during selection!");
messageClient(%this.client, 'MsgError', "");
ndmessageClient(%this.client, '', "\c0Error: \c6Queued brick does not exist anymore. Do not modify the build during selection!");
%this.cancelStackSelection();
%this.client.ndSetMode(NDM_StackSelect);
@ -464,6 +558,32 @@ function ND_Selection::tickStackSelection(%this, %direction, %limited, %heightLi
ndHighlightBrick(%highlightGroup, %brick);
if(%direction==2) {
%conns = 0;
while(%nextBrick = ndGetNextAdjacentBrick(%brick, %limited)) {
//If the brick is not in the list yet, add it to the queue
%nId = $NS[%this, "I", %nextBrick];
if(%nId $= "")
{
if(%queueCount >= %brickLimit)
continue;
//Check trust
if(!ndTrustCheckSelect(%nextBrick, %group, %bl_id, %admin))
{
%trustFailCount++;
continue;
}
$NS[%this, "B", %queueCount] = %nextBrick;
$NS[%this, "I", %nextBrick] = %queueCount;
%queueCount++;
}
}
} else {
//Queue all up bricks
%upCount = %brick.getNumUpBricks();
%conns = 0;
@ -562,6 +682,7 @@ function ND_Selection::tickStackSelection(%this, %direction, %limited, %heightLi
%this.connectionCount++;
}
}
}
$NS[%this, "N", %i] = %conns;
@ -895,7 +1016,8 @@ function ND_Selection::tickBoxSelectionProcess(%this)
if(!%brick)
{
messageClient(%this.client, 'MsgError', "\c0Error: \c6Queued brick does not exist anymore. Do not modify the build during selection!");
messageClient(%this.client, 'MsgError', "");
ndmessageClient(%this.client, '', "\c0Error: \c6Queued brick does not exist anymore. Do not modify the build during selection!");
%this.cancelBoxSelection();
%this.client.ndSetMode(NDM_BoxSelect);
@ -1016,6 +1138,9 @@ function ND_Selection::recordBrickData(%this, %i)
//Rotation
$NS[%this, "R", %i] = %brick.angleID;
//Owner
$NS[%this, "O", %i] = %brick.getGroup().bl_id;
//Colors
if($NDHN[%brick])
{
@ -1588,7 +1713,7 @@ function ND_Selection::finishSuperCut(%this)
%this.client.fillBricksAfterSuperCut = false;
if(%this.trustFailCount)
messageClient(%this.client, '', "\c6Cannot run fill bricks, you do not have enough trust bricks already in the area.");
ndmessageClient(%this.client, '', "\c6Cannot run fill bricks, you do not have enough trust bricks already in the area.");
else
%this.client.doFillBricks(%this.client.NDFillBrickSubset);
}
@ -2070,9 +2195,10 @@ function ND_Selection::getGhostWorldBox(%this)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Start planting bricks!
function ND_Selection::startPlant(%this, %position, %angleID, %forcePlant)
function ND_Selection::startPlant(%this, %position, %angleID, %forcePlant, %ownership)
{
%this.forcePlant = %forcePlant;
%this.ownership = %ownership;
%this.plantSearchIndex = 0;
%this.plantQueueIndex = 0;
@ -2349,6 +2475,29 @@ function ND_Selection::tickPlantTree(%this, %remainingPlants, %position, %angleI
%this.plantSchedule = %this.schedule(30, tickPlantTree, $Pref::Server::ND::ProcessPerTick, %position, %angleID);
}
function ndBrickGroupFromBlid(%blid) {
%bg = "BrickGroup_" @ %blid;
if (isObject(%bg)) {
return %bg.getId();
} else {
%bg = new SimGroup("BrickGroup_" @ %blid){};
%bg.client = 0;
%bg.name = "\c2BL_ID: " @ %blid @ "\c2\c1";
%bg.bl_id = %blid;
mainBrickGroup.add(%bg);
return %bg.getId();
}
}
function ndFindWord(%s, %w, %x, %a) {
if(%a $= "") %a = 1;
%c = getWordCount(%str);
for(%i = %x+0; %i<%c; %i+=%a) {
if(getWord(%s, %i) $= %w) return %i;
}
return -1;
}
//Attempt to plant brick with id %i
//Returns brick if planted, 0 if floating, -1 if blocked, -2 if trust failure
function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, %client, %bl_id)
@ -2549,7 +2698,12 @@ function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, %
$LastLoadedBrick = %brick;
//Add to brickgroup
//%brickGroup.add(%brick);
if(%this.ownership && $NS[%this, "O", %i] !$= "") {
ndBrickGroupFromBlid($NS[%this, "O", %i]).add(%brick);
} else {
%brickGroup.add(%brick);
}
//Attempt plant
%error = %brick.plant();
@ -2728,7 +2882,8 @@ function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, %
%param = ndRotateVector(%param, %angleID);
case "list":
%value = getWord(%paramType, %param * 2 + 1);
//%value = getWord(%paramType, %param * 2 + 1);
%value = getWord(%paramType, ndFindWord(%paramType, %param, 2, 2)-1);
switch$(%value)
{
@ -2743,6 +2898,8 @@ function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, %
if(%dir >= 0)
{
%oldvalue = %value;
%oldparam = %param;
switch(ndTransformDirection(%dir, %angleID, %mirrX, %mirrY, %mirrZ))
{
case 0: %value = "Up";
@ -2753,14 +2910,15 @@ function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, %
case 5: %value = "West";
}
for(%l = 1; %l < getWordCount(%paramType); %l += 2)
{
if(getWord(%paramType, %l) $= %value)
{
%param = getWord(%paramType, %l + 1);
break;
}
}
//for(%l = 1; %l < getWordCount(%paramType); %l += 2)
//{
// if(getWord(%paramType, %l) $= %value)
// {
// %param = getWord(%paramType, %l + 1);
// break;
// }
//}
%param = getWord(%paramType, ndFindWord(%paramType, %value, 1, 2)+1);
}
}
}
@ -2814,7 +2972,7 @@ function ND_Selection::finishPlant(%this)
{
//Report mirror errors
if($NS[%this.client, "MXC"] > 0 || $NS[%this.client, "MZC"] > 0)
messageClient(%this.client, '', "\c6Some bricks were probably mirrored incorrectly. Say \c3/mirErrors\c6 to find out more.");
ndMessageClient(%this.client, '', "\c6Some bricks were probably mirrored incorrectly. Say \c3/mirErrors\c6 to find out more.");
%count = %this.brickCount;
%planted = %this.plantSuccessCount;
@ -3573,6 +3731,11 @@ function ND_Selection::tickSaveBricks(%this)
SPC !$NS[%this, "NR", %i]
);
// Write ownership
if($NS[%this, "O", %i] !$= "") {
%file.writeLine("+-OWNER " @ $NS[%this, "O", %i]);
}
//Write brick name
if((%tmp = $NS[%this, "NT", %i]) !$= "")
%file.writeLine("+-NTOBJECTNAME " @ %tmp);
@ -3849,7 +4012,8 @@ function ND_Selection::finishSaving(%this)
%s1 = %this.brickCount == 1 ? "" : "s";
%s2 = %this.connectionCount == 1 ? "" : "s";
messageClient(%this.client, 'MsgProcessComplete', "\c6Finished saving selection, wrote \c3"
messageClient(%this.client, 'MsgProcessComplete');
ndmessageClient(%this.client, '', "\c6Finished saving selection, wrote \c3"
@ %this.brickCount @ "\c6 Brick" @ %s1 @ " with \c3" @ %this.connectionCount @ "\c6 Connection" @ %s2 @ "!");
%this.client.ndLastSaveTime = $Sim::Time;
@ -4151,10 +4315,12 @@ function ND_Selection::tickLoadBricks(%this)
warn("LOAD DUP: Got connection data before connection sizes");
//Line is irrelevant
//Line is owner
case "+-OWNER":
%nothing = "";
//%ownerBlid = trim(getSubStr(%line, 7, strLen(%line)-7));
%ownerBlid = getWord(%line, 1);
%ownerBlid = mAbs(mFloor(%ownerBlid));
$NS[%this, "O", %index] = %ownerBlid;
//Line is brick
default:
@ -4475,7 +4641,8 @@ function ND_Selection::finishLoading(%this)
%s1 = %this.brickCount == 1 ? "" : "s";
%s2 = %this.connectionCount == 1 ? "" : "s";
messageClient(%this.client, 'MsgProcessComplete', "\c6Finished loading selection, got \c3"
messageClient(%this.client, 'MsgProcessComplete', "");
ndmessageClient(%this.client, '', "\c6Finished loading selection, got \c3"
@ %this.brickCount @ "\c6 Brick" @ %s1 @ " with \c3" @ %this.connectionCount @ "\c6 Connection" @ %s2 @ "!");
%this.client.ndLastLoadTime = $Sim::Time;

29
client.cs Normal file
View File

@ -0,0 +1,29 @@
// Executes all required scripts and initializes the client side.
// -------------------------------------------------------------------
// Not updating because it's useless
$ND::Version = "1.6.3";
$ND::FilePath = filePath($Con::File) @ "/";
$ND::ConfigPath = "config/NewDuplicator/";
$ND::ClassPath = $ND::FilePath @ "classes/";
$ND::ScriptPath = $ND::FilePath @ "scripts/";
$ND::ResourcePath = $ND::FilePath @ "resources/";
exec($ND::ScriptPath @ "client/guis/fillwrench.gui");
exec($ND::ScriptPath @ "client/controls.cs");
exec($ND::ScriptPath @ "client/handshake.cs");
exec($ND::ScriptPath @ "client/wrench.cs");
//if(!$Pref::ND::DisableUpdater
// && !$SupportUpdaterMigration
// && !isFile("Add-Ons/Support_Updater.zip"))
//{
// exec($ND::ScriptPath @ "client/tcpclient.cs");
// exec($ND::ScriptPath @ "client/updater.cs");
//}
activatePackage(NewDuplicator_Client);
ndRegisterKeybinds();

View File

@ -1,4 +1,4 @@
Title: New Duplicator
Author: Zeblote (1163)
Title: New Duplicator (Redo Edit)
Author: Zeblote (1163), Redo (12878)
New lag-free duplicator with intelligent selection modes
Redo's mod v1: better dupsave listing and search, fill and supercut logic wires, V20 support, possibly some other stuff I forgot about
See readme.md

29
readme.md Normal file
View File

@ -0,0 +1,29 @@
# Redo's New Duplicator Edit
A fork of the original New Duplicator by Zeblote, presently maintained and with many improvements.
## New Features
- Added the `/ownership` or `/o` command, which plants each brick in the current selection with its original ownership. Use in plant mode after copying/cutting.
`/savedup` now saves ownership, and `/ownership` can be used while holding a loaded duplication to load it.
(Loading ownership only works if the duplication was saved with this version, as the original newdup does not save ownership)
- Holding ctrl while making an initial stack selection selects all adjacent bricks of the same color, ignoring diagonals.
With limited mode off, all adjacent bricks will be selected regardless of color.
- The `/alldups` list is nicely formatted, sorted by date, and shows who saved each item.
- Support for Brick_LuaLogic
Supercut can be used on wire bricks.
`/FillBrick LogicWire` or `/fbw` can be used to fill with wire bricks.
Initial-multi-box-selecting a ROM sets the box to its data volume.
- Initial multi-box-selecting a brick with a zone sets the box to its zone.
Hitting plant with this box updates the first Event_SetZoneBox event if present.
## Tweaks
- Made the "Create Sym Table on Start" pref default to true.
- Changed a lot of chat messages to be center-prints instead.
- Multi-selecting in box mode now only selects a single stud if ctrl was/is held for the first selection, otherwise it selects the entire brick.
## Fixes
- Fixed "Nonexistent undo state" message when undoing a plant that has been supercut.
- Fixed preventing unequipping any tool for 1.5s after using `/duplicator`
- Removed useless files from the add-on root directory
- Removed the annoying messages about mismatched newdup versions when joining a server.
- Removed the worm known as Support_Updater.
- Probably some more stuff I forgot about.

116
scripts/client/controls.cs Normal file
View File

@ -0,0 +1,116 @@
// Registers hotkeys used to control the new duplicator.
// -------------------------------------------------------------------
//Register rebind-able controls
function ndRegisterKeybinds()
{
if($ND::KeybindsRegistered)
return;
$RemapDivision[$RemapCount] = "New Duplicator";
$RemapName[$RemapCount] = "Copy Selection (Ctrl C)";
$RemapCmd[$RemapCount] = "ndInputCopy";
$RemapCount++;
$RemapName[$RemapCount] = "Paste Selection (Ctrl V)";
$RemapCmd[$RemapCount] = "ndInputPaste";
$RemapCount++;
$RemapName[$RemapCount] = "Cut Selection (Ctrl X)";
$RemapCmd[$RemapCount] = "ndInputCut";
$RemapCount++;
$RemapName[$RemapCount] = "Multiselect (Ctrl, Hold to use)";
$RemapCmd[$RemapCount] = "ndInputMultiSelect";
$RemapCount++;
$RemapName[$RemapCount] = "Send /NewDuplicator";
$RemapCmd[$RemapCount] = "ndInputNewDuplicator";
$RemapCount++;
$RemapName[$RemapCount] = "Send /FillWrench";
$RemapCmd[$RemapCount] = "ndInputFillWrench";
$RemapCount++;
$RemapName[$RemapCount] = "Send /ForcePlant";
$RemapCmd[$RemapCount] = "ndInputForcePlant";
$RemapCount++;
$RemapName[$RemapCount] = "Send /ToggleForcePlant";
$RemapCmd[$RemapCount] = "ndInputToggleForcePlant";
$RemapCount++;
$RemapName[$RemapCount] = "Send /MirrorX";
$RemapCmd[$RemapCount] = "ndInputMirrorX";
$RemapCount++;
$RemapName[$RemapCount] = "Send /MirrorY";
$RemapCmd[$RemapCount] = "ndInputMirrorY";
$RemapCount++;
$RemapName[$RemapCount] = "Send /MirrorZ";
$RemapCmd[$RemapCount] = "ndInputMirrorZ";
$RemapCount++;
$RemapName[$RemapCount] = "Send /SuperCut (Shift-Ctrl X)";
$RemapCmd[$RemapCount] = "ndInputSuperCut";
$RemapCount++;
$RemapName[$RemapCount] = "Send /FillBricks (Shift-Ctrl V)";
$RemapCmd[$RemapCount] = "ndInputFillBricks";
$RemapCount++;
$ND::KeybindsRegistered = true;
}
//Enable the copy, paste, cut keybinds
function clientCmdNdEnableKeybinds(%bool)
{
if(%bool && !$ND::KeybindsEnabled)
{
%map = new ActionMap(ND_KeyMap);
if(MoveMap.getBinding("ndInputCopy") $= "")
%map.bind("keyboard", isWindows() ? "ctrl c" : "cmd c", "ndInputCopy");
if(MoveMap.getBinding("ndInputPaste") $= "")
%map.bind("keyboard", isWindows() ? "ctrl v" : "cmd v", "ndInputPaste");
if(MoveMap.getBinding("ndInputCut") $= "")
%map.bind("keyboard", isWindows() ? "ctrl x" : "cmd x", "ndInputCut");
if(MoveMap.getBinding("ndInputMultiSelect") $= "")
%map.bind("keyboard", isWindows() ? "lcontrol" : "cmd", "ndInputMultiSelect");
if(MoveMap.getBinding("ndInputSuperCut") $= "")
%map.bind("keyboard", isWindows() ? "shift-ctrl x" : "shift-cmd x", "ndInputSuperCut");
if(MoveMap.getBinding("ndInputFillBricks") $= "")
%map.bind("keyboard", isWindows() ? "shift-ctrl v" : "shift-cmd v", "ndInputFillBricks");
%map.push();
$ND::KeybindsEnabled = true;
}
else if(!%bool && $ND::KeybindsEnabled)
{
ND_KeyMap.pop();
ND_KeyMap.delete();
$ND::KeybindsEnabled = false;
}
}
//Input handlers
function ndInputNewDuplicator (%bool) {if(!%bool)return; commandToServer('newDuplicator' );}
function ndInputCopy (%bool) {if(!%bool)return; commandToServer('ndCopy' );}
function ndInputPaste (%bool) {if(!%bool)return; commandToServer('ndPaste' );}
function ndInputCut (%bool) {if(!%bool)return; commandToServer('ndCut' );}
function ndInputFillWrench (%bool) {if(!%bool)return; commandToServer('fillWrench' );}
function ndInputForcePlant (%bool) {if(!%bool)return; commandToServer('forcePlant' );}
function ndInputToggleForcePlant(%bool) {if(!%bool)return; commandToServer('toggleForcePlant');}
function ndInputMirrorX (%bool) {if(!%bool)return; commandToServer('mirrorX' );}
function ndInputMirrorY (%bool) {if(!%bool)return; commandToServer('mirrorY' );}
function ndInputMirrorZ (%bool) {if(!%bool)return; commandToServer('mirrorZ' );}
function ndInputSuperCut (%bool) {if(!%bool)return; commandToServer('superCut' );}
function ndInputFillBricks (%bool) {if(!%bool)return; commandToServer('fillBricks' );}
function ndInputMultiSelect(%bool) {commandToServer('ndMultiSelect', %bool);}

View File

@ -0,0 +1,507 @@
// Modified wrench dialog window with toggle-able settings.
// -------------------------------------------------------------------
new GuiControl(ND_WrenchDlg)
{
profile = "GuiDefaultProfile";
position = "0 0";
extent = "1024 768";
new GuiWindowCtrl(ND_Wrench_Window)
{
profile = "BlockWindowProfile";
horizSizing = "center";
vertSizing = "center";
position = "363 197";
extent = "297 373";
text = "New Duplicator | Fill Wrench";
resizeWidth = "0";
resizeHeight = "0";
canMove = "1";
canClose = "1";
canMinimize = "0";
canMaximize = "0";
minSize = "50 50";
closeCommand = "canvas.popDialog(ND_WrenchDlg);";
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 33";
extent = "57 18";
text = "Brick Name:";
};
new GuiTextEditCtrl(ND_Wrench_Name)
{
profile = "GuiTextEditProfile";
position = "76 33";
extent = "162 18";
maxLength = "32";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 63";
extent = "26 18";
text = "Light:";
};
new GuiPopUpMenuCtrl(ND_Wrench_Lights)
{
profile = "BlockButtonProfile";
position = "76 60";
extent = "162 22";
maxPopupHeight = "200";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 93";
extent = "35 18";
text = "Emitter:";
};
new GuiPopUpMenuCtrl(ND_Wrench_Emitters)
{
profile = "BlockButtonProfile";
position = "76 90";
extent = "162 22";
maxPopupHeight = "200";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 113";
extent = "51 18";
text = "Emitter Dir:";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir0)
{
profile = "GuiRadioProfile";
position = "78 110";
extent = "27 22";
text = "U";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir1)
{
profile = "GuiRadioProfile";
position = "104 110";
extent = "27 22";
text = "D";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir2)
{
profile = "GuiRadioProfile";
position = "130 110";
extent = "27 22";
text = "N";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir3)
{
profile = "GuiRadioProfile";
position = "156 110";
extent = "27 22";
text = "E";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir4)
{
profile = "GuiRadioProfile";
position = "182 110";
extent = "27 22";
text = "S";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_EmitterDir5)
{
profile = "GuiRadioProfile";
position = "208 110";
extent = "27 22";
text = "W";
groupNum = "1";
buttonType = "RadioButton";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 153";
extent = "22 18";
text = "Item:";
};
new GuiPopUpMenuCtrl(ND_Wrench_Items)
{
profile = "BlockButtonProfile";
position = "76 150";
extent = "162 22";
maxPopupHeight = "200";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 173";
extent = "43 18";
text = "Item Pos:";
};
new GuiRadioCtrl(ND_Wrench_ItemPos1)
{
profile = "GuiRadioProfile";
position = "104 170";
extent = "27 22";
text = "D";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemPos0)
{
profile = "GuiRadioProfile";
position = "78 170";
extent = "27 22";
text = "U";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemPos2)
{
profile = "GuiRadioProfile";
position = "130 170";
extent = "27 22";
text = "N";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemPos3)
{
profile = "GuiRadioProfile";
position = "156 170";
extent = "27 22";
text = "E";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemPos4)
{
profile = "GuiRadioProfile";
position = "182 170";
extent = "27 22";
text = "S";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemPos5)
{
profile = "GuiRadioProfile";
position = "208 170";
extent = "27 22";
text = "W";
groupNum = "2";
buttonType = "RadioButton";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 193";
extent = "38 18";
text = "Item Dir:";
};
new GuiRadioCtrl(ND_Wrench_ItemDir5)
{
profile = "GuiRadioProfile";
position = "208 190";
extent = "27 22";
text = "W";
groupNum = "3";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemDir2)
{
profile = "GuiRadioProfile";
position = "130 190";
extent = "27 22";
text = "N";
groupNum = "3";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemDir3)
{
profile = "GuiRadioProfile";
position = "156 190";
extent = "27 22";
text = "E";
groupNum = "3";
buttonType = "RadioButton";
};
new GuiRadioCtrl(ND_Wrench_ItemDir4)
{
profile = "GuiRadioProfile";
position = "182 190";
extent = "27 22";
text = "S";
groupNum = "3";
buttonType = "RadioButton";
};
new GuiTextCtrl()
{
profile = "GuiTextProfile";
position = "13 213";
extent = "97 18";
text = "Item Respawn Time:";
};
new GuiTextEditCtrl(ND_Wrench_ItemTime)
{
profile = "GuiTextEditProfile";
position = "117 213";
extent = "121 18";
};
new GuiCheckBoxCtrl(ND_Wrench_RayCasting)
{
profile = "GuiCheckBoxProfile";
position = "14 240";
extent = "78 22";
text = "Ray Casting";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_Collision)
{
profile = "GuiCheckBoxProfile";
position = "14 260";
extent = "74 22";
text = "Collision";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_Rendering)
{
profile = "GuiCheckBoxProfile";
position = "14 280";
extent = "74 22";
text = "Rendering";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleName)
{
profile = "GuiCheckBoxProfile";
position = "244 32";
extent = "42 22";
command = "ND_Wrench_BlockName.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleLights)
{
profile = "GuiCheckBoxProfile";
position = "244 60";
extent = "42 22";
command = "ND_Wrench_BlockLights.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleEmitters)
{
profile = "GuiCheckBoxProfile";
position = "244 90";
extent = "42 22";
command = "ND_Wrench_BlockEmitters.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleEmitterDir)
{
profile = "GuiCheckBoxProfile";
position = "244 110";
extent = "42 22";
command = "ND_Wrench_BlockEmitterDir.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleItems)
{
profile = "GuiCheckBoxProfile";
position = "244 150";
extent = "42 22";
command = "ND_Wrench_BlockItems.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleItemPos)
{
profile = "GuiCheckBoxProfile";
position = "244 170";
extent = "42 22";
command = "ND_Wrench_BlockItemPos.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleItemDir)
{
profile = "GuiCheckBoxProfile";
position = "244 190";
extent = "42 22";
command = "ND_Wrench_BlockItemDir.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleItemTime)
{
profile = "GuiCheckBoxProfile";
position = "244 210";
extent = "42 22";
command = "ND_Wrench_BlockItemTime.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleRayCasting)
{
profile = "GuiCheckBoxProfile";
position = "244 240";
extent = "42 22";
command = "ND_Wrench_BlockRaycasting.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleCollision)
{
profile = "GuiCheckBoxProfile";
position = "244 260";
extent = "42 22";
command = "ND_Wrench_BlockCollision.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiCheckBoxCtrl(ND_Wrench_ToggleRendering)
{
profile = "GuiCheckBoxProfile";
position = "244 280";
extent = "42 22";
command = "ND_Wrench_BlockRendering.setVisible(!$ThisControl.getValue());";
text = "Apply";
buttonType = "ToggleButton";
};
new GuiSwatchCtrl(ND_Wrench_BlockName)
{
profile = "GuiDefaultProfile";
position = "11 32";
extent = "233 24";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockLights)
{
profile = "GuiDefaultProfile";
position = "11 60";
extent = "233 24";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockEmitters)
{
profile = "GuiDefaultProfile";
position = "11 89";
extent = "233 24";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockEmitterDir)
{
profile = "GuiDefaultProfile";
position = "11 114";
extent = "233 24";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockItems)
{
profile = "GuiDefaultProfile";
position = "11 149";
extent = "233 24";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockItemPos)
{
profile = "GuiDefaultProfile";
position = "11 173";
extent = "233 20";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockItemDir)
{
profile = "GuiDefaultProfile";
position = "11 191";
extent = "233 20";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockItemTime)
{
profile = "GuiDefaultProfile";
position = "11 212";
extent = "233 20";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockRaycasting)
{
profile = "GuiDefaultProfile";
position = "11 242";
extent = "233 20";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockCollision)
{
profile = "GuiDefaultProfile";
position = "11 262";
extent = "233 20";
color = "200 200 200 200";
};
new GuiSwatchCtrl(ND_Wrench_BlockRendering)
{
profile = "GuiDefaultProfile";
position = "11 282";
extent = "233 20";
color = "200 200 200 200";
};
new GuiBitmapButtonCtrl(ND_Wrench_Cancel)
{
profile = "BlockButtonProfile";
position = "16 317";
extent = "91 38";
command = "canvas.popDialog(ND_WrenchDlg);";
accelerator = "escape";
text = "<< Cancel";
buttonType = "PushButton";
bitmap = "base/client/ui/button2";
mColor = "255 255 255 255";
};
new GuiBitmapButtonCtrl(ND_Wrench_Send)
{
profile = "BlockButtonProfile";
position = "119 317";
extent = "160 38";
command = "ndSendFillWrenchData();";
text = "Apply Selected to All >>";
buttonType = "PushButton";
bitmap = "base/client/ui/button1";
mColor = "255 255 255 255";
};
};
};

View File

@ -0,0 +1,33 @@
// Responds to the handshake request sent by the server.
// -------------------------------------------------------------------
//Assume server doesn't have the new duplicator
$ND::ServerVersion = "0.0.0";
$ND::ServerHasND = false;
//Receive handshake from server
function clientCmdNdHandshake(%serverVersion)
{
$ND::ServerVersion = %serverVersion;
$ND::ServerHasND = true;
// Prevent servers from pestering us about version mismatches by pretending to have the same version as them.
// The version is basically not used for anything else, so need to send our actual version.
//commandToServer('ndHandshake', $ND::Version);
commandToServer('ndHandshake', %serverVersion);
}
package NewDuplicator_Client
{
//Reset server version on leaving server
function disconnectedCleanup(%bool)
{
$ND::ServerVersion = "0.0.0";
$ND::ServerHasND = false;
//Disable the keybinds
clientCmdNdEnableKeybinds(false);
parent::disconnectedCleanup(%bool);
}
};

164
scripts/client/wrench.cs Normal file
View File

@ -0,0 +1,164 @@
// Prepares the fillWrench gui and handles submitting the settings.
// -------------------------------------------------------------------
package NewDuplicator_Client
{
function clientCmdWrench_LoadMenus()
{
parent::clientCmdWrench_LoadMenus();
$ND::WrenchReloadRequired = true;
}
};
//Open the wrench gui for fill wrench mode
function clientCmdNdOpenWrenchGui()
{
if($ND::WrenchReloadRequired)
{
//Reload the drop down lists
ND_Wrench_Lights.clear();
ND_Wrench_Emitters.clear();
ND_Wrench_Items.clear();
ND_Wrench_Lights.add(" NONE", 0);
ND_Wrench_Emitters.add(" NONE", 0);
ND_Wrench_Items.add(" NONE", 0);
//Add all datablocks to list
%cnt = getDatablockGroupSize();
for(%i = 0; %i < %cnt; %i++)
{
%data = getDatablock(%i);
%uiName = %data.uiName;
//Skip non-selectable datablocks
if(%uiName $= "")
continue;
//Put datablock in correct list
switch$(%data.getClassName())
{
case "FxLightData":
ND_Wrench_Lights.add(%uiName, %data);
case "ParticleEmitterData":
ND_Wrench_Emitters.add(%uiName, %data);
case "ItemData":
ND_Wrench_Items.add(%uiName, %data);
}
}
//Sort lists
ND_Wrench_Lights.sort();
ND_Wrench_Emitters.sort();
ND_Wrench_Items.sort();
//Select NONE
ND_Wrench_Lights.setSelected(0);
ND_Wrench_Emitters.setSelected(0);
ND_Wrench_Items.setSelected(0);
$ND::WrenchReloadRequired = false;
}
//Open gui
Canvas.pushDialog(ND_WrenchDlg);
}
//Send the settings to the server
function ndSendFillWrenchData()
{
//Close gui
Canvas.popDialog(ND_WrenchDlg);
//Pack all enabled settings in string
%str = "";
if(ND_Wrench_ToggleName.getValue())
%str = %str TAB "N" SPC trim(ND_Wrench_Name.getValue());
if(ND_Wrench_ToggleLights.getValue())
%str = %str TAB "LDB" SPC ND_Wrench_Lights.getSelected();
if(ND_Wrench_ToggleEmitters.getValue())
%str = %str TAB "EDB" SPC ND_Wrench_Emitters.getSelected();
if(ND_Wrench_ToggleEmitterDir.getValue())
{
%dir = -1;
for(%i = 0; %i < 6; %i++)
{
%obj = "ND_Wrench_EmitterDir" @ %i;
if(%obj.getValue())
{
%dir = %i;
break;
}
}
if(%dir >= 0)
%str = %str TAB "EDIR" SPC %dir;
}
if(ND_Wrench_ToggleItems.getValue())
%str = %str TAB "IDB" SPC ND_Wrench_Items.getSelected();
if(ND_Wrench_ToggleItemPos.getValue())
{
%pos = -1;
for(%i = 0; %i < 6; %i++)
{
%obj = "ND_Wrench_ItemPos" @ %i;
if(%obj.getValue())
{
%pos = %i;
break;
}
}
if(%pos >= 0)
%str = %str TAB "IPOS" SPC %pos;
}
if(ND_Wrench_ToggleItemDir.getValue())
{
%dir = -1;
for(%i = 2; %i < 6; %i++)
{
%obj = "ND_Wrench_ItemDir" @ %i;
if(%obj.getValue())
{
%dir = %i;
break;
}
}
if(%dir >= 2)
%str = %str TAB "IDIR" SPC %dir;
}
if(ND_Wrench_ToggleItemTime.getValue())
%str = %str TAB "IRT" SPC trim(ND_Wrench_ItemTime.getValue()) * 1;
if(ND_Wrench_ToggleRayCasting.getValue())
%str = %str TAB "RC" SPC ND_Wrench_RayCasting.getValue();
if(ND_Wrench_ToggleCollision.getValue())
%str = %str TAB "C" SPC ND_Wrench_Collision.getValue();
if(ND_Wrench_ToggleRendering.getValue())
%str = %str TAB "R" SPC ND_Wrench_Rendering.getValue();
//Send string
if(strLen(%str))
commandToServer('ndStartFillWrench', trim(%str));
}

View File

@ -1,3 +1,5 @@
//bls 3
// General server commands used to control the new duplicator.
// -------------------------------------------------------------------
@ -7,7 +9,7 @@
//Shows version of blockland and the new duplicator
function serverCmdDupVersion(%client)
{
messageClient(%client, '', "\c6Blockland version: \c3r" @ getBuildNumber());
//messageClient(%client, '', "\c6Blockland version: \c3r" @ getBuildNumber());
messageClient(%client, '', "\c6New duplicator version: \c3" @ $ND::Version);
if(%client.ndClient)
@ -17,19 +19,19 @@ function serverCmdDupVersion(%client)
}
//Shows versions of other clients
function serverCmdDupClients(%client)
{
messageClient(%client, '', "\c6New duplicator versions:");
%cnt = ClientGroup.getCount();
for(%i = 0; %i < %cnt; %i++)
{
%cl = ClientGroup.getObject(%i);
if(%cl.ndClient)
messageClient(%client, '', "\c3" @ %cl.name @ "\c6 has \c3" @ %cl.ndVersion);
}
}
//function serverCmdDupClients(%client)
//{
// messageClient(%client, '', "\c6New duplicator versions:");
//
// %cnt = ClientGroup.getCount();
// for(%i = 0; %i < %cnt; %i++)
// {
// %cl = ClientGroup.getObject(%i);
//
// if(%cl.ndClient)
// messageClient(%client, '', "\c3" @ %cl.name @ "\c6 has \c3" @ %cl.ndVersion);
// }
//}
//Shows list of commands
function serverCmdDupHelp(%client)
@ -74,8 +76,8 @@ function serverCmdDupHelp(%client)
}
//Alternative short commands
function serverCmdDV(%client){serverCmdDupVersion(%client);}
function serverCmdDC(%client){serverCmdDupClients(%client);}
//function serverCmdDV(%client){serverCmdDupVersion(%client);}
//function serverCmdDC(%client){serverCmdDupClients(%client);}
function serverCmdDH(%client){serverCmdDupHelp(%client);}
@ -89,27 +91,33 @@ function serverCmdNewDuplicator(%client)
//Check admin
if($Pref::Server::ND::AdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6The new duplicator is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6The new duplicator is admin only. Ask an admin for help.");
return;
}
//Check minigame
if(isObject(%client.minigame) && !%client.minigame.enablebuilding)
{
messageClient(%client, '', "\c6You cannot use the new duplicator while building is disabled in your minigame.");
ndmessageClient(%client, '', "\c6You cannot use the new duplicator while building is disabled in your minigame.");
return;
}
//Check player
if(!isObject(%player = %client.player))
{
messageClient(%client, '', "\c6You must be spawned to equip the new duplicator.");
ndmessageClient(%client, '', "\c6You must be spawned to equip the new duplicator.");
return;
}
//Hide brick selector and tool gui
// Abort if already holding the dup
if(isObject(%player.getMountedImage(0)) && getSubStr(%player.getMountedImage(0).getName(), 0, 8) $= "ND_Image")
return;
// If a tool is equipped, hide brick selector and tool gui
if(isObject(%player.getMountedImage(0))) {
%client.ndLastEquipTime = $Sim::Time;
commandToClient(%client, 'setScrollMode', 3);
}
//Give player a duplicator
%image = %client.ndImage;
@ -224,7 +232,8 @@ package NewDuplicator_Server
if(%obj.brickCount > 10 && %client.ndUndoConfirm != %obj)
{
messageClient(%client, '', "\c6Next undo will affect \c3" @ %obj.brickCount @ "\c6 bricks. Press undo again to continue.");
//messageClient(%client, '', "\c6Next undo will affect \c3" @ %obj.brickCount @ "\c6 bricks. Press undo again to continue.");
commandToClient(%client, 'centerPrint', "<font:Verdana:20>\c6Next undo will affect \c3" @ %obj.brickCount @ "\c6 bricks. Press undo again to continue.", 4);
%client.undoStack.push(%state);
%client.ndUndoConfirm = %obj;
return;
@ -237,7 +246,8 @@ package NewDuplicator_Server
%client.ndUndoConfirm = 0;
}else{
talk("serverCmdUndoBrick(" @ %client.name @ ") - Nonexistent undo state " @ %state);
// seems to happen when you SC a plant and then undo it
//talk("serverCmdUndoBrick(" @ %client.name @ ") - Nonexistent undo state " @ %state);
}
return;
}
@ -306,19 +316,19 @@ function serverCmdSuperCut(%client)
{
if(%client.ndModeIndex != $NDM::BoxSelect)
{
messageClient(%client, '', "\c6Supercut can only be used on box selection mode.");
ndmessageClient(%client, '', "\c6Supercut can only be used on box selection mode.");
return;
}
if(!isObject(%client.ndSelectionBox))
{
messageClient(%client, '', "\c6Supercut can only be used with a selection box.");
ndmessageClient(%client, '', "\c6Supercut can only be used with a selection box.");
return;
}
if(%client.ndSelectionAvailable)
{
messageClient(%client, '', "\c6Supercut can not be used with any bricks selected.");
ndmessageClient(%client, '', "\c6Supercut can not be used with any bricks selected.");
return;
}
@ -333,19 +343,19 @@ function serverCmdNdConfirmSuperCut(%client)
{
if(%client.ndModeIndex != $NDM::BoxSelect)
{
messageClient(%client, '', "\c6Supercut can only be used on box selection mode.");
ndmessageClient(%client, '', "\c6Supercut can only be used on box selection mode.");
return;
}
if(!isObject(%client.ndSelectionBox))
{
messageClient(%client, '', "\c6Supercut can only be used with a selection box.");
ndmessageClient(%client, '', "\c6Supercut can only be used with a selection box.");
return;
}
if(%client.ndSelectionAvailable)
{
messageClient(%client, '', "\c6Supercut can not be used with any bricks selected.");
ndmessageClient(%client, '', "\c6Supercut can not be used with any bricks selected.");
return;
}
@ -363,25 +373,25 @@ function serverCmdFillBricks(%client, %conf, %subsetname)
{
if($Pref::Server::ND::FillBricksAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Fill Bricks is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Fill Bricks is admin only. Ask an admin for help.");
return;
}
if(!isObject(%client.ndSelectionBox))
{
messageClient(%client, '', "\c6The fillBricks command can only be used with a selection box.");
ndmessageClient(%client, '', "\c6The fillBricks command can only be used with a selection box.");
return;
}
if(%client.ndSelectionAvailable)
{
messageClient(%client, '', "\c6The fillBricks command can not be used with any bricks selected.");
ndmessageClient(%client, '', "\c6The fillBricks command can not be used with any bricks selected.");
return;
}
if(!%client.ndSelectionBox.hasVolume())
{
messageClient(%client, '', "\c6The fillBricks command can only be used with a selection box that has a volume.");
ndmessageClient(%client, '', "\c6The fillBricks command can only be used with a selection box that has a volume.");
return;
}
@ -403,25 +413,25 @@ function serverCmdNdConfirmFillBricks(%client, %subsetname)
{
if($Pref::Server::ND::FillBricksAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Fill Bricks is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Fill Bricks is admin only. Ask an admin for help.");
return;
}
if(!isObject(%client.ndSelectionBox))
{
messageClient(%client, '', "\c6The fillBricks command can only be used with a selection box.");
ndmessageClient(%client, '', "\c6The fillBricks command can only be used with a selection box.");
return;
}
if(%client.ndSelectionAvailable)
{
messageClient(%client, '', "\c6The fillBricks command can not be used with any bricks selected.");
ndmessageClient(%client, '', "\c6The fillBricks command can not be used with any bricks selected.");
return;
}
if(!%client.ndSelectionBox.hasVolume())
{
messageClient(%client, '', "\c6The fillBricks command can only be used with a selection box that has a volume.");
ndmessageClient(%client, '', "\c6The fillBricks command can only be used with a selection box that has a volume.");
return;
}
@ -494,7 +504,7 @@ function GameConnection::ndMirror(%client, %axis)
if(!$ND::SymmetryTableCreating)
ndCreateSymmetryTable();
messageClient(%client, '', "\c6Please wait for the symmetry table to finish, then mirror again.");
ndmessageClient(%client, '', "\c6Please wait for the symmetry table to finish, then mirror again.");
return;
}
@ -513,7 +523,7 @@ function GameConnection::ndMirror(%client, %axis)
}
//We didn't mirror anything
messageClient(%client, '', "\c6The mirror command can only be used in plant mode or with a ghost brick.");
ndmessageClient(%client, '', "\c6The mirror command can only be used in plant mode or with a ghost brick.");
}
//List potential mirror errors in last plant
@ -555,6 +565,29 @@ function serverCmdME(%client){serverCmdMirErrors(%client);}
///////////////////////////////////////////////////////////////////////////
// Ownership
function serverCmdOwnership(%client) {
if(%client.ndModeIndex != $NDM::PlantCopy) {
ndmessageClient(%client, '', "\c6Ownership plant can only be used in Plant Mode.");
return;
}
if(!%client.isAdmin) {
ndmessageClient(%client, '', "\c6Ownership plant is admin only.");
return;
}
%client.ndOwnership = !%client.ndOwnership;
if(%client.ndOwnership) {
ndmessageClient(%client, '', "\c6Bricks will now be planted in the group of the original owner.");
} else {
ndmessageClient(%client, '', "\c6Bricks will now be planted in your own group.");
}
%client.ndUpdateBottomPrint();
}
function serverCmdOwn(%client) { serverCmdOwnership(%client); }
function serverCmdO(%client) { serverCmdOwnership(%client); }
//Force plant
///////////////////////////////////////////////////////////////////////////
@ -564,18 +597,18 @@ function serverCmdForcePlant(%client)
//Check mode
if(%client.ndModeIndex != $NDM::PlantCopy)
{
messageClient(%client, '', "\c6Force Plant can only be used in Plant Mode.");
ndmessageClient(%client, '', "\c6Force Plant can only be used in Plant Mode.");
return;
}
//Check admin
if($Pref::Server::ND::FloatAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Force Plant is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Force Plant is admin only. Ask an admin for help.");
return;
}
NDM_PlantCopy.conditionalPlant(%client, true);
NDM_PlantCopy.conditionalPlant(%client, true, false);
}
//Alternative short command
@ -587,16 +620,16 @@ function serverCmdToggleForcePlant(%client)
//Check admin
if($Pref::Server::ND::FloatAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Force Plant is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Force Plant is admin only. Ask an admin for help.");
return;
}
%client.ndForcePlant = !%client.ndForcePlant;
if(%client.ndForcePlant)
messageClient(%client, '', "\c6Force Plant has been enabled. Use \c3/toggleForcePlant\c6 to disable it.");
ndmessageClient(%client, '', "\c6Force Plant has been enabled. Use \c3/toggleForcePlant\c6 to disable it.");
else
messageClient(%client, '', "\c6Force Plant has been disabled. Use \c3/toggleForcePlant\c6 to enable it again.");
ndmessageClient(%client, '', "\c6Force Plant has been disabled. Use \c3/toggleForcePlant\c6 to enable it again.");
}
//Alternative short command
@ -672,34 +705,34 @@ function serverCmdFillWrench(%client)
//Check version
if(!%client.ndClient)
{
messageClient(%client, '', "\c6You need to have the new duplicator installed to use Fill Wrench.");
ndmessageClient(%client, '', "\c6You need to have the new duplicator installed to use Fill Wrench.");
return;
}
if(ndCompareVersion("1.2.0", %client.ndVersion) == 1)
{
messageClient(%client, '', "\c6Your version of the new duplicator is too old to use Fill Wrench.");
ndmessageClient(%client, '', "\c6Your version of the new duplicator is too old to use Fill Wrench.");
return;
}
//Check admin
if($Pref::Server::ND::WrenchAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Fill Wrench is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Fill Wrench is admin only. Ask an admin for help.");
return;
}
//Check mode
if(%client.ndModeIndex != $NDM::StackSelect && %client.ndModeIndex != $NDM::BoxSelect)
{
messageClient(%client, '', "\c6Fill Wrench can only be used in Selection Mode.");
ndmessageClient(%client, '', "\c6Fill Wrench can only be used in Selection Mode.");
return;
}
//Check selection
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
{
messageClient(%client, '', "\c6Fill Wrench can only be used with a selection.");
ndmessageClient(%client, '', "\c6Fill Wrench can only be used with a selection.");
return;
}
@ -716,21 +749,21 @@ function serverCmdNdStartFillWrench(%client, %data)
//Check admin
if($Pref::Server::ND::WrenchAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Fill Wrench is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Fill Wrench is admin only. Ask an admin for help.");
return;
}
//Check mode
if(%client.ndModeIndex != $NDM::StackSelect && %client.ndModeIndex != $NDM::BoxSelect)
{
messageClient(%client, '', "\c6Fill Wrench can only be used in Selection Mode.");
ndmessageClient(%client, '', "\c6Fill Wrench can only be used in Selection Mode.");
return;
}
//Check selection
if(!isObject(%client.ndSelection) || !%client.ndSelection.brickCount)
{
messageClient(%client, '', "\c6Fill Wrench can only be used with a selection.");
ndmessageClient(%client, '', "\c6Fill Wrench can only be used with a selection.");
return;
}
@ -757,21 +790,21 @@ package NewDuplicator_Server_Final
if(%remain != 1)
%s = "s";
messageClient(%client, '', "\c6Please wait\c3 " @ %remain @ "\c6 second" @ %s @ " before saving again!");
ndmessageClient(%client, '', "\c6Please wait\c3 " @ %remain @ "\c6 second" @ %s @ " before saving again!");
return;
}
//Check admin
if($Pref::Server::ND::SaveAdminOnly && !%client.isAdmin)
{
messageClient(%client, '', "\c6Saving duplications is admin only. Ask an admin for help.");
ndmessageClient(%client, '', "\c6Saving duplications is admin only. Ask an admin for help.");
return;
}
//Check mode
if(%client.ndModeIndex != $NDM::PlantCopy)
{
messageClient(%client, '', "\c6Saving duplications can only be used in Plant Mode.");
ndmessageClient(%client, '', "\c6Saving duplications can only be used in Plant Mode.");
return;
}
@ -958,7 +991,7 @@ function ND_SaveFileInfo(%filename) {
%info = $ND::FileDate[%filename];
%info_aftername = getSubStr(%info, strStr(%info, " (")+2, strLen(%info));
%date = getSubStr(%info_aftername, strLen(%info_aftername)-17, 17);
%blid = getSubStr(%info_aftername, 0, strStr(%info_aftername, ")"));
//%blid = getSubStr(%info_aftername, 0, strStr(%info_aftername, ")"));
%name = getSubStr(%info, 9, strStr(%info, " (") - 9);
// Fix date format for sorting
@ -970,7 +1003,7 @@ function ND_SaveFileInfo(%filename) {
%filetext = %sort @
"\c3" @ %namepart TAB
"\c3" @ %name TAB
"\c6" @ %blid TAB
//"\c6" @ %blid TAB
"\c6" @ %date
;
@ -1031,7 +1064,7 @@ function serverCmdAllDups(%client, %pattern)
%format = "<tab:400,550,650,750>";
if(%fileCount>0) {
messageClient(%client, '', %format @ "\c6Name\t\c6Saved By\t\c6BL_ID\t\c6Date");
messageClient(%client, '', %format @ "\c6Name\t\c6Saved By\t\t\c6Date");
}
for(%i = 0; %i < %fileCount; %i++) {
%text = %sort.getRowText(%i);
@ -1064,6 +1097,7 @@ function serverCmdAD(%client, %pattern) {serverCmdAllDups(%client, %pattern);}
//Cancel all active dups in case of spamming
function serverCmdClearDups(%client)
{
echo("serverCmdClearDups " @ %client.name);
if(!%client.isAdmin)
{
messageClient(%client, '', "\c6Canceling all duplicators is admin only. Ask an admin for help.");
@ -1084,6 +1118,7 @@ function serverCmdClearDups(%client)
//Plant as a different brick group
function serverCmdPlantAs(%client, %t0, %t1, %t2, %t3, %t4)
{
echo("serverCmdPlantAs " @ %client.name @ " - " @ %t0 SPC %t1 SPC %t2 SPC %t3 SPC %t4);
//Check mode
if(%client.ndModeIndex != $NDM::PlantCopy)
{
@ -1119,7 +1154,7 @@ function serverCmdPlantAs(%client, %t0, %t1, %t2, %t3, %t4)
if(!isObject(%targetGroup))
{
messageClient(%client, '', "\c6No brick group was found for \"\c3" @ %target @ "\c6\".");
messageClient(%client, '', "\c6Bricks will be planted in your own group!");
ndmessageClient(%client, '', "\c6Bricks will be planted in your own group!");
%client.ndSelection.targetGroup = "";
%client.ndSelection.targetBlid = "";
%client.ndUpdateBottomPrint();

View File

@ -1,6 +1,12 @@
// This file should not exist. Fix later...
//bls 3
// -------------------------------------------------------------------
// Utility
function ndmessageClient(%client, %ignore, %msg) {
commandToClient(%client, 'centerPrint', "<font:Verdana:20>" @ %msg, 4);
}
//Math functions
///////////////////////////////////////////////////////////////////////////
@ -33,6 +39,21 @@ function ndTransformDirection(%dir, %steps, %mirrX, %mirrY, %mirrZ)
return %dir;
}
function ndColorFToI(%f){
%i = %f*255;
%i = mFloor(%i + 0.5);
return %i;
}
function ndGetColorI(%color){
%color2 =
ndColorFToI(getWord(%color, 0)) SPC
ndColorFToI(getWord(%color, 1)) SPC
ndColorFToI(getWord(%color, 2)) SPC
ndColorFToI(getWord(%color, 3))
;
}
//Get the closest paint color to an rgb value
function ndGetClosestColorID(%rgb)
{
@ -42,7 +63,7 @@ function ndGetClosestColorID(%rgb)
for(%i = 0; %i < 64; %i++)
{
%color = getColorI(getColorIdTable(%i));
%color = ndGetColorI(getColorIdTable(%i));
%diff = vectorLen(vectorSub(%rgb, %color));
@ -71,7 +92,7 @@ function ndGetClosestColorID2(%rgba)
for(%i = 0; %i < 64; %i++)
{
%color = getColorI(getColorIdTable(%i));
%color = ndGetColorI(getColorIdTable(%i));
%alpha = getWord(%color, 3);
%diff = vectorLen(vectorSub(%rgb, %color));
@ -292,7 +313,7 @@ function FxDtsBrick::ndMirrorGhost(%brick, %client, %axis)
}
else
{
messageClient(%client, '', "\c6Sorry, your ghost brick is asymmetric and cannot be mirrored.");
ndmessageClient(%client, '', "\c6Sorry, your ghost brick is asymmetric and cannot be mirrored.");
return;
}
@ -341,7 +362,7 @@ function FxDtsBrick::ndMirrorGhost(%brick, %client, %axis)
}
else
{
messageClient(%client, '', "\c6Sorry, your ghost brick is asymmetric and cannot be mirrored.");
ndmessageClient(%client, '', "\c6Sorry, your ghost brick is asymmetric and cannot be mirrored.");
return;
}
@ -384,7 +405,7 @@ function FxDtsBrick::ndMirrorGhost(%brick, %client, %axis)
}
else
{
messageClient(%client, '', "\c6Sorry, your ghost brick is not vertically symmetric and cannot be mirrored.");
ndmessageClient(%client, '', "\c6Sorry, your ghost brick is not vertically symmetric and cannot be mirrored.");
return;
}
}
@ -443,6 +464,7 @@ function ndCreateSimpleBrickTable()
}
%db.ndSubset = ndSubsetOfDatablock(%db);
if(%db.ndSubset $= "") continue;
%file.openForRead(%db.brickFile);
%file.readLine();
@ -694,34 +716,41 @@ function GameConnection::doFillBricks(%this, %subset)
%box = %this.ndSelectionBox.getWorldBox();
$ND::FillBrickCount = 0;
ndUpdateSpawnedClientList();
ndFillAreaWithBricks(getWords(%box, 0, 2), getWords(%box, 3, 5));
//%s = ($ND::FillBrickCount == 1 ? "" : "s");
//messageClient(%this, '', "\c6Filled in \c3" @ $ND::FillBrickCount @ "\c6 brick" @ %s);
if(%subset == $ND::SubsetLogicBus) {
$ND::FillBrickSubset = $ND::SubsetLogicWire;
ndFillBus(getWords(%box, 0, 2), getWords(%box, 3, 5), getAngleIDFromPlayer(%this.getControlObject()), %this.currentColor);
} else {
ndFillAreaWithBricks(getWords(%box, 0, 2), getWords(%box, 3, 5));
}
%s = ($ND::FillBrickCount == 1 ? "" : "s");
ndmessageClient(%this, '', "\c6Filled in \c3" @ $ND::FillBrickCount @ "\c6 brick" @ %s);
}
$ND::SubsetDefault = 0;
$ND::SubsetLogicWire = 1;
$ND::SubsetLogicBuffer = 2;
$ND::SubsetLogicBufferAl = 3;
$ND::SubsetLogicDff = 4;
$ND::SubsetLogicDffAl = 5;
$ND::SubsetLogicEnabler = 6;
$ND::SubsetLogicEnablerAl = 7;
$ND::SubsetLogicBus = 2;
//$ND::SubsetLogicBuffer = 2;
//$ND::SubsetLogicBufferAl = 3;
//$ND::SubsetLogicDff = 4;
//$ND::SubsetLogicDffAl = 5;
//$ND::SubsetLogicEnabler = 6;
//$ND::SubsetLogicEnablerAl = 7;
// Which subset of fill bricks to use - normal or wire
function ndSubsetOfDatablock(%data){
if(%data.isLogic) {
if(%data.isLogicWire) {
return $ND::SubsetLogicWire;
} else if(strStr(%data.uiName, "Buffer") == 0) {
return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicBuffer : $ND::SubsetLogicBufferAl;
} else if(strStr(%data.uiName, "D FlipFlop") == 0) {
return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicDff : $ND::SubsetLogicDffAl;
}else if(strStr(%data.uiName, "Enabler") == 0) {
return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicEnabler : $ND::SubsetLogicEnablerAl;
//} else if(strStr(%data.uiName, "Buffer") == 0) {
// return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicBuffer : $ND::SubsetLogicBufferAl;
//} else if(strStr(%data.uiName, "D FlipFlop") == 0) {
// return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicDff : $ND::SubsetLogicDffAl;
//}else if(strStr(%data.uiName, "Enabler") == 0) {
// return (strStr(%data.uiName, "Active Low")==-1) ? $ND::SubsetLogicEnabler : $ND::SubsetLogicEnablerAl;
} else {
return $ND::SubsetDefault;
return "";
}
} else {
return $ND::SubsetDefault;

View File

@ -17,28 +17,30 @@ package NewDuplicator_Server
//Client responded, so he has new duplicator
function serverCmdNdHandshake(%this, %version)
{
echo("serverCmdNdHandshake " @ %this.name @ " - " @ %version);
cancel(%this.ndHandshakeTimeout);
%this.ndClient = true;
%this.ndVersion = %version;
//Inform client whether he has an outdated version
switch(ndCompareVersion($ND::Version, %version))
{
case 1:
%m = "\c6Your version of the \c3New Duplicator\c6 is outdated! Some features might not work. ";
%m = %m @ "(Server Version: \c3" @ $ND::Version @ "\c6 | Your Version: \c0" @ %version @ "\c6)";
//messageClient(%this, '', %m);
case 2:
//Hide this message on long-running dedicated servers
if($Sim::Time < 86400)
{
%m = "\c6Your version of the \c3New Duplicator\c6 is newer than the server's! Ask the host to update it! ";
%m = %m @ "(Server Version: \c0" @ $ND::Version @ "\c6 | Your Version: \c3" @ %version @ "\c6)";
//messageClient(%this, '', %m);
}
}
// nobody gives a shit
//switch(ndCompareVersion($ND::Version, %version))
//{
// case 1:
// %m = "\c6Your version of the \c3New Duplicator\c6 is outdated! Some features might not work. ";
// %m = %m @ "(Server Version: \c3" @ $ND::Version @ "\c6 | Your Version: \c0" @ %version @ "\c6)";
// messageClient(%this, '', %m);
//
// case 2:
// //Hide this message on long-running dedicated servers
// if($Sim::Time < 86400)
// {
// %m = "\c6Your version of the \c3New Duplicator\c6 is newer than the server's! Ask the host to update it! ";
// %m = %m @ "(Server Version: \c0" @ $ND::Version @ "\c6 | Your Version: \c3" @ %version @ "\c6)";
// messageClient(%this, '', %m);
// }
//}
}
//Compares two version numbers (major.minor.patch)

View File

@ -1,3 +1,4 @@
//bls 3
// Handles interactions with the handheld duplicator item.
// -------------------------------------------------------------------
@ -230,12 +231,19 @@ package NewDuplicator_Server
//Prevent accidently unequipping the duplicator
function serverCmdUnUseTool(%client)
{
if(%client.ndLastEquipTime + 1.5 > $Sim::Time)
if(
%client.ndLastEquipTime + 1.5 > $Sim::Time &&
isObject(%client.player) &&
getSubStr(%client.player.getMountedImage(0).getName(), 0, 8) $= "ND_Image"
) {
%client.ndLastEquipTime = "";
return;
}
if(%client.ndModeIndex == $NDM::StackSelect || %client.ndModeIndex == $NDM::BoxSelect)
{
%client.ndToolSchedule = %client.schedule(100, ndUnUseTool);
//%client.ndToolSchedule = %client.schedule(100, ndUnUseTool);
%client.ndUnUseTool();
return;
}

View File

@ -0,0 +1,29 @@
//bls 3
//function ndRotateVector(%vector, %steps)
function ndFillBus(%pos1, %pos2, %angleId, %color) {
talk(%pos1 @ ", " @ %pos2 @ ", " @ %angleId);
$ND::FillBrickColorID = %color + 1;
ndFillAreaWithBricks(%pos1, %pos2);
}
function ndNormalizeBox(%box) {
%x1 = getWord(%box, 0);
%y1 = getWord(%box, 1);
%z1 = getWord(%box, 2);
%x2 = getWord(%box, 3);
%y2 = getWord(%box, 4);
%z2 = getWord(%box, 5);
return
mMin(%x1, %x2) SPC
mMin(%y1, %y2) SPC
mMin(%z1, %z2) SPC
mMax(%x1, %x2) SPC
mMax(%y1, %y2) SPC
mMax(%z1, %z2) ;
}
function ndFillAreaWithBricks_box(%pos, %boxSize) {
%boxHalf = vectorScale(%boxSize, 0.5);
%box = vectorSub(%pos, %boxHalf) SPC vectorAdd(%pos, %boxHalf);
ndFillAreaWithBricks(getWords(%box, 0, 2), getWords(%box, 3, 5));
}

View File

@ -21,17 +21,17 @@ function NewDuplicatorMode::onCancelBrick(%this, %client){}
function NewDuplicatorMode::onCopy(%this, %client)
{
messageClient(%client, '', "\c6Copy can not be used in your current duplicator mode.");
ndmessageClient(%client, '', "\c6Copy can not be used in your current duplicator mode.");
}
function NewDuplicatorMode::onPaste(%this, %client)
{
messageClient(%client, '', "\c6Paste can not be used in your current duplicator mode.");
ndmessageClient(%client, '', "\c6Paste can not be used in your current duplicator mode.");
}
function NewDuplicatorMode::onCut(%this, %client)
{
messageClient(%client, '', "\c6Cut can not be used in your current duplicator mode.");
ndmessageClient(%client, '', "\c6Cut can not be used in your current duplicator mode.");
}
function NewDuplicatorMode::getBottomPrint(%this, %client){}

View File

@ -48,7 +48,7 @@ function ndRegisterPrefsToRtb()
RTB_registerPref("Scatter Ghost Bricks", "New Duplicator | Advanced", "$Pref::Server::ND::ScatterGhostBricks", "bool", "Tool_NewDuplicator", true, false, false, "");
RTB_registerPref("Process Bricks per Tick", "New Duplicator | Advanced", "$Pref::Server::ND::ProcessPerTick", "int 1 50000", "Tool_NewDuplicator", 300, false, false, "");
RTB_registerPref("Box Selection Chunk Size", "New Duplicator | Advanced", "$Pref::Server::ND::BoxSelectChunkDim", "int 1 50000", "Tool_NewDuplicator", 6, false, false, "");
RTB_registerPref("Create Sym Table on Start", "New Duplicator | Advanced", "$Pref::Server::ND::SymTableOnStart", "bool", "Tool_NewDuplicator", false, false, false, "");
RTB_registerPref("Create Sym Table on Start", "New Duplicator | Advanced", "$Pref::Server::ND::SymTableOnStart", "bool", "Tool_NewDuplicator", true, false, false, "");
//Restore default prefs
RTB_registerPref("Check to restore defaults", "New Duplicator | Reset Prefs", "$ND::RestoreDefaultPrefs", "bool", "Tool_NewDuplicator", false, false, false, "ndRestoreDefaultPrefs");
@ -96,7 +96,7 @@ function ndExtendDefaultPrefValues()
if($Pref::Server::ND::ScatterGhostBricks $= "") $Pref::Server::ND::ScatterGhostBricks = true;
if($Pref::Server::ND::ProcessPerTick $= "") $Pref::Server::ND::ProcessPerTick = 300;
if($Pref::Server::ND::BoxSelectChunkDim $= "") $Pref::Server::ND::BoxSelectChunkDim = 6;
if($Pref::Server::ND::SymTableOnStart $= "") $Pref::Server::ND::SymTableOnStart = false;
if($Pref::Server::ND::SymTableOnStart $= "") $Pref::Server::ND::SymTableOnStart = true;
//Always set this to false so we don't accidently reset the prefs
$ND::RestoreDefaultPrefs = false;
@ -138,7 +138,7 @@ function ndApplyDefaultPrefValues()
$Pref::Server::ND::ScatterGhostBricks = true;
$Pref::Server::ND::ProcessPerTick = 300;
$Pref::Server::ND::BoxSelectChunkDim = 6;
$Pref::Server::ND::SymTableOnStart = false;
$Pref::Server::ND::SymTableOnStart = true;
//Always set this to false so we don't accidently reset the prefs
$ND::RestoreDefaultPrefs = false;
@ -189,7 +189,7 @@ function ndDeleteOutdatedPrefs()
$Pref::Server::ND::FloatAdminOnly = %floatAdminOnly;
$Pref::Server::ND::SaveAdminOnly = %saveAdminOnly;
$Pref::Server::ND::LoadAdminOnly = %loadAdminOnly;
$Pref::Server::ND::FillBricksAdminOnly = %fillBricksAdminOnl;
$Pref::Server::ND::FillBricksAdminOnly = %fillBricksAdminOnly;
//Settings
$Pref::Server::ND::TrustLimit = %trustLimit;
$Pref::Server::ND::AdminTrustBypass1 = %adminTrustBypass1;

View File

@ -1,7 +1,8 @@
// Executes all required scripts and initializes the server side.
// -------------------------------------------------------------------
$ND::Version = "1.6.2";
// Not updating because it's useless
$ND::Version = "1.6.3";
$ND::FilePath = filePath($Con::File) @ "/";
$ND::ConfigPath = "config/NewDuplicator/";
@ -61,5 +62,3 @@ ndResendHandshakes();
if($Pref::Server::ND::SymTableOnStart && !$ND::SymmetryTableCreated){
schedule(10, 0, ndCreateSymmetryTable);
}
exec("./v20fix.cs");

View File

@ -1,15 +0,0 @@
function colorFToI(%f){
%i = %f*255;
%i = mFloor(%i + 0.5);
return %i;
}
function getColorI(%color){
%color2 =
colorFToI(getWord(%color, 0)) SPC
colorFToI(getWord(%color, 1)) SPC
colorFToI(getWord(%color, 2)) SPC
colorFToI(getWord(%color, 3))
;
}