added bombs
This commit is contained in:
@@ -7,10 +7,7 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.entity.EntityCreature;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.entity.attribute.Attribute;
|
import net.minestom.server.entity.attribute.Attribute;
|
||||||
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
||||||
import net.minestom.server.event.player.PlayerTickEvent;
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
@@ -18,20 +15,21 @@ import net.minestom.server.instance.block.Block;
|
|||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
class TurtleGame extends StatelessGame {
|
class TurtleGame extends StatelessGame {
|
||||||
private final boolean firstPerson;
|
|
||||||
private final int radius;
|
private final int radius;
|
||||||
private final Map<Player, EntityCreature> turtlePlayerMap = new WeakHashMap<>();
|
private final Map<Player, EntityCreature> turtlePlayerMap = new WeakHashMap<>();
|
||||||
|
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
||||||
private final ArrayList<Entity> snacks = new ArrayList<>();
|
private final ArrayList<Entity> snacks = new ArrayList<>();
|
||||||
private final double speed = 2;
|
private final ArrayList<Entity> bombs = new ArrayList<>();
|
||||||
|
private double speed = 2;
|
||||||
|
|
||||||
public TurtleGame(boolean firstPerson, int radius) {
|
public TurtleGame(int radius) {
|
||||||
super(Dimension.OVERWORLD.key, "Turtle Game", new PointsWinScore());
|
super(Dimension.OVERWORLD.key, "Turtle Game", new PointsWinScore());
|
||||||
this.firstPerson = firstPerson;
|
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
|
|
||||||
this.eventNode()
|
this.eventNode()
|
||||||
@@ -60,20 +58,39 @@ class TurtleGame extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
||||||
EntityCreature turtle = this.turtlePlayerMap.get(event.getPlayer());
|
Player p = event.getPlayer();
|
||||||
turtle.teleport(turtle.getPosition().withView(event.getPlayer().getPosition()));
|
if(p.getGameMode() == GameMode.SPECTATOR) return;
|
||||||
Vec direction = event.getPlayer().getPosition().direction();
|
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
||||||
|
turtle.teleport(turtle.getPosition().withView(p.getPosition()));
|
||||||
|
Vec direction = p.getPosition().direction();
|
||||||
if(this.isRunning()) {
|
if(this.isRunning()) {
|
||||||
Vec targetDirection = direction.withY(0).normalize().mul(this.speed);
|
Vec targetDirection = direction.withY(0).normalize().mul(this.speed);
|
||||||
turtle.setVelocity(targetDirection);
|
turtle.setVelocity(targetDirection);
|
||||||
|
|
||||||
List<Entity> hit = this.snacks.stream()
|
List<Entity> hitSnacks = this.snacks.stream()
|
||||||
.filter(snack -> snack.getBoundingBox().intersectBox(turtle.getPosition().sub(snack.getPosition()), turtle.getBoundingBox()))
|
.filter(snack -> snack.getBoundingBox().intersectBox(turtle.getPosition().sub(snack.getPosition()), turtle.getBoundingBox()))
|
||||||
.toList();
|
.toList();
|
||||||
hit.forEach(snack -> {
|
List<Entity> hitBombs = this.bombs.stream()
|
||||||
|
.filter(bomb -> bomb.getBoundingBox().intersectBox(turtle.getPosition().sub(bomb.getPosition()), turtle.getBoundingBox()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
hitSnacks.forEach(snack -> {
|
||||||
this.snacks.remove(snack);
|
this.snacks.remove(snack);
|
||||||
snack.remove();
|
snack.remove();
|
||||||
this.generateNewSnack();
|
this.generateNewSnack();
|
||||||
|
this.scoreMap.put(p, this.scoreMap.get(p) + 1);
|
||||||
|
});
|
||||||
|
hitBombs.forEach(bomb -> {
|
||||||
|
p.setGameMode(GameMode.SPECTATOR);
|
||||||
|
p.setFlying(true);
|
||||||
|
turtle.removePassenger(p);
|
||||||
|
turtle.remove();
|
||||||
|
turtle.kill();
|
||||||
|
this.bombs.remove(bomb);
|
||||||
|
bomb.remove();
|
||||||
|
this.generateNewBomb();
|
||||||
|
this.getScore().insertResult(p, this.scoreMap.get(p));
|
||||||
|
this.speed += 0.5;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,6 +103,7 @@ class TurtleGame extends StatelessGame {
|
|||||||
EntityCreature turtle = new EntityCreature(EntityType.TURTLE);
|
EntityCreature turtle = new EntityCreature(EntityType.TURTLE);
|
||||||
this.turtlePlayerMap.put(p, turtle);
|
this.turtlePlayerMap.put(p, turtle);
|
||||||
}
|
}
|
||||||
|
this.scoreMap.putIfAbsent(p, 0);
|
||||||
|
|
||||||
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
||||||
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
|
||||||
@@ -116,38 +134,67 @@ class TurtleGame extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewSnack() {
|
private void generateNewSnack() {
|
||||||
Pos spawnPosition;
|
|
||||||
boolean isInRadius, collides;
|
|
||||||
int counter = 0;
|
|
||||||
Entity snack = new Entity(EntityType.FALLING_BLOCK);
|
Entity snack = new Entity(EntityType.FALLING_BLOCK);
|
||||||
FallingBlockMeta meta = (FallingBlockMeta) snack.getEntityMeta();
|
FallingBlockMeta meta = (FallingBlockMeta) snack.getEntityMeta();
|
||||||
meta.setBlock(Block.CHORUS_FLOWER);
|
meta.setBlock(Block.SUNFLOWER.withProperty("half", "upper"));
|
||||||
snack.setInstance(this);
|
snack.setInstance(this);
|
||||||
|
Pos spawnPosition = this.newSpawnPosition(snack);
|
||||||
do {
|
if(spawnPosition == null) {
|
||||||
if(counter > 200) {
|
|
||||||
snack.remove();
|
snack.remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
snack.teleport(spawnPosition);
|
||||||
|
this.snacks.add(snack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateNewBomb() {
|
||||||
|
Entity bomb = new Entity(EntityType.FALLING_BLOCK);
|
||||||
|
FallingBlockMeta meta = (FallingBlockMeta) bomb.getEntityMeta();
|
||||||
|
meta.setBlock(Block.TNT);
|
||||||
|
bomb.setInstance(this);
|
||||||
|
Pos spawnPosition = this.newSpawnPosition(bomb, 2);
|
||||||
|
if(spawnPosition == null) {
|
||||||
|
bomb.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bomb.teleport(spawnPosition);
|
||||||
|
this.bombs.add(bomb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Pos newSpawnPosition(Entity entity) {
|
||||||
|
return this.newSpawnPosition(entity, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Pos newSpawnPosition(Entity entity, double border) {
|
||||||
|
Pos spawnPosition;
|
||||||
|
int counter = 0;
|
||||||
|
boolean isInRadius, collides;
|
||||||
|
do {
|
||||||
|
if(counter > 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
int x = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
int x = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
||||||
int z = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
int z = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
||||||
spawnPosition = new Pos(x, 1, z).add(0.5, 0, 0.5);
|
spawnPosition = new Pos(x, 1, z).add(0.5, 0, 0.5);
|
||||||
Pos checkPosition = spawnPosition;
|
Pos checkPosition = spawnPosition;
|
||||||
isInRadius = checkPosition.distance(0, 1, 0) < this.radius-3;
|
isInRadius = checkPosition.distance(0, 1, 0) < this.radius-3;
|
||||||
collides = this.getEntities().stream()
|
collides = this.getEntities().stream()
|
||||||
.filter(entity -> !entity.equals(snack))
|
.filter(e -> !e.equals(entity))
|
||||||
.anyMatch(entity -> snack.getBoundingBox().intersectBox(entity.getPosition().sub(checkPosition), entity.getBoundingBox()));
|
.anyMatch(e -> entity.getBoundingBox().growSymmetrically(border, border, border).intersectBox(e.getPosition().sub(checkPosition), e.getBoundingBox()));
|
||||||
counter++;
|
counter++;
|
||||||
} while (!isInRadius || collides);
|
} while (!isInRadius || collides);
|
||||||
|
return spawnPosition;
|
||||||
snack.teleport(spawnPosition);
|
|
||||||
this.snacks.add(snack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
this.generateNewSnack();
|
this.generateNewSnack();
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
this.generateNewBomb();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import eu.mhsl.minenet.minigames.instance.game.Game;
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.BoolOption;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
||||||
import eu.mhsl.minenet.minigames.instance.room.Room;
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
@@ -27,13 +26,12 @@ public class TurtleGameFactory implements GameFactory {
|
|||||||
@Override
|
@Override
|
||||||
public ConfigManager configuration() {
|
public ConfigManager configuration() {
|
||||||
return new ConfigManager()
|
return new ConfigManager()
|
||||||
.addOption(new BoolOption("firstPerson", Material.SPYGLASS, TranslatedComponent.byId("game_TurtleGame#firstPerson")))
|
|
||||||
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30, 40));
|
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30, 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
return new TurtleGame(configuration.get("firstPerson").getAsBoolean(), configuration.get("radius").getAsInt());
|
return new TurtleGame(configuration.get("radius").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user