From f88dbceb61e8bf6e92fee1ade46a0e598d1a0fa9 Mon Sep 17 00:00:00 2001 From: Redo Date: Sat, 19 Jul 2025 01:33:47 -0700 Subject: [PATCH] Add box selection history --- classes/server/duplimode/boxselect.cs | 19 +++++++++- classes/server/duplimode/plantcopy.cs | 8 ++--- classes/server/selection.cs | 9 +++-- readme.md | 13 ++++--- scripts/client/controls.cs | 51 +++++++++++++++------------ scripts/server/commands.cs | 33 ++++++++++++----- scripts/server/modes.cs | 8 ++--- server.cs | 1 + 8 files changed, 91 insertions(+), 51 deletions(-) diff --git a/classes/server/duplimode/boxselect.cs b/classes/server/duplimode/boxselect.cs index c7ab9e9..d792052 100644 --- a/classes/server/duplimode/boxselect.cs +++ b/classes/server/duplimode/boxselect.cs @@ -199,7 +199,9 @@ function NDM_BoxSelect::onSelectObject(%this, %client, %obj, %pos, %normal) } %client.ndSelectionBox.setSizeAligned(%p1, %p2, %client.getControlObject()); + %client.ndPushBoxHistory(); %client.ndUpdateBottomPrint(); + } function ndRound(%v, %step) { @@ -305,6 +307,8 @@ function NDM_BoxSelect::onShiftBrick(%this, %client, %x, %y, %z) { %client.ndSelectionBox.shift(%newX SPC %newY SPC %z); } + + %client.ndBoxChanged(); } //Super Shift Brick @@ -320,6 +324,8 @@ function NDM_BoxSelect::onSuperShiftBrick(%this, %client, %x, %y, %z) } %this.onShiftBrick(%client, %x * 8, %y * 8, %z * 20); + + %client.ndBoxChanged(); } //Rotate Brick @@ -344,7 +350,8 @@ function NDM_BoxSelect::onRotateBrick(%this, %client, %direction) %client.ndSelectionBox.rotate(%direction); %client.ndUpdateBottomPrint(); } - + + %client.ndBoxChanged(); } //Plant Brick @@ -386,6 +393,9 @@ function NDM_BoxSelect::onPlantBrick(%this, %client) //Start selection %box = %client.ndSelectionBox.getWorldBox(); + %client.ndPushBoxHistory(); + %client.ndBoxChanged(); + %client.ndSetMode(NDM_BoxSelectProgress); %client.ndSelection.startBoxSelection(%box, %client.ndLimited); } @@ -410,6 +420,8 @@ function NDM_BoxSelect::onCancelBrick(%this, %client) return; } + %client.ndBoxCleared(); + if(isObject(%client.ndSelection)) %client.ndSelection.deleteData(); @@ -436,8 +448,11 @@ function NDM_BoxSelect::onCut(%this, %client) return; } + %client.ndPushBoxHistory(); + %client.ndSetMode(NDM_CutProgress); %client.ndSelection.startCutting(); + } //Supercut selection @@ -460,6 +475,8 @@ function NDM_BoxSelect::onSuperCut(%this, %client) %client.ndSetMode(NDM_SuperCutProgress); %client.ndSelection.startSuperCut(%box); + + %client.ndBoxChanged(); } diff --git a/classes/server/duplimode/plantcopy.cs b/classes/server/duplimode/plantcopy.cs index ced3c90..86ff30d 100644 --- a/classes/server/duplimode/plantcopy.cs +++ b/classes/server/duplimode/plantcopy.cs @@ -143,10 +143,10 @@ function NDM_PlantCopy::onCancelBrick(%this, %client) } //Paste Selection -function NDM_PlantCopy::onPaste(%this, %client) -{ - %this.onPlantBrick(%client); -} +//function NDM_PlantCopy::onPaste(%this, %client) +//{ +// %this.onPlantBrick(%client); +//} diff --git a/classes/server/selection.cs b/classes/server/selection.cs index aa36651..64b130f 100644 --- a/classes/server/selection.cs +++ b/classes/server/selection.cs @@ -2970,10 +2970,6 @@ function ND_Selection::plantBrick(%this, %i, %position, %angleID, %brickGroup, % //Finished planting all the bricks! function ND_Selection::finishPlant(%this) { - //Report mirror errors - if($NS[%this.client, "MXC"] > 0 || $NS[%this.client, "MZC"] > 0) - ndMessageClient(%this.client, '', "\c6Some bricks were probably mirrored incorrectly. Say \c3/mirErrors\c6 to find out more."); - %count = %this.brickCount; %planted = %this.plantSuccessCount; %blocked = %this.plantBlockedFailCount; @@ -2996,6 +2992,9 @@ function ND_Selection::finishPlant(%this) if(%missing) %message = %message @ "\n\c3" @ %missing @ "\c6 missing Datablock."; + if($NS[%this.client, "MXC"] > 0 || $NS[%this.client, "MZC"] > 0) + %message = %message @ "\n\c6Some bricks were probably mirrored incorrectly. Say \c3/mirErrors\c6 to find out more."; + commandToClient(%this.client, 'centerPrint', %message, 4); if($Pref::Server::ND::PlayMenuSounds && %planted && %this.brickCount > $Pref::Server::ND::ProcessPerTick * 10) @@ -4298,7 +4297,7 @@ function ND_Selection::tickLoadBricks(%this) %db = 0; $NS[%this, "VD", %index] = %db; - $NS[%this, "VC", %index] = mFLoor(getSubStr(%line, %pos + 2, 9999)); + $NS[%this, "VC", %index] = mFloor(getSubStr(%line, %pos + 2, 9999)); //Start reading connections case "ND_SIZE\"": diff --git a/readme.md b/readme.md index 166ff06..15ec774 100644 --- a/readme.md +++ b/readme.md @@ -4,21 +4,25 @@ A fork of the original New Duplicator by Zeblote, presently maintained and with ## 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. +(Loading ownership only works if the duplication was saved with this version, as the original newdup does not save ownership) +Use `/toggleownership` or `/to` to always plant with original ownership, similar to `/toggleforceplant` or `/tfp` +- Added `/prevBox` and `/nextBox` (aliases `/pb` and `/nb`) to recall selection-box history when in box-select mode, similar to pressing up in a chat client or terminal. +- Holding ctrl while making an initial stack selection selects all adjacent bricks of the same color, ignoring diagonals, similar to the fill-can. 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. +- Support for `Event_setZoneBox` +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. +- Removed paste - not sure why it even existed, it was the same as planting. ## Fixes - Fixed "Nonexistent undo state" message when undoing a plant that has been supercut. @@ -26,4 +30,3 @@ Hitting plant with this box updates the first Event_SetZoneBox event if present. - 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. diff --git a/scripts/client/controls.cs b/scripts/client/controls.cs index 1cde87d..d0e51de 100644 --- a/scripts/client/controls.cs +++ b/scripts/client/controls.cs @@ -2,52 +2,47 @@ // ------------------------------------------------------------------- //Register rebind-able controls -function ndRegisterKeybinds() -{ +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] = "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++; @@ -55,11 +50,17 @@ function ndRegisterKeybinds() $RemapName[$RemapCount] = "Send /SuperCut (Shift-Ctrl X)"; $RemapCmd[$RemapCount] = "ndInputSuperCut"; $RemapCount++; - $RemapName[$RemapCount] = "Send /FillBricks (Shift-Ctrl V)"; $RemapCmd[$RemapCount] = "ndInputFillBricks"; $RemapCount++; + $RemapName[$RemapCount] = "Send /NextBox (Ctrl-Up)"; + $RemapCmd[$RemapCount] = "ndInputNextBox"; + $RemapCount++; + $RemapName[$RemapCount] = "Send /PrevBox (Ctrl-Down)"; + $RemapCmd[$RemapCount] = "ndInputPrevBox"; + $RemapCount++; + $ND::KeybindsRegistered = true; } @@ -72,10 +73,8 @@ function clientCmdNdEnableKeybinds(%bool) 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("ndInputPaste") $= "") + // %map.bind("keyboard", isWindows() ? "ctrl v" : "cmd v", "ndInputPaste"); if(MoveMap.getBinding("ndInputCut") $= "") %map.bind("keyboard", isWindows() ? "ctrl x" : "cmd x", "ndInputCut"); @@ -84,10 +83,14 @@ function clientCmdNdEnableKeybinds(%bool) 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"); + if(MoveMap.getBinding("ndInputNextBox") $= "") + %map.bind("keyboard", isWindows() ? "ctrl up" : "cmd up", "ndInputNextBox"); + if(MoveMap.getBinding("ndInputPrevBox") $= "") + %map.bind("keyboard", isWindows() ? "ctrl down" : "cmd down", "ndInputPrevBox"); + %map.push(); $ND::KeybindsEnabled = true; } @@ -102,7 +105,7 @@ function clientCmdNdEnableKeybinds(%bool) //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 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' );} @@ -112,5 +115,7 @@ function ndInputMirrorY (%bool) {if(!%bool)return; commandToServer('mirr 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 ndInputNextBox (%bool) {if(!%bool)return; commandToServer('nextBox' );} +function ndInputPrevBox (%bool) {if(!%bool)return; commandToServer('prevBox' );} function ndInputMultiSelect(%bool) {commandToServer('ndMultiSelect', %bool);} diff --git a/scripts/server/commands.cs b/scripts/server/commands.cs index b80d8e2..449bbd5 100644 --- a/scripts/server/commands.cs +++ b/scripts/server/commands.cs @@ -45,6 +45,7 @@ function serverCmdDupHelp(%client) messageClient(%client, '', "\c3/ForcePlant\t\c6 Plant a selection in mid air; bricks can float."); messageClient(%client, '', "\c3/ToggleForcePlant\t\c6 Enable force plant for normal planting, so you dont have to type it all the time."); messageClient(%client, '', "\c3/PlantAs\c6 [\c3target\c6]\t\c6 Plant bricks in a different brick group. Target can be a name or blid."); + messageClient(%client, '', "\c3/Ownership\t\c6 Plant bricks with the original ownership from when they were copied or saved."); messageClient(%client, '', " "); messageClient(%client, '', "\c3/FillWrench\t\c6 Open the fill wrench gui to change settings on all selected bricks."); @@ -57,16 +58,20 @@ function serverCmdDupHelp(%client) messageClient(%client, '', " "); messageClient(%client, '', "\c3/SuperCut\t\c6 Delete everything in your selection box, cutting bricks in half on its sides!"); - messageClient(%client, '', "\c3/FillBricks\t\c6 First supercut, then completely fill your selection box with few bricks."); + messageClient(%client, '', "\c3/FillBricks\t\c6 First supercut, then completely fill your selection box with bricks."); + messageClient(%client, '', " "); + + messageClient(%client, '', "\c3/PrevBox\t\c6 Recall the previous selection box when in Box Select mode. Similar to pressing up in a chat client. Can be used multiple times."); + messageClient(%client, '', "\c3/NextBox\t\c6 Undo one /prevBox, going forward in the selection box history."); messageClient(%client, '', " "); messageClient(%client, '', "\c3/SaveDup\c6 [\c3name\c6]\t\c6 Save your current selection to a file."); messageClient(%client, '', "\c3/LoadDup\c6 [\c3name\c6]\t\c6 Load a selection from a file. Your current selection will be deleted."); messageClient(%client, '', "\c3/AllDups\c6 [\c3filter\c6]\t\c6 Show all known saved duplications that match the filter. Leave blank to show all."); - messageClient(%client, '', " "); + //messageClient(%client, '', " "); - messageClient(%client, '', "\c3/DupVersion\t\c6 Show the duplicator and blockland versions running on the server."); - messageClient(%client, '', "\c3/DupClients\t\c6 Show the duplicator versions of other clients on the server."); + //messageClient(%client, '', "\c3/DupVersion\t\c6 Show the duplicator and blockland versions running on the server."); + //messageClient(%client, '', "\c3/DupClients\t\c6 Show the duplicator versions of other clients on the server."); messageClient(%client, '', "\c7--------------------------------------------------------------------------------"); messageClient(%client, '', "\c6All of the commands can be shortened by just typing a \c3/\c6 and the capital letters!"); @@ -78,6 +83,7 @@ function serverCmdDupHelp(%client) //function serverCmdDV(%client){serverCmdDupVersion(%client);} //function serverCmdDC(%client){serverCmdDupClients(%client);} function serverCmdDH(%client){serverCmdDupHelp(%client);} +function serverCmdNdHelp(%client) { serverCmdDupHelp(%client); } @@ -291,11 +297,11 @@ function serverCmdNdCopy(%client) } //Paste selection (ctrl v) -function serverCmdNdPaste(%client) -{ - if(%client.ndModeIndex) - %client.ndMode.onPaste(%client); -} +//function serverCmdNdPaste(%client) +//{ +// if(%client.ndModeIndex) +// %client.ndMode.onPaste(%client); +//} //Cut selection (ctrl x) function serverCmdNdCut(%client) @@ -1203,3 +1209,12 @@ function serverCmdPlantAs(%client, %t0, %t1, %t2, %t3, %t4) //Alternative short command function serverCmdPA(%client, %t0, %t1, %t2, %t3, %t4) {serverCmdPlantAs(%client, %t0, %t1, %t2, %t3, %t4);} + + +/////////////////////////////////////////////////////////////////////////// +// Box history + +function serverCmdPrevBox(%client) { %client.ndPrevBox(); } +function serverCmdNextBox(%client) { %client.ndNextBox(); } +function serverCmdPB(%client) { serverCmdPrevBox(%client); } +function serverCmdNB(%client) { serverCmdNextBox(%client); } diff --git a/scripts/server/modes.cs b/scripts/server/modes.cs index 4dc7bca..d8f658b 100644 --- a/scripts/server/modes.cs +++ b/scripts/server/modes.cs @@ -24,10 +24,10 @@ function NewDuplicatorMode::onCopy(%this, %client) ndmessageClient(%client, '', "\c6Copy can not be used in your current duplicator mode."); } -function NewDuplicatorMode::onPaste(%this, %client) -{ - ndmessageClient(%client, '', "\c6Paste can not be used in your current duplicator mode."); -} +//function NewDuplicatorMode::onPaste(%this, %client) +//{ +// ndmessageClient(%client, '', "\c6Paste can not be used in your current duplicator mode."); +//} function NewDuplicatorMode::onCut(%this, %client) { diff --git a/server.cs b/server.cs index b4114a2..707a8f3 100644 --- a/server.cs +++ b/server.cs @@ -25,6 +25,7 @@ exec($ND::ClassPath @ "server/undogroupplant.cs"); exec($ND::ClassPath @ "server/undogroupwrench.cs"); exec($ND::ClassPath @ "server/duplimode/boxselect.cs"); +exec($ND::ClassPath @ "server/duplimode/boxselecthistory.cs"); exec($ND::ClassPath @ "server/duplimode/boxselectprogress.cs"); exec($ND::ClassPath @ "server/duplimode/cutprogress.cs"); exec($ND::ClassPath @ "server/duplimode/fillcolor.cs");