Archived
0

refactory Location's

This commit is contained in:
2018-09-08 05:25:24 +03:00
parent 6808ae34f9
commit 09c7626c2d
27 changed files with 269 additions and 319 deletions

View File

@@ -24,10 +24,10 @@ public class CoreEventListener {
log.trace("(GameLoop) playerMoveEventHandler()");
Chunk chunk;
chunk = event.getOldLocation().getChunk(); // Old chunk
chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation()); // Old chunk
int ccX = chunk.getX();
int ccZ = chunk.getZ();
chunk = event.getNewLocation().getChunk(); // Next chunk
chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation()); // Next chunk
int ncX = chunk.getX();
int ncZ = chunk.getZ();
@@ -71,7 +71,11 @@ public class CoreEventListener {
}
}
event.getPlayer().getLocation().setXYZ(event.getNewLocation());
event.getPlayer().getLocation().setXYZ(
event.getNewLocation().getX(),
event.getNewLocation().getY(),
event.getNewLocation().getZ()
);
// TODO отсылать клиенту только(!) для корректировки позиции
// SC_PlayerMoveEvent nextEvent = new SC_PlayerMoveEvent(event.getPlayer());

View File

@@ -1,21 +1,29 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-08-08
*/
package mc.core;
import lombok.Getter;
import lombok.Setter;
import mc.core.world.World;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class EntityLocation extends Location implements Cloneable {
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
public class EntityLocation implements Cloneable {
private double x, y, z;
private float yaw, pitch;
public EntityLocation(double x, double y, double z, float yaw, float pitch, World world) {
super(x, y, z, world);
setYawPitch(yaw, pitch);
public static EntityLocation ZERO() {
return new EntityLocation(0d,0d,0d,0f,0f);
}
public void set(EntityLocation location) {
setXYZ(location.x, location.y, location.z);
setYawPitch(location.yaw, location.pitch);
}
public void setXYZ(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setYawPitch(float yaw, float pitch) {
@@ -23,12 +31,25 @@ public class EntityLocation extends Location implements Cloneable {
this.pitch = pitch;
}
public void setYawPitch(EntityLocation entityLocation) {
setYawPitch(entityLocation.yaw, entityLocation.pitch);
public int getBlockX() {
return Double.valueOf(Math.floor(x)).intValue();
}
public int getBlockY() {
return Double.valueOf(Math.floor(y)).intValue();
}
public int getBlockZ() {
return Double.valueOf(Math.floor(z)).intValue();
}
@Override
public EntityLocation clone() {
return (EntityLocation) super.clone();
try {
return (EntityLocation) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -1,91 +0,0 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-08-08
*/
package mc.core;
import lombok.Getter;
import lombok.Setter;
import mc.core.exception.ResourceUnloadedException;
import mc.core.world.World;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
public class Location implements Cloneable {
@Getter
@Setter
private double x, y, z;
private Reference<World> refWorld;
public Location (double x, double y, double z, World world) {
setXYZ(x, y, z);
setWorld(world);
}
public void setXYZ(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setXYZ(Location location) {
setXYZ(location.x, location.y, location.z);
}
public World getWorld() {
if (refWorld == null) {
return null;
} else if (refWorld.get() == null) {
throw new ResourceUnloadedException("You're trying to get unloaded world");
} else {
return refWorld.get();
}
}
public void setWorld (World world) {
this.refWorld = new WeakReference<>(world);
}
public int getBlockX() {
return Double.valueOf(Math.floor(x)).intValue();
}
public int getBlockY() {
return Double.valueOf(Math.floor(y)).intValue();
}
public int getBlockZ() {
return Double.valueOf(Math.floor(z)).intValue();
}
public Chunk getChunk() {
World world = getWorld();
if (world == null) {
return null;
} else {
return world.getChunk(getBlockX() >> 4, getBlockZ() >> 4);
}
}
public ChunkSection getChunkSection() {
Chunk chunk = getChunk();
if (chunk == null) {
return null;
} else {
return chunk.getChunkSection(getBlockY() >> 4);
}
}
@Override
public Location clone() {
try {
return (Location) super.clone();
} catch (CloneNotSupportedException e) { // такое в нашем случае вообще возможно?
e.printStackTrace();
return null;
}
}
}

View File

@@ -12,8 +12,7 @@ import mc.core.player.Player;
import mc.core.player.PlayerManager;
import mc.core.text.Text;
import mc.core.text.Title;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import mc.core.world.World;
import java.util.Collections;
import java.util.List;
@@ -53,7 +52,7 @@ public class FakePlayerManager implements PlayerManager {
private static final NetChannel FAKE_NET_CHANNEL = new FakeNetChannet();
@Override
public Player createPlayer(String name, EntityLocation defaultLocation) {
public Player createPlayer(String name, EntityLocation location, World world) {
return null;
}

View File

@@ -10,6 +10,7 @@ import mc.core.Config;
import mc.core.EntityLocation;
import mc.core.network.BroadcastNetChannel;
import mc.core.network.NetChannel;
import mc.core.world.World;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
@@ -31,14 +32,13 @@ public class InMemoryPlayerManager implements PlayerManager, Runnable {
}
@Override
public Player createPlayer(String name, EntityLocation defaultLocation) {
public Player createPlayer(String name, EntityLocation location, World world) {
SimplePlayer player = new SimplePlayer();
player.setId(rand.nextInt(10000));
player.setUUID(UUID.nameUUIDFromBytes(name.getBytes()));
player.setName(name);
player.getLocation().setXYZ(defaultLocation);
player.getLocation().setYawPitch(defaultLocation);
player.getLocation().setWorld(defaultLocation.getWorld());
player.getLocation().set(location);
player.setWorld(world);
player.setSettings(new PlayerSettings());
synchronized (lock) {

View File

@@ -6,6 +6,7 @@ package mc.core.player;
import mc.core.EntityLocation;
import mc.core.network.NetChannel;
import mc.core.world.World;
import java.util.List;
import java.util.UUID;
@@ -23,7 +24,8 @@ public interface Player {
void setChannel(NetChannel channel);
EntityLocation getLocation();
//TODO надо определиться - нужно ли здесь setLocation() или нет
World getWorld();
void setWorld(World world);
boolean isFlying();
void setFlying(boolean value);

View File

@@ -6,12 +6,13 @@ package mc.core.player;
import mc.core.EntityLocation;
import mc.core.network.NetChannel;
import mc.core.world.World;
import java.util.List;
import java.util.Optional;
public interface PlayerManager {
Player createPlayer(String name, EntityLocation defaultLocation);
Player createPlayer(String name, EntityLocation location, World world);
void joinServer(Player player);
void leftServer(Player player);
Optional<Player> getPlayer(String name);

View File

@@ -6,8 +6,12 @@ package mc.core.player;
import lombok.Data;
import mc.core.EntityLocation;
import mc.core.exception.ResourceUnloadedException;
import mc.core.network.NetChannel;
import mc.core.world.World;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -19,21 +23,33 @@ public class SimplePlayer implements Player {
private String name;
private boolean online = false;
private NetChannel channel;
private EntityLocation location = new EntityLocation(0d, 0d, 0d, 0f, 0f, null);
private EntityLocation location = EntityLocation.ZERO();
private Reference<World> $refWorld;
private boolean flying = false;
private PlayerSettings settings;
private List<Integer> loadedChunks = new ArrayList<>();
public void setLocation(EntityLocation location) {
this.location.setXYZ(location);
this.location.setYawPitch(location);
}
@Override
public UUID getUUID() {
return uuid;
}
@Override
public World getWorld() {
if ($refWorld == null) {
return null;
} else if ($refWorld.get() == null) {
throw new ResourceUnloadedException("You're trying to get unloaded world");
} else {
return $refWorld.get();
}
}
@Override
public void setWorld(World world) {
this.$refWorld = new WeakReference<>(world);
}
public void setUUID(UUID uuid) {
this.uuid = uuid;
}

View File

@@ -5,6 +5,7 @@
package mc.core.world;
import mc.core.EntityLocation;
import mc.core.world.block.BlockLocation;
import mc.core.world.chunk.Chunk;
public interface World {
@@ -15,4 +16,12 @@ public interface World {
Chunk getChunk(int x, int z);
void setChunk(int x, int z, Chunk chunkSection);
default Chunk getChunk(BlockLocation location) {
return getChunk(location.getX() >> 4, location.getZ() >> 4);
}
default Chunk getChunk(EntityLocation location) {
return getChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4);
}
}

View File

@@ -3,7 +3,6 @@ package mc.core.world.block;
import com.flowpowered.nbt.Tag;
import lombok.Getter;
import lombok.Setter;
import mc.core.Location;
import java.util.HashMap;
import java.util.Map;
@@ -12,7 +11,7 @@ import java.util.stream.Stream;
public abstract class AbstractBlock implements Block {
@Getter
@Setter
private Location location;
private BlockLocation location;
@Getter
private int light = 0;
@Getter

View File

@@ -1,11 +1,10 @@
package mc.core.world.block;
import mc.core.Location;
import mc.core.nbt.Taggable;
public interface Block extends Taggable{
int getLight();
void setLight(int light);
BlockType getBlockType();
Location getLocation();
BlockLocation getLocation();
}

View File

@@ -1,19 +1,16 @@
package mc.core.world.block;
import mc.core.Location;
import mc.core.world.World;
public class BlockFactory {
public Block create(BlockType blockType, int x, int y, int z, World world) {
return new EmbeddedBlock(blockType, x, y, z, world);
public Block create(BlockType blockType, int x, int y, int z) {
return new EmbeddedBlock(blockType, x, y, z);
}
/** For first-time generation */
private class EmbeddedBlock extends AbstractBlock {
EmbeddedBlock(BlockType type, int x, int y, int z, World world) {
EmbeddedBlock(BlockType type, int x, int y, int z) {
super(type);
setLocation(new Location(x,y,z, world));
setLocation(new BlockLocation(x, y, z));
}
}
}

View File

@@ -0,0 +1,26 @@
package mc.core.world.block;
import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class BlockLocation implements Cloneable {
private int x, y, z;
public void setXYZ(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public BlockLocation clone() {
try {
return (BlockLocation) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,40 @@
package mc.core;
import mc.core.world.block.BlockLocation;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.ThreadLocalRandom;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class TestBlockLocation {
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current();
private static final int minI = 0, maxI = 10;
private int x, y, z;
@Before
public void before() {
x = rnd.nextInt(minI, maxI);
y = rnd.nextInt(minI, maxI);
z = rnd.nextInt(minI, maxI);
}
@Test
public void testEquals() {
BlockLocation loc1 = new BlockLocation(x, y, z);
BlockLocation loc2 = new BlockLocation(x, y, z);
assertEquals(loc1, loc2);
loc2 = new BlockLocation(x+1, y+2, z-3);
assertNotEquals(loc1, loc2);
}
@Test
public void testClone() {
BlockLocation locOrig = new BlockLocation(x, y, z);
BlockLocation locClone = locOrig.clone();
assertEquals(locOrig, locClone);
}
}

View File

@@ -1,35 +1,91 @@
package mc.core;
import mc.core.world.World;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.concurrent.ThreadLocalRandom;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import static org.junit.Assert.assertNotEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class TestEntityLocation {
@Autowired
@Qualifier("simpleMockWorld")
private World mockWorld;
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current();
private static final double minD = 0.0d, maxD = 10.0d;
private static final float minF = 0.0f, maxF = 359.9f;
private double x, y, z;
private float yaw, pitch;
@Before
public void before() {
x = rnd.nextDouble(minD, maxD);
y = rnd.nextDouble(minD, maxD);
z = rnd.nextDouble(minD, maxD);
yaw = rnd.nextFloat() * (maxF - minF) + minF;
pitch = rnd.nextFloat() * (maxF - minF) + minF;
}
@Test
public void cloneTest() {
EntityLocation firstLocation = new EntityLocation(10, 20, 30, 40, 50, mockWorld);
assertSame("Lost world reference before cloning", mockWorld, firstLocation.getWorld());
EntityLocation locationClone = firstLocation.clone();
public void testEquals() {
EntityLocation loc1 = new EntityLocation(x, y, z, yaw, pitch);
EntityLocation loc2 = new EntityLocation(x, y, z, yaw, pitch);
assertEquals(loc1, loc2);
assertEquals("X mismatch", firstLocation.getX(), locationClone.getX(), 0);
assertEquals("Y mismatch", firstLocation.getY(), locationClone.getY(), 0);
assertEquals("Z mismatch", firstLocation.getZ(), locationClone.getZ(), 0);
assertEquals("Pitch mismatch", firstLocation.getPitch(), locationClone.getPitch(), 0);
assertEquals("Yaw mismatch", firstLocation.getYaw(), locationClone.getYaw(), 0);
assertSame("World mismatch (accidental clone of the World object?)", firstLocation.getWorld(), locationClone.getWorld());
loc2 = new EntityLocation(x+1, y+2, z-3, yaw, pitch);
assertNotEquals(loc1, loc2);
loc2 = new EntityLocation(x, y, z, yaw-1, pitch+2);
assertNotEquals(loc1, loc2);
}
@Test
public void testClone() {
EntityLocation locOrig = new EntityLocation(x, y, z, yaw, pitch);
EntityLocation locClone = locOrig.clone();
assertEquals(locOrig, locClone);
}
@Test
public void testGetBlockXZ() {
EntityLocation location;
location = new EntityLocation(0d, 0, 0d, 0f, 0f);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.1d, 0, 0.1d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.5d, 0, 0.5d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.9d, 0, 0.9d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(1d, 0, 1d);
assertEquals(1, location.getBlockX());
assertEquals(1, location.getBlockZ());
location.setXYZ(-0.1d, 0, -0.1d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-0.5d, 0, -0.5d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-0.9d, 0, -0.9d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-1d, 0, -1d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-1.1d, 0, -1.1d);
assertEquals(-2, location.getBlockX());
assertEquals(-2, location.getBlockZ());
}
}

View File

@@ -1,119 +0,0 @@
package mc.core;
import mc.core.world.World;
import mc.core.world.chunk.Chunk;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class TestLocation {
@Autowired
@Qualifier("chunkedMockWorld")
private World world;
@Test
public void testGetBlockXZ() {
Location location;
location = new Location(0d, 0, 0d, world);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.1d, 0, 0.1d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.5d, 0, 0.5d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(0.9d, 0, 0.9d);
assertEquals(0, location.getBlockX());
assertEquals(0, location.getBlockZ());
location.setXYZ(1d, 0, 1d);
assertEquals(1, location.getBlockX());
assertEquals(1, location.getBlockZ());
location.setXYZ(-0.1d, 0, -0.1d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-0.5d, 0, -0.5d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-0.9d, 0, -0.9d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-1d, 0, -1d);
assertEquals(-1, location.getBlockX());
assertEquals(-1, location.getBlockZ());
location.setXYZ(-1.1d, 0, -1.1d);
assertEquals(-2, location.getBlockX());
assertEquals(-2, location.getBlockZ());
}
@Test
public void testGetChunk() {
Location location;
Chunk chunk;
location = new Location(0d, 0, 0d, world);
chunk = location.getChunk();
assertEquals(0, chunk.getX());
assertEquals(0, chunk.getZ());
location.setXYZ(1d, 0, 1d);
chunk = location.getChunk();
assertEquals(0, chunk.getX());
assertEquals(0, chunk.getZ());
location.setXYZ(15d, 0, 15d);
chunk = location.getChunk();
assertEquals(0, chunk.getX());
assertEquals(0, chunk.getZ());
location.setXYZ(16d, 0, 16d);
chunk = location.getChunk();
assertEquals(1, chunk.getX());
assertEquals(1, chunk.getZ());
location.setXYZ(-0.1d, 0, -0.1d);
chunk = location.getChunk();
assertEquals(-1, chunk.getX());
assertEquals(-1, chunk.getZ());
location.setXYZ(-1d, 0, -1d);
chunk = location.getChunk();
assertEquals(-1, chunk.getX());
assertEquals(-1, chunk.getZ());
location.setXYZ(-15d, 0, -15d);
chunk = location.getChunk();
assertEquals(-1, chunk.getX());
assertEquals(-1, chunk.getZ());
//TODO на практике, таких точных значений не встретиться, но тем не менее данный тест не проходит
//location.setXYZ(-16.0d, 0, -16.0d);
//chunk = location.getChunk();
//assertEquals(-2, chunk.getX());
//assertEquals(-2, chunk.getZ());
location.setXYZ(-16.001d, 0, -16.001d);
chunk = location.getChunk();
assertEquals(-2, chunk.getX());
assertEquals(-2, chunk.getZ());
}
}