Merge branch 'proto_1.12.2' into h2-playermanager
# Conflicts: # core/src/main/java/mc/core/EntityLocation.java # core/src/main/java/mc/core/Location.java # core/src/test/java/mc/core/TestEntityLocation.java # core/src/test/java/mc/core/TestLocation.java
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -1,23 +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;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
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) {
|
||||
@@ -25,27 +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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
EntityLocation that = (EntityLocation) o;
|
||||
return Float.compare(that.yaw, yaw) == 0 &&
|
||||
Float.compare(that.pitch, pitch) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), yaw, pitch);
|
||||
try {
|
||||
return (EntityLocation) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
core/src/main/java/mc/core/ImmutableEntityLocation.java
Normal file
57
core/src/main/java/mc/core/ImmutableEntityLocation.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package mc.core;
|
||||
|
||||
public class ImmutableEntityLocation extends EntityLocation {
|
||||
public ImmutableEntityLocation(double x, double y, double z, float yaw, float pitch) {
|
||||
super(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
public ImmutableEntityLocation(EntityLocation location) {
|
||||
this(
|
||||
location.getX(),
|
||||
location.getY(),
|
||||
location.getZ(),
|
||||
location.getYaw(),
|
||||
location.getPitch()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setX(double x) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setY(double y) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZ(double z) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setYaw(float yaw) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPitch(float pitch) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(EntityLocation location) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXYZ(double x, double y, double z) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setYawPitch(float yaw, float pitch) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -1,108 +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;
|
||||
import java.util.Objects;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Location location = (Location) obj;
|
||||
return Double.compare(location.x, x) == 0 &&
|
||||
Double.compare(location.y, y) == 0 &&
|
||||
Double.compare(location.z, z) == 0 &&
|
||||
Objects.equals(refWorld.get(), location.refWorld.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y, z, refWorld.get());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,23 @@
|
||||
package mc.core.eventbus.events;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import mc.core.EntityLocation;
|
||||
import mc.core.ImmutableEntityLocation;
|
||||
import mc.core.eventbus.EventBase;
|
||||
import mc.core.player.Player;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public class CS_PlayerMoveEvent extends EventBase {
|
||||
private final Player player;
|
||||
private final EntityLocation oldLocation; // TODO сомнительное решение
|
||||
// вообще нужно будет создать реализацию "иммутабл локейшен" для подобных ситуаций
|
||||
private final ImmutableEntityLocation oldLocation;
|
||||
@Setter
|
||||
private EntityLocation newLocation;
|
||||
@Setter
|
||||
private boolean recalcChunk = false;
|
||||
|
||||
public CS_PlayerMoveEvent(Player player, EntityLocation oldLocation) {
|
||||
this.player = player;
|
||||
this.oldLocation = new ImmutableEntityLocation(oldLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -25,18 +25,4 @@ public class CompactedCoords {
|
||||
int i = (int)value;
|
||||
return value < (double)i ? i - 1 : i;
|
||||
}
|
||||
|
||||
public static long compressXYZ(double x, double y, double z) {
|
||||
return ((floor_double(x) & 0x3FFFFFF) << 38)
|
||||
| ((floor_double(y) & 0xFFF) << 26)
|
||||
| (floor_double(z) & 0x3FFFFFF);
|
||||
}
|
||||
|
||||
public static double[] uncompressXYZ(long compactValue) {
|
||||
return new double[]{
|
||||
compactValue >> 38,
|
||||
(compactValue >> 26) & 0x0FFF,
|
||||
compactValue << 38 >> 38 // is normal?
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -16,4 +17,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
core/src/main/java/mc/core/world/block/BlockLocation.java
Normal file
30
core/src/main/java/mc/core/world/block/BlockLocation.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package mc.core.world.block;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class BlockLocation implements Cloneable {
|
||||
private int x, y, z;
|
||||
|
||||
public static BlockLocation ZERO() {
|
||||
return new BlockLocation(0,0,0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
core/src/test/java/mc/core/SpringConfig.java
Normal file
34
core/src/test/java/mc/core/SpringConfig.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package mc.core;
|
||||
|
||||
import mc.core.world.World;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Configuration
|
||||
public class SpringConfig {
|
||||
@Bean()
|
||||
public World simpleMockWorld() {
|
||||
return mock(World.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public World chunkedMockWorld() {
|
||||
World world = mock(World.class);
|
||||
when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
|
||||
Chunk chunk = mock(Chunk.class);
|
||||
when(chunk.getX()).thenReturn((int) args[0]);
|
||||
when(chunk.getZ()).thenReturn((int) args[1]);
|
||||
|
||||
return chunk;
|
||||
});
|
||||
|
||||
return world;
|
||||
}
|
||||
}
|
||||
40
core/src/test/java/mc/core/TestBlockLocation.java
Normal file
40
core/src/test/java/mc/core/TestBlockLocation.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package mc.core;
|
||||
|
||||
import mc.core.world.World;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -8,51 +7,85 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class TestEntityLocation {
|
||||
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() {
|
||||
mockWorld = mock(World.class);
|
||||
when(mockWorld.getName()).thenReturn("mock_world");
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
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());
|
||||
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 testEquals() {
|
||||
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
final double minD = 0.0d, maxD = 10.0d;
|
||||
final float minF = 0.0f, maxF = 359.9f;
|
||||
final double x = rnd.nextDouble(minD, maxD);
|
||||
final double y = rnd.nextDouble(minD, maxD);
|
||||
final double z = rnd.nextDouble(minD, maxD);
|
||||
final float yaw = rnd.nextFloat() * (maxF - minF) + minF;
|
||||
final float pitch = rnd.nextFloat() * (maxF - minF) + minF;
|
||||
|
||||
EntityLocation loc1 = new EntityLocation(x, y, z, yaw, pitch, mockWorld);
|
||||
EntityLocation loc2 = new EntityLocation(x, y, z, yaw, pitch, mockWorld);
|
||||
EntityLocation loc1 = new EntityLocation(x, y, z, yaw, pitch);
|
||||
EntityLocation loc2 = new EntityLocation(x, y, z, yaw, pitch);
|
||||
assertEquals(loc1, loc2);
|
||||
|
||||
loc2 = new EntityLocation(x+3, y+1, z+2, yaw, pitch, mockWorld);
|
||||
loc2 = new EntityLocation(x+1, y+2, z-3, yaw, pitch);
|
||||
assertNotEquals(loc1, loc2);
|
||||
loc2 = new EntityLocation(x, y, z, yaw+5, pitch-1, mockWorld);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
35
core/src/test/java/mc/core/TestImmutableEntityLocation.java
Normal file
35
core/src/test/java/mc/core/TestImmutableEntityLocation.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package mc.core;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestImmutableEntityLocation {
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testSetValue() {
|
||||
EntityLocation location = new ImmutableEntityLocation(1d, 2d, 3d, 4f, 5f);
|
||||
|
||||
thrown.expect(UnsupportedOperationException.class);
|
||||
location.setX(1);
|
||||
location.setY(1);
|
||||
location.setZ(1);
|
||||
location.setYaw(1);
|
||||
location.setPitch(1);
|
||||
location.setXYZ(1, 2, 3);
|
||||
location.setYawPitch(1, 2);
|
||||
location.set(EntityLocation.ZERO());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClone() {
|
||||
EntityLocation locOrig = new ImmutableEntityLocation(1d, 2d, 3d, 4f, 5f);
|
||||
EntityLocation locClone = locOrig.clone();
|
||||
|
||||
assertEquals(locOrig, locClone);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +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 java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class TestLocation {
|
||||
private World world;
|
||||
|
||||
@Before
|
||||
public void prepareWorld() {
|
||||
this.world = mock(World.class);
|
||||
when(world.getChunk(anyInt(), anyInt())).thenAnswer(invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
|
||||
Chunk chunk = mock(Chunk.class);
|
||||
when(chunk.getX()).thenReturn((int) args[0]);
|
||||
when(chunk.getZ()).thenReturn((int) args[1]);
|
||||
|
||||
return chunk;
|
||||
});
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
final double minD = 0.0d, maxD = 10.0d;
|
||||
final double x = rnd.nextDouble(minD, maxD);
|
||||
final double y = rnd.nextDouble(minD, maxD);
|
||||
final double z = rnd.nextDouble(minD, maxD);
|
||||
|
||||
Location loc1 = new Location(x, y, z, world);
|
||||
Location loc2 = new Location(x, y, z, world);
|
||||
assertEquals(loc1, loc2);
|
||||
|
||||
loc2 = new Location(x+3, y+1, z+2, world);
|
||||
assertNotEquals(loc1, loc2);
|
||||
}
|
||||
}
|
||||
@@ -2,61 +2,25 @@ package mc.core.utils;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
public class TestCompactedCoords {
|
||||
@Test
|
||||
public void testXZSimple() {
|
||||
for (int z = -100; z <= 100; z++) {
|
||||
for (int x = -100; x <= 100; x++) {
|
||||
int compressXZ = CompactedCoords.compressXZ(x, z);
|
||||
int[] xz = CompactedCoords.uncompressXZ(compressXZ);
|
||||
|
||||
assertEquals(x, xz[0]);
|
||||
assertEquals(z, xz[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXZRandom() {
|
||||
Random random = new Random();
|
||||
int x,z;
|
||||
public void testXZ() {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
do {
|
||||
x = random.nextInt();
|
||||
} while (x < Short.MIN_VALUE || x > Short.MAX_VALUE);
|
||||
final int x = random.nextInt(Short.MIN_VALUE, Short.MAX_VALUE);
|
||||
final int z = random.nextInt(Short.MIN_VALUE, Short.MAX_VALUE);
|
||||
|
||||
do {
|
||||
z = random.nextInt();
|
||||
} while (z < Short.MIN_VALUE || z > Short.MAX_VALUE);
|
||||
|
||||
|
||||
int compressXZ = CompactedCoords.compressXZ(x, z);
|
||||
final int compressXZ = CompactedCoords.compressXZ(x, z);
|
||||
int[] xz = CompactedCoords.uncompressXZ(compressXZ);
|
||||
|
||||
assertEquals(x, xz[0]);
|
||||
assertEquals(z, xz[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testXYZSimple() {
|
||||
for (int z = -100; z <= 100; z++) {
|
||||
for (int x = -100; x <= 100; x++) {
|
||||
for (int y = -100; y <= 100; y++) {
|
||||
long compressXYZ = CompactedCoords.compressXYZ(x, y, z);
|
||||
double[] xyz = CompactedCoords.uncompressXYZ(compressXYZ);
|
||||
|
||||
assertEquals(x, xyz[0], 0.001d);
|
||||
assertEquals(y, xyz[1], 0.001d);
|
||||
assertEquals(z, xyz[2], 0.001d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user