Added EntityFireEvent and EntitySpawnEvent

This commit is contained in:
Felix Cravic 2020-05-05 21:04:05 +02:00
parent 0627d8d368
commit 5de6888b59
9 changed files with 88 additions and 52 deletions

View File

@ -17,7 +17,6 @@ import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material; import net.minestom.server.item.Material;
import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionManager;
import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.ping.ResponseDataConsumer;
import net.minestom.server.storage.StorageFolder;
import net.minestom.server.timer.TaskRunnable; import net.minestom.server.timer.TaskRunnable;
import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position; import net.minestom.server.utils.Position;
@ -33,11 +32,11 @@ public class PlayerInit {
private static volatile InstanceContainer instanceContainer; private static volatile InstanceContainer instanceContainer;
static { static {
StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("chunk_data"); //StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("chunk_data");
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator(); NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder); //instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(); instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer();
instanceContainer.enableAutoChunkLoad(true); instanceContainer.enableAutoChunkLoad(true);
instanceContainer.setChunkGenerator(noiseTestGenerator); instanceContainer.setChunkGenerator(noiseTestGenerator);

View File

@ -15,14 +15,14 @@ public class StoneBlock extends CustomBlock {
@Override @Override
public void onPlace(Instance instance, BlockPosition blockPosition, Data data) { public void onPlace(Instance instance, BlockPosition blockPosition, Data data) {
System.out.println("PLACED at "+blockPosition);
} }
@Override @Override
public void onDestroy(Instance instance, BlockPosition blockPosition, Data data) { public void onDestroy(Instance instance, BlockPosition blockPosition, Data data) {
BlockPosition above = blockPosition.clone().add(0, 1, 0); BlockPosition above = blockPosition.clone().add(0, 1, 0);
CustomBlock blockAbove = instance.getCustomBlock(above); CustomBlock blockAbove = instance.getCustomBlock(above);
if(blockAbove == this) { if (blockAbove == this) {
instance.setBlock(above, Block.AIR); instance.setBlock(above, Block.AIR);
instance.setBlock(blockPosition, Block.AIR); // this should NOT create a stack overflow simply because we are trying to remove this same block instance.setBlock(blockPosition, Block.AIR); // this should NOT create a stack overflow simply because we are trying to remove this same block
} }
@ -30,9 +30,7 @@ public class StoneBlock extends CustomBlock {
@Override @Override
public void updateFromNeighbor(Instance instance, BlockPosition thisPosition, BlockPosition neighborPosition, boolean directNeighbor) { public void updateFromNeighbor(Instance instance, BlockPosition thisPosition, BlockPosition neighborPosition, boolean directNeighbor) {
if(directNeighbor) {
System.out.println("Block at "+thisPosition+" has been updated by neighbor at "+neighborPosition);
}
} }
@Override @Override

View File

@ -25,24 +25,11 @@ public class SimpleCommand implements CommandProcessor {
Instance instance = player.getInstance(); Instance instance = player.getInstance();
instance.saveChunksToStorageFolder();
for (EntityCreature creature : instance.getCreatures()) { for (EntityCreature creature : instance.getCreatures()) {
creature.setPathTo(player.getPosition()); creature.setPathTo(player.getPosition());
} }
/*StorageManager storageManager = MinecraftServer.getStorageManager();
StorageFolder storageFolder = storageManager.getFolder("player_data");
// Load a data directly into a DataContainer
// The StorageFolder keeps track of the returned data and automatically save it with the #save method
storageFolder.getAndCacheData("held_data", player.getInventory().getItemInMainHand());
storageFolder.saveCachedData();*/
player.sendMessage("Direction: " + MathUtils.getHorizontalDirection(player.getPosition().getYaw())); player.sendMessage("Direction: " + MathUtils.getHorizontalDirection(player.getPosition().getYaw()));
return true; return true;

View File

@ -7,11 +7,11 @@ import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.data.Data; import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer; import net.minestom.server.data.DataContainer;
import net.minestom.server.event.CancellableEvent; import net.minestom.server.event.CancellableEvent;
import net.minestom.server.event.EntitySpawnEvent;
import net.minestom.server.event.Event; import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback; import net.minestom.server.event.EventCallback;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.network.packet.PacketWriter; import net.minestom.server.network.packet.PacketWriter;
import net.minestom.server.network.packet.server.play.*; import net.minestom.server.network.packet.server.play.*;
@ -127,15 +127,17 @@ public abstract class Entity implements Viewable, DataContainer {
/** /**
* Checks if now is a good time to send a velocity update packet * Checks if now is a good time to send a velocity update packet
* @return *
* @param time * @param time
* @return
*/ */
protected boolean shouldSendVelocityUpdate(long time) { protected boolean shouldSendVelocityUpdate(long time) {
return (time-lastVelocityUpdateTime) >= velocityUpdatePeriod; return (time - lastVelocityUpdateTime) >= velocityUpdatePeriod;
} }
/** /**
* Gets the period, in ms, between two velocity update packets * Gets the period, in ms, between two velocity update packets
*
* @return period, in ms, between two velocity update packets * @return period, in ms, between two velocity update packets
*/ */
public long getVelocityUpdatePeriod() { public long getVelocityUpdatePeriod() {
@ -144,6 +146,7 @@ public abstract class Entity implements Viewable, DataContainer {
/** /**
* Sets the period, in ms, between two velocity update packets * Sets the period, in ms, between two velocity update packets
*
* @param velocityUpdatePeriod period, in ms, between two velocity update packets * @param velocityUpdatePeriod period, in ms, between two velocity update packets
*/ */
public void setVelocityUpdatePeriod(long velocityUpdatePeriod) { public void setVelocityUpdatePeriod(long velocityUpdatePeriod) {
@ -248,14 +251,14 @@ public abstract class Entity implements Viewable, DataContainer {
Position newPosition = new Position(newX, newY, newZ); Position newPosition = new Position(newX, newY, newZ);
if (!(this instanceof Player) && !noGravity) { // players handle gravity by themselves if (!(this instanceof Player) && !noGravity) { // players handle gravity by themselves
velocity.setY(velocity.getY() - gravityDragPerTick*tps); velocity.setY(velocity.getY() - gravityDragPerTick * tps);
} }
Vector newVelocityOut = new Vector(); Vector newVelocityOut = new Vector();
Vector deltaPos = new Vector( Vector deltaPos = new Vector(
getVelocity().getX()/tps, getVelocity().getX() / tps,
getVelocity().getY()/tps, getVelocity().getY() / tps,
getVelocity().getZ()/tps getVelocity().getZ() / tps
); );
onGround = CollisionUtils.handlePhysics(this, deltaPos, newPosition, newVelocityOut); onGround = CollisionUtils.handlePhysics(this, deltaPos, newPosition, newVelocityOut);
@ -264,7 +267,7 @@ public abstract class Entity implements Viewable, DataContainer {
velocity.multiply(tps); velocity.multiply(tps);
float drag; float drag;
if(onGround) { if (onGround) {
drag = 0.5f; // ground drag drag = 0.5f; // ground drag
} else { } else {
drag = 0.98f; // air drag drag = 0.98f; // air drag
@ -287,17 +290,17 @@ public abstract class Entity implements Viewable, DataContainer {
int maxY = (int) Math.ceil(boundingBox.getMaxY()); int maxY = (int) Math.ceil(boundingBox.getMaxY());
int minZ = (int) Math.floor(boundingBox.getMinZ()); int minZ = (int) Math.floor(boundingBox.getMinZ());
int maxZ = (int) Math.ceil(boundingBox.getMaxZ()); int maxZ = (int) Math.ceil(boundingBox.getMaxZ());
BlockPosition tmpPosition = new BlockPosition(0,0,0); // allow reuse BlockPosition tmpPosition = new BlockPosition(0, 0, 0); // allow reuse
for (int y = minY; y <= maxY; y++) { for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) { for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) { for (int z = minZ; z <= maxZ; z++) {
CustomBlock customBlock = instance.getCustomBlock(x, y, z); CustomBlock customBlock = instance.getCustomBlock(x, y, z);
if(customBlock != null) { if (customBlock != null) {
tmpPosition.setX(x); tmpPosition.setX(x);
tmpPosition.setY(y); tmpPosition.setY(y);
tmpPosition.setZ(z); tmpPosition.setZ(z);
// checks that we are actually in the block, and not just here because of a rounding error // checks that we are actually in the block, and not just here because of a rounding error
if(boundingBox.intersect(tmpPosition)) { if (boundingBox.intersect(tmpPosition)) {
// TODO: replace with check with custom block bounding box // TODO: replace with check with custom block bounding box
customBlock.handleContact(instance, tmpPosition, this); customBlock.handleContact(instance, tmpPosition, this);
} }
@ -397,6 +400,8 @@ public abstract class Entity implements Viewable, DataContainer {
this.instance = instance; this.instance = instance;
instance.addEntity(this); instance.addEntity(this);
spawn(); spawn();
EntitySpawnEvent entitySpawnEvent = new EntitySpawnEvent(instance);
callEvent(EntitySpawnEvent.class, entitySpawnEvent);
} }
public Vector getVelocity() { public Vector getVelocity() {

View File

@ -5,6 +5,7 @@ import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.property.Attribute; import net.minestom.server.entity.property.Attribute;
import net.minestom.server.event.DeathEvent; import net.minestom.server.event.DeathEvent;
import net.minestom.server.event.EntityDamageEvent; import net.minestom.server.event.EntityDamageEvent;
import net.minestom.server.event.EntityFireEvent;
import net.minestom.server.event.PickupItemEvent; import net.minestom.server.event.PickupItemEvent;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
@ -64,11 +65,11 @@ public abstract class LivingEntity extends Entity {
@Override @Override
public void update() { public void update() {
if(isOnFire()) { if (isOnFire()) {
if(System.currentTimeMillis() > fireExtinguishTime) { if (System.currentTimeMillis() > fireExtinguishTime) {
setOnFire(false); setOnFire(false);
} else { } else {
if(System.currentTimeMillis() - lastFireDamageTime > fireDamagePeriod) { if (System.currentTimeMillis() - lastFireDamageTime > fireDamagePeriod) {
damage(DamageType.ON_FIRE, 1.0f); damage(DamageType.ON_FIRE, 1.0f);
lastFireDamageTime = System.currentTimeMillis(); lastFireDamageTime = System.currentTimeMillis();
} }
@ -137,21 +138,26 @@ public abstract class LivingEntity extends Entity {
/** /**
* Sets fire to this entity for a given duration * Sets fire to this entity for a given duration
*
* @param duration duration in ticks of the effect * @param duration duration in ticks of the effect
*/ */
public void setFireForDuration(int duration) { public void setFireForDuration(int duration) {
setOnFire(true);
setFireForDuration(duration, TimeUnit.TICK); setFireForDuration(duration, TimeUnit.TICK);
} }
/** /**
* Sets fire to this entity for a given duration * Sets fire to this entity for a given duration
*
* @param duration duration of the effet * @param duration duration of the effet
* @param unit unit used to express the duration * @param unit unit used to express the duration
*/ */
public void setFireForDuration(int duration, TimeUnit unit) { public void setFireForDuration(int duration, TimeUnit unit) {
setOnFire(true); EntityFireEvent entityFireEvent = new EntityFireEvent(duration, unit);
fireExtinguishTime = System.currentTimeMillis()+unit.toMilliseconds(duration); callCancellableEvent(EntityFireEvent.class, entityFireEvent, () -> {
long fireTime = entityFireEvent.getFireTime(TimeUnit.MILLISECOND);
setOnFire(true);
fireExtinguishTime = System.currentTimeMillis() + fireTime;
});
} }
/** /**
@ -176,9 +182,9 @@ public abstract class LivingEntity extends Entity {
// play damage sound // play damage sound
Sound sound = type.getSound(this); Sound sound = type.getSound(this);
if(sound != null) { if (sound != null) {
SoundCategory soundCategory; SoundCategory soundCategory;
if(this instanceof Player) { if (this instanceof Player) {
soundCategory = SoundCategory.PLAYERS; soundCategory = SoundCategory.PLAYERS;
} else { } else {
// TODO: separate living entity categories // TODO: separate living entity categories

View File

@ -0,0 +1,31 @@
package net.minestom.server.event;
import net.minestom.server.utils.time.TimeUnit;
public class EntityFireEvent extends CancellableEvent {
private int duration;
private TimeUnit timeUnit;
public EntityFireEvent(int duration, TimeUnit timeUnit) {
setFireTime(duration, timeUnit);
}
public long getFireTime(TimeUnit timeUnit) {
switch (timeUnit) {
case TICK:
return duration;
case MILLISECOND:
return timeUnit.toMilliseconds(duration);
default:
// Unexpected
return -1;
}
}
public void setFireTime(int duration, TimeUnit timeUnit) {
this.duration = duration;
this.timeUnit = timeUnit;
}
}

View File

@ -0,0 +1,17 @@
package net.minestom.server.event;
import net.minestom.server.instance.Instance;
public class EntitySpawnEvent extends Event {
private Instance spawnInstance;
public EntitySpawnEvent(Instance spawnInstance) {
this.spawnInstance = spawnInstance;
}
public Instance getSpawnInstance() {
return spawnInstance;
}
}

View File

@ -2,15 +2,8 @@ package net.minestom.server.event;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
public class PlayerSpawnEvent extends Event { public class PlayerSpawnEvent extends EntitySpawnEvent {
private Instance spawnInstance;
public PlayerSpawnEvent(Instance spawnInstance) { public PlayerSpawnEvent(Instance spawnInstance) {
this.spawnInstance = spawnInstance; super(spawnInstance);
}
public Instance getSpawnInstance() {
return spawnInstance;
} }
} }

View File

@ -15,7 +15,7 @@ public class StorageManager {
public StorageFolder getFolder(String folderName) { public StorageFolder getFolder(String folderName) {
if (storageSystemSupplier == null) if (storageSystemSupplier == null)
throw new NullPointerException("You need to define a storage system before using the Storage API"); throw new NullPointerException("You need to define a storage system before using the Storage API");
StorageSystem storageSystem = storageSystemSupplier.get(); StorageSystem storageSystem = storageSystemSupplier.get();
return folderMap.computeIfAbsent(folderName, s -> new StorageFolder(storageSystem, folderName)); return folderMap.computeIfAbsent(folderName, s -> new StorageFolder(storageSystem, folderName));
} }