Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Portal Mechanics (Closes #130) #1024

Open
wants to merge 30 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ad96125
First commit on this
heisluft Feb 7, 2019
f3db1db
Fixed imports
heisluft Feb 7, 2019
ab2915e
Renamed generic Portal variables to 'ender portal' in BlockEnderPorta…
VaiTon Feb 7, 2019
8c98b9c
Merge branch 'nether-portal' of https://github.com/VaiTon/Glowstone i…
heisluft Feb 7, 2019
6b442c0
Added proper portal checking
heisluft Feb 13, 2019
518999d
Merge branch 'dev' of https://github.com/GlowstoneMC/Glowstone into c…
heisluft Feb 13, 2019
c5ee5ba
Implement findOrCreate
Pr0methean Feb 15, 2019
5f0b8f0
Update NetherTravelAgent.java
Pr0methean Feb 15, 2019
c3d961f
Lombokify
Pr0methean Feb 15, 2019
7a6eec2
Bug fix
Pr0methean Feb 15, 2019
8f7da12
Fix the placing of portal blocks
heisluft Feb 16, 2019
2960c9f
Fixed compile error (Bukkit getCanCreatePortal vs. Lombok generated
heisluft Feb 16, 2019
08b584b
Dwelete debugging print statements
heisluft Feb 17, 2019
2a9d771
Fixed Logic for portal creation
heisluft Feb 17, 2019
7417ac4
Implement PortalCreateEvent
heisluft Feb 17, 2019
bdde48d
Implement Zombie Pigmen spawn and the destroying of portals
heisluft Feb 17, 2019
347eb38
Fix checkstyle errors
heisluft Feb 17, 2019
70713fd
Changed pigman spawn rate to vanilla value
heisluft Feb 17, 2019
97b12d8
implement portal creation by linking
heisluft Feb 21, 2019
ac789f8
Fix checkstyle video
heisluft Feb 22, 2019
ee11102
Renamed NetherTravelAgent to TravelAgentImpl as it will also be used
heisluft Feb 22, 2019
aa5dd7e
wired up travelagentimpl (now called GlowTravelAgent)
heisluft Feb 23, 2019
4a3463b
Fix checkstyle errors
mastercoms Apr 12, 2019
0f03af4
Merge branch 'dev' of https://github.com/GlowstoneMC/Glowstone into c…
heisluft Apr 28, 2019
517f540
Implement teleport to the nether and back
heisluft Apr 28, 2019
abb1290
Implement BoundingBox based portal entrance; Bugfix: Fire EnterEvent …
heisluft Apr 29, 2019
6af92fa
Fixed Checkstyle errors
heisluft Apr 29, 2019
69a4bb0
Applied suggestions
heisluft Apr 30, 2019
d31d8a0
Merge remote-tracking branch 'upstream/dev' into create-portal-event
heisluft Jan 9, 2020
8accf54
Applied suggestions
heisluft Jan 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 19 additions & 13 deletions src/main/java/net/glowstone/block/blocktype/BlockPortal.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@

public class BlockPortal extends BlockType {

/**
* Gets the Axis-specific bounding box of the specified block. Only works for Portal blocks.
*
* @param block the block to get the bounding box from.
* @return the resulting bounding box, axis alignment dependent.
*/
public static BoundingBox getBoundingBox(GlowBlock block) {
boolean north = getFace(block.getData()) == BlockFace.NORTH;
Vector base = new Vector(north ? .375 : 0, 0, north ? 0 : .375);
Vector size = new Vector(north ? .25 : 1, 1, north ? 1 : .25);
return BoundingBox.fromPositionAndSize(block.getLocation().toVector().add(base), size);
}

private static BlockFace getFace(int blockData) {
int faceData = blockData & 3;
return faceData == 1 ? BlockFace.WEST : faceData == 2 ? BlockFace.NORTH : null;
}

@Override
public void onNearBlockChanged(final GlowBlock block, BlockFace face, GlowBlock changedBlock,
Material oldType, byte oldData, Material newType, byte newData) {
Expand All @@ -28,24 +46,12 @@ public void onNearBlockChanged(final GlowBlock block, BlockFace face, GlowBlock
}
PortalShape shape = new PortalShape(block.getLocation(), left);
if (shape.validate()
&& shape.getPortalBlockCount() == shape.getHeight() * shape.getWidth()) {
&& shape.getPortalBlockCount() == shape.getHeight() * shape.getWidth()) {
return;
}
block.setType(Material.AIR);
}

public static BoundingBox getBoundingBox(GlowBlock block) {
boolean north = getFace(block.getData()) == BlockFace.NORTH;
Vector base = new Vector(north ? .375 : 0, 0, north ? 0 : .375);
Vector size = new Vector(north ? .25 : 1, 1, north ? 1 : .25);
return BoundingBox.fromPositionAndSize(block.getLocation().toVector().add(base), size);
}

private static BlockFace getFace(int blockData) {
int faceData = blockData & 3;
return faceData == 1 ? BlockFace.WEST : faceData == 2 ? BlockFace.NORTH : null;
}

@Override
public void updateBlock(GlowBlock block) {
// remove invalid portal blocks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;


public class ItemFlintAndSteel extends ItemTool {

public ItemFlintAndSteel() {
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/net/glowstone/entity/GlowEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -616,37 +616,47 @@ public void pulse() {
}
}
GlowBlock block = world.getBlockAt(location);
// Nether portal handling
if (block.getType().equals(Material.PORTAL)
&& BlockPortal.getBoundingBox(block).intersects(boundingBox)) {
if (!isInPortal) {
heisluft marked this conversation as resolved.
Show resolved Hide resolved
//Entity just entered the Portal, fire EnterEvent
EventFactory.getInstance().callEvent(
new EntityPortalEnterEvent(this, block.getLocation()));
// prevent EnterEvent being fired again
isInPortal = true;
}
// only try porting if the nether is enabled
if (server.getAllowNether() && portalCooldown <= 0) {
GlowWorld w = getWorld().getEnvironment().equals(Environment.NETHER)
// determine destination world
GlowWorld destination = getWorld().getEnvironment().equals(Environment.NETHER)
heisluft marked this conversation as resolved.
Show resolved Hide resolved
? server.getWorld("world") : server.getWorld("world_nether");
TravelAgent agent = w.getTravelAgent();
boolean destIsNether = w.getEnvironment().equals(Environment.NETHER);
TravelAgent agent = destination.getTravelAgent();
boolean destIsNether = destination.getEnvironment().equals(Environment.NETHER);
// Destination Coordinates: NetherX * 8 = OverworldX etc.
int destX = destIsNether ? location.getBlockX() / 8 : location.getBlockX() * 8;
int destY = destIsNether ? location.getBlockY() / 8 : location.getBlockY() * 8;
int destZ = destIsNether ? location.getBlockZ() / 8 : location.getBlockZ() * 8;
Location requested = new Location(w, destX, destY, destZ);
Location requested = new Location(destination, destX, destY, destZ);
if (agent.getCanCreatePortal() || agent.findPortal(requested) != null) {
Location teleportLocation = agent.findOrCreate(requested);
//attempt teleportation: fire porting event, abort if cancelled
EntityPortalEvent p = EventFactory.getInstance().callEvent(
heisluft marked this conversation as resolved.
Show resolved Hide resolved
new EntityPortalEvent(this,
location.clone(), teleportLocation.clone(), agent));
if (!p.isCancelled()) {
// if not, teleport the Entity to the location specified by the event
teleport(p.getTo());
setPortalCooldown(300);
// change the velocity based on the portal exit event
setVelocity(EventFactory.getInstance().callEvent(
new EntityPortalExitEvent(this, previousLocation,
location.clone(), velocity.clone(), new Vector())).getAfter());
}
}
}
} else {
// entity has left the portal
isInPortal = false;
}

Expand Down
7 changes: 1 addition & 6 deletions src/main/java/net/glowstone/util/GlowTravelAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class GlowTravelAgent implements TravelAgent {
*/
public GlowTravelAgent(World world) {
if (world.getEnvironment() == World.Environment.THE_END) {
throw new UnsupportedOperationException("Not supported yet.");
throw new UnsupportedOperationException("End Portals are not supported yet.");
}
this.world = world;
}
Expand Down Expand Up @@ -316,9 +316,4 @@ public boolean createPortal(Location destination) {
}
return false;
}

private boolean canBuildPortal(Location loc, BlockFace facing) {
// TODO: Need impl
return false;
}
}
46 changes: 31 additions & 15 deletions src/main/java/net/glowstone/util/pattern/PortalShape.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@
*/
public class PortalShape {

/**
* Max portal width or height.
*/
private static final int MAX_PORTAL_WIDTH_HEIGHT = 21;
heisluft marked this conversation as resolved.
Show resolved Hide resolved

/**
* Min portal height.
*/
private static final int MIN_PORTAL_HEIGHT = 3;

/**
* Min portal width.
*/
private static final int MIN_PORTAL_WIDTH = 2;

/**
* The direction that is considered left.
*/
Expand Down Expand Up @@ -54,8 +69,8 @@ public PortalShape(Location buildLocation, BlockFace portalFace) {
Location location = buildLocation.clone();

// calculations start on the lower part, so we have to move down
while (location.getY() > buildLocation.getY() - 21 && location.getY() > 0 // validate y axis
&& canBuildThrough(downImmutable(location).getBlock().getType())) {
while (location.getY() > buildLocation.getY() - MAX_PORTAL_WIDTH_HEIGHT
&& location.getY() > 0 && canBuildThrough(downImmutable(location).getBlock().getType())) {
// move downwards
location.subtract(0, 1, 0);
}
Expand All @@ -80,7 +95,7 @@ && canBuildThrough(downImmutable(location).getBlock().getType())) {
width = getDistanceUntilEdge(bottomLeft, left.getOppositeFace()) + 1;

// Portal too big / too small
if (width < 2 || width > 21) {
if (width < MIN_PORTAL_WIDTH || width > MAX_PORTAL_WIDTH_HEIGHT) {
return;
}

Expand Down Expand Up @@ -138,8 +153,8 @@ private int getDistanceUntilEdge(Location location, BlockFace face) {
// Clone the location as Location objects are mutable
Location destLoc = location.clone();

int i;
for (i = 0; i < 22; ++i) {
int distance;
for (distance = 0; distance <= MAX_PORTAL_WIDTH_HEIGHT; ++distance) {
// Move onwards
destLoc.add(face.getModX(), face.getModY(), face.getModZ());
// Break if either an obstacle or the end of the obsidian "line" is reached
Expand All @@ -149,7 +164,7 @@ private int getDistanceUntilEdge(Location location, BlockFace face) {
}
}
// If the target block is not obsidian, the portal is invalid.
return destLoc.getBlock().getType() == Material.OBSIDIAN ? i : -1;
return destLoc.getBlock().getType() == Material.OBSIDIAN ? distance : -1;
}

/**
Expand All @@ -158,7 +173,7 @@ private int getDistanceUntilEdge(Location location, BlockFace face) {
* @return the height or 0 in case of failure
*/
private int calculatePortalHeight() {
for (height = 0; height < 21; ++height) {
for (height = 0; height < MAX_PORTAL_WIDTH_HEIGHT; ++height) {
boolean flag = false;
for (int i = 0; i < width; ++i) {
Location location = offsetImmutable(bottomLeft, left.getOppositeFace(), i)
Expand Down Expand Up @@ -201,14 +216,15 @@ private int calculatePortalHeight() {
}
}

if (height <= 21 && height >= 3) {
if (height <= MAX_PORTAL_WIDTH_HEIGHT && height >= MIN_PORTAL_HEIGHT) {
return height;
} else {
bottomLeft = null;
width = 0;
height = 0;
return 0;
}

bottomLeft = null;
width = 0;
height = 0;
return 0;

heisluft marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -217,7 +233,8 @@ private int calculatePortalHeight() {
* @return whether the portal shape is valid
*/
public boolean validate() {
return bottomLeft != null && width >= 2 && width <= 21 && height >= 3 && height <= 21;
return bottomLeft != null && width >= MIN_PORTAL_WIDTH && width <= MAX_PORTAL_WIDTH_HEIGHT
&& height >= MIN_PORTAL_HEIGHT && height <= MAX_PORTAL_WIDTH_HEIGHT;
}

/**
Expand All @@ -242,7 +259,6 @@ public void placePortalBlocks() {
block.setType(Material.PORTAL);
block.setData(meta);
});

}
}
}