diff --git a/classes/server/duplimode/boxselect.cs b/classes/server/duplimode/boxselect.cs index d792052..8eadd50 100644 --- a/classes/server/duplimode/boxselect.cs +++ b/classes/server/duplimode/boxselect.cs @@ -163,7 +163,7 @@ function NDM_BoxSelect::onSelectObject(%this, %client, %obj, %pos, %normal) } else { - %client.ndSelectionBox.ez_zoneBrick = ""; + %client.ndSelectionBox.zoneBrick = ""; %box = %obj.getWorldBox(); %p1 = getWords(%box, 0, 2); %p2 = getWords(%box, 3, 5); @@ -185,7 +185,7 @@ function NDM_BoxSelect::onSelectObject(%this, %client, %obj, %pos, %normal) %box = ndGetBoxFromRom(%obj); } else if (isObject(%obj.physicalZone)) { %box = ndGetBoxFromZone(%obj); - %client.ndSelectionBox.ez_zoneBrick = %obj; + %client.ndSelectionBox.zoneBrick = %obj; } else { %box = ndGetPlateBoxFromRayCast(%pos, %normal); } @@ -232,9 +232,12 @@ function ndGetBoxFromRom(%b) { function ndGetBoxFromZone(%b) { %z = %b.physicalZone; %pos = %z.position; - %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); + %scale = %z.getScale(); + %sx = getWord(%scale, 0); + %sy = getWord(%scale, 1); + %sz = getWord(%scale, 2); + %bl = vectorAdd(%pos, 0 SPC -%sy SPC 0); + %bh = vectorAdd(%pos, %sx SPC 0 SPC %sz); return ndCorrectBox(%bl SPC %bh); } @@ -354,12 +357,42 @@ function NDM_BoxSelect::onRotateBrick(%this, %client, %direction) %client.ndBoxChanged(); } +function ndApplyZoneEvent(%brick, %p1a, %p2a, %client) { + %pos = %brick.getPosition(); + %p1 = vectorSub(%p1a, %pos); + %p2 = vectorSub(%p2a, %pos); + + for(%i=0; %i<%brick.numEvents; %i++) { + if(%brick.eventOutput[%i] $= "setZoneBox") { + %brick.eventOutputParameter[%i, 1] = %p1; + %brick.eventOutputParameter[%i, 2] = %p2; + messageClient(%client, 'MsgError', ""); + commandToClient(%client, 'centerPrint', + "\c6Applied selection box to zone event \c3" @ %i + @ "\c6 on brick, and re-created zone.", 5); + %brick.setZoneBox(%p1, %p2, + %brick.eventOutputParameter[%i,3], 0); + return; + } + } + messageClient(%client, 'MsgError', ""); + commandToClient(%client, 'centerPrint', "\c6Cannot set zone" @ + " - Brick does not use the setZoneBox event.", 5); +} + + //Plant Brick function NDM_BoxSelect::onPlantBrick(%this, %client) { if(!isObject(%client.ndSelectionBox)) return; + if(isObject(%client.ndSelectionBox.zoneBrick)) { + ndApplyZoneEvent(%client.ndSelectionBox.zoneBrick, + %client.ndSelectionBox.point1, %client.ndSelectionBox.point2, %client); + return; + } + //If we have a selection, enter plant mode! if(%client.ndSelectionAvailable) { diff --git a/classes/server/duplimode/boxselecthistory.cs b/classes/server/duplimode/boxselecthistory.cs new file mode 100644 index 0000000..b658935 --- /dev/null +++ b/classes/server/duplimode/boxselecthistory.cs @@ -0,0 +1,88 @@ + +function ndBoxPlaySound(%sel, %sound) { + if(%sel.selectedCorner) + %soundPoint = %sel.point2; + else + %soundPoint = %sel.point1; + serverPlay3d(BrickMoveSound, %soundPoint); +} + +function gameConnection::ndCreateSelectionBox(%client) { + %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); +} + +function gameConnection::ndPushBoxHistory(%client) { + //talk("push"); + if(!isObject(%client.ndSelectionBox)) return; + %box = %client.ndSelectionBox.point1 SPC %client.ndSelectionBox.point2; + if(%client.ndBoxHistoryCount>0 && + %box $= %client.ndBoxHistory[%client.ndBoxHistoryCount-1]) + return; + %client.ndBoxHistory[%client.ndBoxHistoryCount+0] = %box; + %client.ndBoxHistoryCount++; + %client.ndBoxHistoryPos = 1; // recall prior to this one +} +function gameConnection::ndBoxChanged(%client) { + //talk("changed"); + %client.ndBoxHistoryPos = 0; // recall starting with this initial selection + %client.ndSaveBoxOnRecall = true; +} +function gameConnection::ndBoxCleared(%client) { + //talk("cleared"); + if(%client.ndSaveBoxOnRecall) { + %client.ndPushBoxHistory(); + %client.ndSaveBoxOnRecall = false; + } + %client.ndBoxHistoryPos = 0; +} +function gameConnection::ndRecallBoxHistory(%client, %offset) { + //talk("recall " @ %offset); + if(%offset<1 || %offset>%client.ndBoxHistoryCount) return; + + %idx = %client.ndBoxHistoryCount - %offset; + %box = %client.ndBoxHistory[%idx]; + %p1 = getWords(%box,0,2); + %p2 = getWords(%box,3,5); + + if(!isObject(%client.ndSelectionBox)) + %client.ndCreateSelectionBox(); + %client.ndSelectionBox.setSize(%p1,%p2); + %client.ndUpdateBottomPrint(); + ndBoxPlaySound(%client.ndSelectionBox, BrickMoveSound); +} + +function ndPlayerHoldingNewdup(%player) { + return isObject(%player) && + isObject(%player.getMountedImage(0)) && + getSubStr(%player.getMountedImage(0).getName(),0,8) $= "ND_Image"; +} +function gameConnection::ndPrevBox(%client) { + if(!ndPlayerHoldingNewdup(%client.player)) return; + if(%client.ndModeIndex != $NDM::BoxSelect) return; + + if(%client.ndBoxHistoryPos < %client.ndBoxHistoryCount) + %client.ndBoxHistoryPos++; + if(%client.ndSaveBoxOnRecall) { + %client.ndPushBoxHistory(); + %client.ndBoxHistoryPos++; + %client.ndSaveBoxOnRecall = false; + } + + %client.ndRecallBoxHistory(%client.ndBoxHistoryPos); +} +function gameConnection::ndNextBox(%client) { + if(!ndPlayerHoldingNewdup(%client.player)) return; + if(%client.ndModeIndex != $NDM::BoxSelect) return; + + if(%client.ndBoxHistoryPos > 1) + %client.ndBoxHistoryPos--; + else + %client.ndBoxHistoryPos = 1; + + %client.ndRecallBoxHistory(%client.ndBoxHistoryPos); +} diff --git a/readme.md b/readme.md index 15ec774..be52494 100644 --- a/readme.md +++ b/readme.md @@ -14,7 +14,7 @@ With limited mode off, all adjacent bricks will be selected regardless of color. 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. -- Support for `Event_setZoneBox` +- 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. @@ -22,7 +22,6 @@ Hitting plant with this box updates the first Event_SetZoneBox event if present. - 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.