From b4a72d274bb507625aad8c219889afb39087953b Mon Sep 17 00:00:00 2001
From: Minecon724 <git@m724.eu>
Date: Mon, 8 Jul 2024 10:00:58 +0200
Subject: [PATCH] holding

---
 src/main/java/net/pivipi/LoginHandler.java    |  5 ++-
 src/main/java/net/pivipi/Main.java            |  4 +-
 src/main/java/net/pivipi/ball/Ball.java       | 33 ++++++++++++++++-
 src/main/java/net/pivipi/ball/BallKicker.java | 37 +++++++++++++++++--
 src/main/java/net/pivipi/physics/Physics.java |  9 +++--
 .../java/net/pivipi/world/FancyDimension.java |  3 +-
 .../net/pivipi/world/SoccerGenerator.java     |  6 +--
 7 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/src/main/java/net/pivipi/LoginHandler.java b/src/main/java/net/pivipi/LoginHandler.java
index 54e2380..915628a 100644
--- a/src/main/java/net/pivipi/LoginHandler.java
+++ b/src/main/java/net/pivipi/LoginHandler.java
@@ -9,6 +9,7 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
 import net.minestom.server.event.player.PlayerDisconnectEvent;
 import net.minestom.server.event.player.PlayerSpawnEvent;
 import net.minestom.server.instance.Instance;
+import net.minestom.server.instance.Weather;
 import net.pivipi.ball.Ball;
 import net.pivipi.ball.BallKicker;
 import net.pivipi.world.Stadium;
@@ -34,7 +35,7 @@ public class LoginHandler {
         event.setSpawningInstance(spawningInstance);
         event.setHardcore(true);
 
-        player.setRespawnPoint(new Pos(5, 5, 0));
+        player.setRespawnPoint(new Pos(0, 67, 0));
         stadium.players.add(player);
     }
     
@@ -52,7 +53,7 @@ public class LoginHandler {
         if (stadium.ball == null) {
             Ball ball = new Ball(stadium);
             ball.setInstance(event.getInstance());
-            ball.teleport(new Pos(0, 15, 0));
+            ball.teleport(new Pos(0, 90, 5));
             stadium.ball = ball;
         }
     }
diff --git a/src/main/java/net/pivipi/Main.java b/src/main/java/net/pivipi/Main.java
index c58be4f..6a412a0 100644
--- a/src/main/java/net/pivipi/Main.java
+++ b/src/main/java/net/pivipi/Main.java
@@ -6,7 +6,10 @@ import net.minestom.server.event.GlobalEventHandler;
 import net.minestom.server.instance.InstanceContainer;
 import net.minestom.server.instance.InstanceManager;
 import net.minestom.server.instance.LightingChunk;
+import net.minestom.server.instance.Weather;
 import net.minestom.server.registry.DynamicRegistry.Key;
+import net.minestom.server.timer.SchedulerManager;
+import net.minestom.server.timer.TaskSchedule;
 import net.minestom.server.world.DimensionType;
 import net.pivipi.world.FancyDimension;
 import net.pivipi.world.SoccerGenerator;
