Skip to content

Commit

Permalink
Nether portals (#1597)
Browse files Browse the repository at this point in the history
* Add WorldSettings methods for portals

* Vanilla portals option added.

Currently defaulted on for testing. Ultimately, the game mode config can
decide if the vanilla portal is used or not.
Note that the end platform is just a set of obsidian blocks.

* Reduces search radius when close to island edge

* Adds and fixes tests

* Use EntityPortalEnterEvent instead of PlayerMoveEvent

* Removed duplication between nether and end portalling

* Code clean up

* Single event handler for nether and end.

* Created new PlayerEntityPortalEvent class to enable entity teleports

Unfortunately, PlayerPortalEvent and EntityPortalEvent are not fraternal
classes so there's no way to apply code to both except via this
abstraction class.

Tests fail.

* Places end portal always in the same place.

* Teleport entites to nether or end

Identify the teleport cause manually because there is no method.
Teleports to the End happen but seem to be slightly different locations.
Some entities will disappear, others will stick around. I don't know
why.

* Put defaults back to false.

* Create end spawn point to default point when not making end islands

* Fixed PortalTeleportationListener tests.

* Updated since tag
  • Loading branch information
tastybento authored Feb 3, 2021
1 parent 455e662 commit 4e7b788
Show file tree
Hide file tree
Showing 4 changed files with 614 additions and 306 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ default List<String> getFallingBannedCommands() {
*/
@NonNull
List<String> getOnLeaveCommands();

/**
* Returns a list of commands that should be executed when the player respawns after death if {@link Flags#ISLAND_RESPAWN} is true.<br/>
* @return a list of commands.
Expand Down Expand Up @@ -537,4 +537,22 @@ default String getDefaultNewPlayerAction()
{
return "create";
}

/**
* Make a nether portal when teleporting to the nether through an overworld portal
* @return true if a portal should be made
* @since 1.16.0
*/
default boolean isMakeNetherPortals() {
return false;
}

/**
* Make an end portal when teleporting to the end through an end portal
* @return true if a portal should be made
* @since 1.16.0
*/
default boolean isMakeEndPortals() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package world.bentobox.bentobox.listeners;

import java.util.Optional;

import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;

/**
* Abstracts PlayerPortalEvent and EntityPortalEvent
* @author tastybento
*
*/
public class PlayerEntityPortalEvent {

private final EntityPortalEvent epe;
private final PlayerPortalEvent ppe;

/**
* Create a hybrid PlayerEntityPortalEvent
* @param epe - EntityPortalEvent
*/
public PlayerEntityPortalEvent(EntityPortalEvent epe) {
this.ppe = null;
this.epe = epe;
}

/**
* Create a hybrid PlayerEntityPortalEvent
* @param ppe - PlayerPortalEvent
*/
public PlayerEntityPortalEvent(PlayerPortalEvent ppe) {
this.ppe = ppe;
this.epe = null;
}

/**
* Returns whether the server will attempt to create a destination portal or not.
* Only applicable to {@link PlayerPortalEvent}
* @return whether there should create be a destination portal created
*/
public boolean getCanCreatePortal() {
return epe == null ? ppe.getCanCreatePortal() : false;
}

/**
* Returns the entity involved in this event
* @return Entity who is involved in this event
*/
@NonNull
public Entity getEntity() {
return epe == null ? ppe.getPlayer() : epe.getEntity();
}

/**
* Gets the location this player moved from
* @return Location the player or entity moved from
*/
@NonNull
public Location getFrom() {
return epe == null ? ppe.getFrom() : epe.getFrom();
}

/**
* Gets the location this player moved to
* @return Location the player moved to
*/
@Nullable
public Location getTo() {
return epe == null ? ppe.getTo() : epe.getTo();
}

/**
* @return true if constructed with an {@link EntityPortalEvent}
*/
public boolean isEntityPortalEvent() {
return epe != null;
}

/**
* @return true if constructed with an {@link PlayerPortalEvent}
*/
public boolean isPlayerPortalEvent() {
return ppe != null;
}

/**
* Sets the cancellation state of this event. A cancelled event will not be executed in the server, but will still pass to other plugins
* If a move or teleport event is cancelled, the player will be moved or teleported back to the Location as defined by getFrom(). This will not fire an event
* Specified by: setCancelled(...) in Cancellable
* @param cancel true if you wish to cancel this event
*/
public void setCancelled(boolean cancel) {
if (epe == null) {
ppe.setCancelled(cancel);
} else {
epe.setCancelled(cancel);
}
}

/**
* Sets whether the server should attempt to create a destination portal or not.
* Only applicable to {@link PlayerPortalEvent}
* @param canCreatePortal Sets whether there should be a destination portal created
*/
public void setCanCreatePortal(boolean canCreatePortal) {
if (ppe != null) {
ppe.setCanCreatePortal(canCreatePortal);
}

}

/**
* Set the Block radius to search in for available portals.
* @param searchRadius the radius in which to search for a portal from the location
*/
public void setSearchRadius(int searchRadius) {
if (epe == null) {
ppe.setSearchRadius(searchRadius);
} else {
epe.setSearchRadius(searchRadius);
}
}

/**
* Sets the location that this player will move to
* @param to New Location this player or entity will move to
*/
public void setTo(Location to) {
if (epe == null) {
ppe.setTo(to);
} else {
epe.setTo(to);
}
}

/**
* Get island at the from location
* @return optional island at from location
*/
public Optional<Island> getIsland() {
return BentoBox.getInstance().getIslands().getProtectedIslandAt(getFrom());
}

/**
* Get the from world
* @return from world
*/
@Nullable
public World getWorld() {
return getFrom().getWorld();
}
}
Loading

0 comments on commit 4e7b788

Please sign in to comment.