Skip to content

Commit

Permalink
Refactor placement system to be more flexible
Browse files Browse the repository at this point in the history
  • Loading branch information
TomyLobo committed Apr 5, 2023
1 parent c3aa9bc commit 58a512e
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 25 deletions.
40 changes: 24 additions & 16 deletions worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
Expand Up @@ -46,6 +46,8 @@
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.Placement;
import com.sk89q.worldedit.session.PlacementType;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.SideEffectSet;
Expand Down Expand Up @@ -93,7 +95,7 @@ public class LocalSession {

// Session related
private transient RegionSelector selector = new CuboidRegionSelector();
private transient boolean placeAtPos1 = false;
private transient Placement placement = new Placement(PlacementType.PLAYER);
private final transient LinkedList<EditSession> history = new LinkedList<>();
private transient int historyPointer = 0;
private transient ClipboardHolder clipboard;
Expand Down Expand Up @@ -559,34 +561,40 @@ public boolean toggleSuperPickAxe() {
* @throws IncompleteRegionException thrown if a region is not fully selected
*/
public BlockVector3 getPlacementPosition(Actor actor) throws IncompleteRegionException {
checkNotNull(actor);
if (!placeAtPos1) {
if (actor instanceof Locatable) {
return ((Locatable) actor).getBlockLocation().toVector().toBlockPoint();
} else {
throw new IncompleteRegionException();
}
}
return this.placement.getPlacementPosition(selector, actor);
}

public Placement getPlacement() {
return this.placement;
}

return selector.getPrimaryPosition();
public void setPlacement(Placement placement) {
this.placement = placement;
}

@Deprecated
public void setPlaceAtPos1(boolean placeAtPos1) {
this.placeAtPos1 = placeAtPos1;
this.placement = new Placement(placeAtPos1 ? PlacementType.POS1 : PlacementType.PLAYER);
}

@Deprecated
public boolean isPlaceAtPos1() {
return placeAtPos1;
return this.placement.getPlacementType() == PlacementType.POS1;
}

/**
* Toggle placement position.
* Toggle placement position between POS1 and PLAYER.
*
* @return whether "place at position 1" is now enabled
* @return whether placement is now at position 1
*/
@Deprecated
public boolean togglePlacementPosition() {
placeAtPos1 = !placeAtPos1;
return placeAtPos1;
if (this.placement.getPlacementType() == PlacementType.POS1) {
this.placement = new Placement(PlacementType.PLAYER);
} else {
this.placement = new Placement(PlacementType.POS1);
}
return this.placement.getPlacementType() == PlacementType.POS1;
}

/**
Expand Down
Expand Up @@ -32,7 +32,6 @@
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.ApplySideEffect;
Expand All @@ -42,6 +41,9 @@
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.internal.command.CommandUtil;
import com.sk89q.worldedit.internal.cui.ServerCUIHandler;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.Placement;
import com.sk89q.worldedit.session.PlacementType;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.util.auth.AuthorizationException;
Expand Down Expand Up @@ -420,20 +422,26 @@ public void gmask(Actor actor, LocalSession session,
}
}

private static void placementImpl(Actor actor, LocalSession session, Placement placement) {
if (!placement.canUseActor(actor)) {
actor.printError(TranslatableComponent.of("worldedit.toggleplace.not-locatable"));
return;
}

session.setPlacement(placement);
actor.printInfo(placement.getInfo());
}

@Command(
name = "toggleplace",
aliases = {"/toggleplace"},
desc = "Switch between your position and pos1 for placement"
)
public void togglePlace(Actor actor, LocalSession session) {
if (!(actor instanceof Locatable)) {
actor.printError(TranslatableComponent.of("worldedit.toggleplace.not-locatable"));
return;
}
if (session.togglePlacementPosition()) {
actor.printInfo(TranslatableComponent.of("worldedit.toggleplace.pos1"));
if (session.getPlacement().getPlacementType() == PlacementType.POS1) {
placementImpl(actor, session, new Placement(PlacementType.PLAYER));
} else {
actor.printInfo(TranslatableComponent.of("worldedit.toggleplace.player"));
placementImpl(actor, session, new Placement(PlacementType.POS1));
}
}

Expand Down
@@ -0,0 +1,51 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.session;

import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;

public class Placement {
private final PlacementType placementType;

public Placement(PlacementType placementType) {
this.placementType = placementType;
}

public PlacementType getPlacementType() {
return placementType;
}

public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return placementType.getPlacementPosition(selector, actor);
}

public boolean canUseActor(Actor actor) {
return placementType.canUseActor(actor);
}

public Component getInfo() {
return TranslatableComponent.of(placementType.getTranslationKey());
}
}
@@ -0,0 +1,70 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.session;

import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.RegionSelector;

import static com.google.common.base.Preconditions.checkNotNull;

public enum PlacementType {
PLAYER("worldedit.toggleplace.player") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException
{
if (!canUseActor(actor)) {
throw new IncompleteRegionException();
}
return ((Locatable) actor).getBlockLocation().toVector().toBlockPoint();
}

@Override
public boolean canUseActor(Actor actor) {
checkNotNull(actor);
return actor instanceof Locatable;
}
},

POS1("worldedit.toggleplace.pos1") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return selector.getPrimaryPosition();
}
};

private final String translationKey;

PlacementType(String translationKey) {
this.translationKey = translationKey;
}

public abstract BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException;

public boolean canUseActor(Actor actor) {
return true;
}

public String getTranslationKey() {
return translationKey;
}
}
Expand Up @@ -35,6 +35,7 @@
import com.sk89q.worldedit.event.platform.SessionIdleEvent;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.storage.JsonFileSessionStore;
import com.sk89q.worldedit.session.storage.SessionStore;
Expand Down Expand Up @@ -213,7 +214,7 @@ public synchronized LocalSession get(SessionOwner owner) {

// Force non-locatable actors to use placeAtPos1
if (!(owner instanceof Locatable)) {
session.setPlaceAtPos1(true);
session.setPlacement(new Placement(PlacementType.POS1));
}

return session;
Expand Down
Expand Up @@ -46,6 +46,7 @@ void setUp() {
doReturn(world).when(player).getWorld();
}

@SuppressWarnings("deprecation")
@Test
void testPlacementSet() {
session.setPlaceAtPos1(true);
Expand All @@ -58,6 +59,7 @@ void testPlacementSet() {
assertTrue(session.isPlaceAtPos1());
}

@SuppressWarnings("deprecation")
@Test
void testPlacementToggle() {
// Start with pos1 and verify that toggling back and forth works
Expand All @@ -81,6 +83,7 @@ void testPlacementToggle() {
assertFalse(session.isPlaceAtPos1());
}

@SuppressWarnings("deprecation")
@Test
void testPlacementPos1() throws Exception {
final ActorSelectorLimits limits = ActorSelectorLimits.forActor(player);
Expand All @@ -103,6 +106,7 @@ void testPlacementPos1() throws Exception {
assertEquals(pos1, session.getPlacementPosition(player));
}

@SuppressWarnings("deprecation")
@Test
void testPlacementPlayer() throws Exception {
final BlockVector3 playerPosition = BlockVector3.at(42,1337,23);
Expand Down

0 comments on commit 58a512e

Please sign in to comment.