@@ -34,7 +37,6 @@ public class Main {
         WorldConstraints worldConstraints = new WorldConstraints();
         worldConstraints.setup(globalEventHandler);
 
-
         /* done */
 
         MinecraftServer.setCompressionThreshold(0);
diff --git a/src/main/java/net/pivipi/ball/Ball.java b/src/main/java/net/pivipi/ball/Ball.java
index 8f3426b..6f5533a 100644
--- a/src/main/java/net/pivipi/ball/Ball.java
+++ b/src/main/java/net/pivipi/ball/Ball.java
@@ -1,15 +1,20 @@
 package net.pivipi.ball;
 
+import net.minestom.server.coordinate.Pos;
 import net.minestom.server.coordinate.Vec;
 import net.minestom.server.entity.Entity;
 import net.minestom.server.entity.EntityType;
+import net.minestom.server.entity.Player;
 import net.minestom.server.entity.metadata.other.FallingBlockMeta;
+import net.minestom.server.event.player.PlayerEntityInteractEvent;
+import net.minestom.server.instance.Instance;
 import net.minestom.server.instance.block.Block;
 import net.pivipi.physics.Physics;
 import net.pivipi.world.Stadium;
 
 public class Ball extends Entity {
     private long lastTick;
+    private Player holder;
     
     private final Physics physics = new Physics(this);
     public final Stadium stadium;
@@ -28,7 +33,18 @@ public class Ball extends Entity {
     }
     
     public Ball(Stadium stadium) {
-    	this(Block.WHITE_WOOL, stadium);
+    	this(Block.BIRCH_WOOD, stadium);
+    }
+    
+    public void setBlock(Block block) {
+    	this.editEntityMeta(FallingBlockMeta.class, meta -> {
+        	meta.setBlock(block);
+        });
+    	
+    	this.getViewers().forEach(player -> {
+    		this.removeViewer(player);
+    		this.addViewer(player);
+    	});
     }
     
 
@@ -39,7 +55,11 @@ public class Ball extends Entity {
 
         long delay = time - this.lastTick;
 
-        physics.process(delay / 1000.0, stadium.players);
+        if (holder == null) {
+            physics.process(delay / 1000.0, stadium.players);
+        } else {
+        	this.teleport(holder.getPosition().add(holder.getPosition().direction()).add(0, holder.getEyeHeight() - getBoundingBox().height() / 2, 0));
+        }
 
         this.lastTick = time;
     }
@@ -51,5 +71,14 @@ public class Ball extends Entity {
     public void addPos(Vec vec) {
     	this.teleport(this.getPosition().add(vec));
     }
+    
+    public Player getHolder() {
+    	return this.holder;
+    }
+    
+    public void setHolder(Player player) {
+    	if (player != null) physics.setVelocity(Vec.ZERO);
+    	this.holder = player;
+    }
 
 }
diff --git a/src/main/java/net/pivipi/ball/BallKicker.java b/src/main/java/net/pivipi/ball/BallKicker.java
index 592da4d..c9da3c8 100644
--- a/src/main/java/net/pivipi/ball/BallKicker.java
+++ b/src/main/java/net/pivipi/ball/BallKicker.java
@@ -1,16 +1,24 @@
 package net.pivipi.ball;
 
 import javax.print.attribute.standard.MediaSize.Engineering;
+import javax.swing.plaf.basic.BasicInternalFrameTitlePane.IconifyAction;
 
 import net.minestom.server.coordinate.Point;
 import net.minestom.server.coordinate.Pos;
 import net.minestom.server.coordinate.Vec;
+import net.minestom.server.entity.Entity;
 import net.minestom.server.entity.Player;
+import net.minestom.server.entity.Entity.Pose;
 import net.minestom.server.event.GlobalEventHandler;
+import net.minestom.server.event.player.PlayerEntityInteractEvent;
 import net.minestom.server.event.player.PlayerHandAnimationEvent;
 import net.minestom.server.event.player.PlayerMoveEvent;
 import net.minestom.server.event.player.PlayerStartSneakingEvent;
 import net.minestom.server.event.player.PlayerStopSneakingEvent;
+import net.minestom.server.instance.block.Block;
+import net.minestom.server.item.ItemStack;
+import net.minestom.server.network.packet.server.play.BlockActionPacket;
+import net.minestom.server.particle.Particle.Item;
 import net.pivipi.physics.Collision;
 import net.pivipi.physics.CollisionData;
 import net.pivipi.world.Stadium;
@@ -22,8 +30,9 @@ public class BallKicker { // TODO apply physics settings here
 	private int sneakStreak;
 	
 	private double reach = 3;
-	private double verticalReach = 2;
+	private double verticalReach = 2.5;
 	private double maxKickStrength = 10; // if reach is 0, but you'll never hit the max
+	private double shootStrength = 10; // when holding
 	
 	public BallKicker(Stadium stadium) {
 		this.stadium = stadium;
@@ -34,6 +43,7 @@ public class BallKicker { // TODO apply physics settings here
 		globalEventHandler.addListener(PlayerStartSneakingEvent.class, event -> onSneak(event));
 		globalEventHandler.addListener(PlayerStopSneakingEvent.class, event -> onStopSneaking(event));
 		globalEventHandler.addListener(PlayerHandAnimationEvent.class, event -> onSwing(event));
+		globalEventHandler.addListener(PlayerEntityInteractEvent.class, event -> onInteract(event));
 	}
 	
 	private void onStopSneaking(PlayerStopSneakingEvent event) {
@@ -81,8 +91,29 @@ public class BallKicker { // TODO apply physics settings here
 		double distance = collisionData.distance.withY(0).distance(0, 0, 0);
 		
 		if (collisionData.distance.y() < verticalReach && distance < reach) {
-			double percent = 1 - distance / reach;
-			stadium.ball.addVelocity(player.getPosition().direction().withY(y -> y + 1 - collisionData.distance.y()).mul(maxKickStrength * percent));
+			if (stadium.ball.getHolder() != null) {
+				stadium.ball.addVelocity(player.getPosition().direction().mul(shootStrength));
+			} else {
+				double percent = 1 - distance / reach;
+				stadium.ball.addVelocity(player.getPosition().direction().withY(y -> y + 1 - collisionData.distance.y()).mul(maxKickStrength * percent));
+			}
+			stadium.ball.setHolder(null);
+		}
+	}
+	
+	private void onInteract(PlayerEntityInteractEvent event) {
+		Entity entity = event.getTarget();
+		
+		if (entity instanceof Ball) {
+			Ball ball = (Ball) entity;
+			Player player = event.getPlayer();
+			
+			if (player.isSneaking()) {
+				Block block = player.getItemInHand(event.getHand()).material().block();
+				if (block != null) ball.setBlock(block);
+			} else {
+				ball.setHolder(player);
+			}
 		}
 	}
 }
diff --git a/src/main/java/net/pivipi/physics/Physics.java b/src/main/java/net/pivipi/physics/Physics.java
index fd38ea4..2e517e7 100644
--- a/src/main/java/net/pivipi/physics/Physics.java
+++ b/src/main/java/net/pivipi/physics/Physics.java
@@ -23,6 +23,7 @@ public class Physics {
 	private final double jumpStrength = 20;
 	private final double groundFriction = 0.5;
 	private final double airFriction = 0.1;
+	private final int groundY = 64;
 	
 	private final double flame = 20; // flame starts at speed
 	private final double flameFreq = 100; // ms per flame
@@ -32,7 +33,6 @@ public class Physics {
 	private Vec velocity = new Vec(0, 0, 0);
 	
 	private final Entity entity;
-	private Player holder;
 	private int p;
 	
 	public Physics(Entity entity) {
@@ -61,8 +61,8 @@ public class Physics {
 	private Vec applyPhysics(double delta, Set<Player> players) {
 		velocity = velocity.sub(0, gravity * delta, 0).mul(1 - (airFriction * delta), 1, 1 - (airFriction * delta));
 		
-		if (Collision.collidesWithGround(2, entity)) {
-			entity.teleport(entity.getPosition().withY(2));
+		if (Collision.collidesWithGround(groundY, entity)) {
+			entity.teleport(entity.getPosition().withY(groundY));
 			velocity = velocity.mul(1 - (groundFriction * delta), -blockBounciness, 1 - (groundFriction * delta));
 		} else {
 			for (Player player : players) {
@@ -118,6 +118,9 @@ public class Physics {
 		}
 	}
 
+	public void setVelocity(Vec velocity) {
+		this.velocity = velocity;
+	}
 	
 	public void addVelocity(Vec velocity) {
 		this.velocity = this.velocity.add(velocity);
diff --git a/src/main/java/net/pivipi/world/FancyDimension.java b/src/main/java/net/pivipi/world/FancyDimension.java
index 0fd54d9..e6e3cdb 100644
--- a/src/main/java/net/pivipi/world/FancyDimension.java
+++ b/src/main/java/net/pivipi/world/FancyDimension.java
@@ -9,8 +9,7 @@ public class FancyDimension {
 	public static Key<DimensionType> create() {
 		DimensionType dimension = DimensionType.builder()
 				.ambientLight(1.0f)
-				.fixedTime(18000l)
-				.effects("minecraft:the_end")
+				.fixedTime(1000l)
 				.build();
 		
 		return MinecraftServer.getDimensionTypeRegistry().register(NamespaceID.from("fancy_dimension"), dimension);
diff --git a/src/main/java/net/pivipi/world/SoccerGenerator.java b/src/main/java/net/pivipi/world/SoccerGenerator.java
index 1103c03..d751a9a 100644
--- a/src/main/java/net/pivipi/world/SoccerGenerator.java
+++ b/src/main/java/net/pivipi/world/SoccerGenerator.java
@@ -14,10 +14,10 @@ public class SoccerGenerator implements Generator {
     public void generate(@NotNull GenerationUnit unit) {
         UnitModifier modifier = unit.modifier();
 
-        modifier.fillBiome(Biome.SNOWY_PLAINS);
+        modifier.fillBiome(Biome.CRIMSON_FOREST);
         
-        modifier.fillHeight(1, 2, Block.COARSE_DIRT);
-        modifier.fill(unit.absoluteStart().withY(1).add(1, 0, 1), unit.absoluteEnd().withY(2), Block.GRASS_BLOCK);
+        modifier.fillHeight(63, 64, Block.WHITE_WOOL);
+        modifier.fill(unit.absoluteStart().withY(63).add(1, 0, 1), unit.absoluteEnd().withY(64), Block.GREEN_CONCRETE_POWDER);
     }
     
 }