use of org.lanternpowered.server.world.LanternWorld in project LanternServer by LanternPowered.
the class LightningSpawnerAction method run.
@Override
public void run(ScriptContext scriptContext) {
final LanternWorld world = (LanternWorld) scriptContext.get(Parameters.WORLD).get();
final Random random = RANDOM.get();
final Iterable<Chunk> chunks = world.getLoadedChunks();
final int chance = (int) (1f / Math.max(this.chance, 0.000000000001f));
for (Chunk chunk : chunks) {
for (int i = 0; i < this.attemptsPerChunk; i++) {
final LanternChunk chunk1 = (LanternChunk) chunk;
if (random.nextInt(chance) != 0) {
continue;
}
final int value = random.nextInt(0x10000);
final int x = chunk1.getX() << 4 | value & 0xf;
final int z = chunk1.getZ() << 4 | (value >> 4) & 0xf;
final Entity entity = world.createEntity(EntityTypes.LIGHTNING, new Vector3d(x, world.getHighestYAt(x, z), z));
world.spawnEntity(entity);
}
}
}
use of org.lanternpowered.server.world.LanternWorld in project LanternServer by LanternPowered.
the class CommandParticle method completeSpec.
@Override
public void completeSpec(PluginContainer pluginContainer, CommandSpec.Builder specBuilder) {
specBuilder.arguments(new PatternMatchingCommandElement(Text.of("type")) {
@Override
protected Iterable<String> getChoices(CommandSource source) {
return Sponge.getGame().getRegistry().getAllOf(ParticleType.class).stream().filter(type -> ((LanternParticleType) type).getInternalType().isPresent()).map(CatalogType::getId).collect(Collectors.toList());
}
@Override
protected Object getValue(String choice) throws IllegalArgumentException {
final Optional<ParticleType> ret = Sponge.getGame().getRegistry().getType(ParticleType.class, choice);
if (!ret.isPresent() || !((LanternParticleType) ret.get()).getInternalType().isPresent()) {
throw new IllegalArgumentException("Invalid input " + choice + " was found");
}
return ret.get();
}
}, GenericArguments2.targetedVector3d(Text.of("position")), // The default value should be 0 for x, y and z
GenericArguments2.vector3d(Text.of("offset"), Vector3d.ZERO), GenericArguments2.doubleNum(Text.of("speed"), 1.0), GenericArguments.optional(GenericArguments2.integer(Text.of("count"), 1)), GenericArguments.optional(new CommandElement(Text.of("mode")) {
@Nullable
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
return args.next();
}
@Override
public List<String> complete(CommandSource src, CommandArgs args, CommandContext context) {
Optional<String> arg = args.nextIfPresent();
if (arg.isPresent()) {
return Stream.of("normal", "force").filter(new StartsWithPredicate(arg.get())).collect(Collectors.toList());
}
return Collections.emptyList();
}
}), GenericArguments.optional(GenericArguments.player(Text.of("player"))), GenericArguments.optional(new CommandElement(Text.of("params")) {
@Nullable
@Override
protected Object parseValue(CommandSource source, CommandArgs args) throws ArgumentParseException {
List<Integer> params = new ArrayList<>();
while (args.hasNext()) {
String arg = args.next();
try {
params.add(Integer.parseInt(arg));
} catch (NumberFormatException e) {
throw args.createError(t("Expected an integer, but input '%s' was not", arg));
}
}
return params.stream().mapToInt(i -> i).toArray();
}
@Override
public List<String> complete(CommandSource src, CommandArgs args, CommandContext context) {
return Collections.emptyList();
}
})).executor((src, args) -> {
final LanternParticleType particleType = args.<LanternParticleType>getOne("type").get();
final int particleId = particleType.getInternalType().getAsInt();
final Vector3f position = args.<Vector3d>getOne("position").get().toFloat();
final Vector3f offset = args.<Vector3d>getOne("offset").get().toFloat();
final float speed = args.<Double>getOne("speed").get().floatValue();
final int count = args.<Integer>getOne("count").orElse(1);
final boolean longDistance = args.<String>getOne("mode").map(mode -> mode.equalsIgnoreCase("force")).orElse(false);
final int[] params = args.<int[]>getOne("params").orElse(new int[0]);
final LanternWorld world = CommandHelper.getWorld(src, args);
final int dataLength;
if (particleType == ParticleTypes.BLOCK_CRACK || particleType == ParticleTypes.BLOCK_DUST || particleType == ParticleTypes.FALLING_DUST) {
dataLength = 1;
} else if (particleType == ParticleTypes.ITEM_CRACK) {
dataLength = 2;
} else {
dataLength = 0;
}
if (params.length != dataLength) {
throw new CommandException(t("Invalid parameters (%s), length mismatch (got %s, expected %s) for the particle type %s", Arrays.toString(params), params.length, dataLength, particleType.getId()));
}
final MessagePlayOutSpawnParticle message = new MessagePlayOutSpawnParticle(particleId, position, offset, speed, count, params, longDistance);
if (args.hasAny("player")) {
args.<LanternPlayer>getOne("player").get().getConnection().send(message);
} else {
for (LanternPlayer player : world.getRawPlayers()) {
player.getConnection().send(message);
}
}
src.sendMessage(t("commands.particle.success", particleType.getName(), count));
return CommandResult.success();
});
}
use of org.lanternpowered.server.world.LanternWorld in project LanternServer by LanternPowered.
the class LanternPlayer method setWorld.
@Override
public void setWorld(@Nullable LanternWorld world) {
final LanternWorld oldWorld = getWorld();
if (world == oldWorld) {
return;
}
setWorld(oldWorld, world);
}
use of org.lanternpowered.server.world.LanternWorld in project LanternServer by LanternPowered.
the class PlayerInteractionHandler method sendBreakUpdate.
/**
* TODO: Maybe also send this to the player this handler is attached to for
* custom break times? Only allowed by faster breaking.
*/
private void sendBreakUpdate(int breakState) {
final LanternWorld world = this.player.getWorld();
// noinspection ConstantConditions
if (world == null) {
return;
}
final Set<LanternPlayer> players = this.player.getWorld().getRawPlayers();
// Update for all the players except the breaker
if (players.size() - 1 <= 0) {
final MessagePlayOutBlockBreakAnimation message = new MessagePlayOutBlockBreakAnimation(this.diggingBlock, this.player.getNetworkId(), breakState);
players.forEach(player -> {
if (player != this.player) {
player.getConnection().send(message);
}
});
}
}
use of org.lanternpowered.server.world.LanternWorld in project LanternServer by LanternPowered.
the class LanternPlayer method pulseChunkChanges.
public void pulseChunkChanges() {
final LanternWorld world = getWorld();
if (world == null) {
return;
}
ChunkLoadingTicket loadingTicket = this.getChunkLoadingTicket();
Vector3d position = this.getPosition();
double xPos = position.getX();
double zPos = position.getZ();
int centralX = ((int) xPos) >> 4;
int centralZ = ((int) zPos) >> 4;
// Fail fast if the player hasn't moved a chunk
if (this.lastChunkPos != null && this.lastChunkPos.getX() == centralX && this.lastChunkPos.getY() == centralZ) {
return;
}
this.lastChunkPos = new Vector2i(centralX, centralZ);
// Get the radius of visible chunks
int radius = world.getProperties().getConfig().getViewDistance();
if (radius == WorldConfig.USE_SERVER_VIEW_DISTANCE) {
radius = Lantern.getGame().getGlobalConfig().getViewDistance();
}
if (this.viewDistance != -1) {
radius = Math.min(radius, this.viewDistance + 1);
}
final Set<Vector2i> previousChunks = new HashSet<>(this.knownChunks);
final List<Vector2i> newChunks = new ArrayList<>();
for (int x = (centralX - radius); x <= (centralX + radius); x++) {
for (int z = (centralZ - radius); z <= (centralZ + radius); z++) {
final Vector2i coords = new Vector2i(x, z);
if (!previousChunks.remove(coords)) {
newChunks.add(coords);
}
}
}
// Early end if there's no changes
if (newChunks.size() == 0 && previousChunks.size() == 0) {
return;
}
// Sort chunks by distance from player - closer chunks sent/forced first
newChunks.sort((a, b) -> {
double dx = 16 * a.getX() + 8 - xPos;
double dz = 16 * a.getY() + 8 - zPos;
double da = dx * dx + dz * dz;
dx = 16 * b.getX() + 8 - xPos;
dz = 16 * b.getY() + 8 - zPos;
double db = dx * dx + dz * dz;
return Double.compare(da, db);
});
ObservedChunkManager observedChunkManager = world.getObservedChunkManager();
// Force all the new chunks to be loaded and track the changes
newChunks.forEach(coords -> {
observedChunkManager.addObserver(coords, this);
loadingTicket.forceChunk(coords);
});
// Unforce old chunks so they can unload and untrack the chunk
previousChunks.forEach(coords -> {
observedChunkManager.removeObserver(coords, this, true);
loadingTicket.unforceChunk(coords);
});
this.knownChunks.removeAll(previousChunks);
this.knownChunks.addAll(newChunks);
}
Aggregations