diff --git a/.gitignore b/.gitignore
index 7555dcb..f5cebb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,4 @@ runClient.launch
runData.launch
runServer.launch
-src/generated
\ No newline at end of file
+src/generated
diff --git a/build.gradle b/build.gradle
index a413144..4b2e1b9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,11 +4,13 @@ buildscript {
// These repositories are only for Gradle plugins, put any other repositories in the repository block further below
maven { url = 'https://maven.minecraftforge.net' }
maven { url = 'https://maven.parchmentmc.org' }
+ maven { url = 'https://plugins.gradle.org/m2/' }
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
classpath 'org.parchmentmc:librarian:1.+'
+ classpath 'com.adarshr:gradle-test-logger-plugin:3.2.0'
}
}
apply plugin: 'net.minecraftforge.gradle'
@@ -18,6 +20,7 @@ apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'java'
apply plugin: 'checkstyle'
+apply plugin: 'com.adarshr.test-logger'
version = '1.18-0.1.1'
group = 'com.ocelotslovebirds.birdhaus' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 3119a68..b64ee5b 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -391,12 +391,6 @@
-
-
-
-
-
-
diff --git a/src/main/java/com/ocelotslovebirds/birdhaus/HelloWorld.java b/src/main/java/com/ocelotslovebirds/birdhaus/HelloWorld.java
deleted file mode 100644
index f6f58f4..0000000
--- a/src/main/java/com/ocelotslovebirds/birdhaus/HelloWorld.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.ocelotslovebirds.birdhaus;
-
-public class HelloWorld {
- public static int getFourOneTwo() {
- return 412;
- }
-}
diff --git a/src/main/java/com/ocelotslovebirds/birdhaus/blocks/BirdhouseBlockEntity.java b/src/main/java/com/ocelotslovebirds/birdhaus/blocks/BirdhouseBlockEntity.java
index 96ff1a4..028aa5b 100644
--- a/src/main/java/com/ocelotslovebirds/birdhaus/blocks/BirdhouseBlockEntity.java
+++ b/src/main/java/com/ocelotslovebirds/birdhaus/blocks/BirdhouseBlockEntity.java
@@ -1,10 +1,17 @@
package com.ocelotslovebirds.birdhaus.blocks;
+import java.util.concurrent.ThreadLocalRandom;
+
import com.ocelotslovebirds.birdhaus.setup.Registration;
+import com.ocelotslovebirds.birdhaus.ticker.FixedIntervalTicker;
+import com.ocelotslovebirds.birdhaus.ticker.Ticker;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.animal.Parrot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -26,7 +33,11 @@ public class BirdhouseBlockEntity extends BlockEntity {
private final ItemStackHandler itemHandler = createHandler();
private final LazyOptional handler = LazyOptional.of(() -> itemHandler);
- private int counter;
+ private Ticker tickerForBirdSpawns = new FixedIntervalTicker(150);
+ private Ticker tickerForSeedConsumption = new FixedIntervalTicker(100);
+
+ // The block is active if it able to consume seeds
+ private Boolean isActive = false;
/**
* @param pos Position of the block.
@@ -59,8 +70,6 @@ public void load(CompoundTag tag) {
}
- // TODO: Hook in bird spawning into the Entity ticker.
-
/**
* This is the main loop for the birdhouse. It needs to be improved to allow for the spawning of birds however at
* the moment it works well for
@@ -70,22 +79,62 @@ public void load(CompoundTag tag) {
*/
public void tickServer() {
- if (counter > 0) {
- counter--;
- setChanged();
+ handleSeedsForTick();
+ handleBirdSpawnForTick();
+ }
+
+ /*
+ * @param xOffset x offset (East-West axis) at which to spawn the bird
+ * @param yOffset y offset (Up-Down axis) at which to spawn the bird
+ * @param yOffset z offset (North-South axis) at which to spawn the bird
+ * All offsets are relative to the birdhouse
+ */
+ private void spawnNewBird(int xOffset, int yOffset, int zOffset) {
+ // Dirty type casting because it works
+ ServerLevel lvl = (ServerLevel) this.getLevel();
+ Parrot newBird = new Parrot(EntityType.PARROT, lvl);
+ lvl.addFreshEntity(newBird);
+ BlockPos desBlockPos = this.getBlockPos().offset(xOffset, yOffset, zOffset);
+
+ // Move the spawned bird to the destination
+ // 0.0 because it works, not sure what this supposed to be
+ newBird.moveTo(desBlockPos, (float) 0.0, (float) 0.0);
+ }
+
+ private void handleBirdSpawnForTick() {
+ if (tickerForBirdSpawns.tick()) {
+ // Random x offset
+ int xOffset = ThreadLocalRandom.current().nextInt(-20, 20);
+ // Spawn bird 10 units higher than the birdhouse
+ int yOffset = this.getBlockPos().getY() + 10;
+ // Random z offset
+ int zOffset = ThreadLocalRandom.current().nextInt(-20, 20);
+ spawnNewBird(xOffset, yOffset, zOffset);
}
- if (counter <= 0) {
+ }
+
+ private void handleSeedsForTick() {
+ if (isActive) {
+ // If the birdhouse is active, try consuming a seed
if (!itemHandler.extractItem(0, 1, false).isEmpty()) {
- counter = 100;
- setChanged();
+ // If a seed was successfully consumed, set birdhouse to inactive
+ isActive = false;
+ }
+ } else {
+ // If birdhouse is inactive, start ticking to eventually reactivate it
+ if (tickerForSeedConsumption.tick()) {
+ isActive = true;
}
}
- // When adding seeds, if the seeds are "burnable" then set the block to active.
+ // Update the block state if there was a change
BlockState blockState = getBlockState();
- if (blockState.getValue(BlockStateProperties.CONDITIONAL) != counter > 0) {
- level.setBlock(worldPosition, blockState.setValue(BlockStateProperties.CONDITIONAL, counter > 0),
- Block.UPDATE_ALL);
+ if (blockState.getValue(BlockStateProperties.CONDITIONAL) != isActive) {
+ level.setBlock(
+ worldPosition,
+ blockState.setValue(BlockStateProperties.CONDITIONAL, isActive),
+ Block.UPDATE_ALL
+ );
}
}
diff --git a/src/main/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTicker.java b/src/main/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTicker.java
new file mode 100644
index 0000000..e4dde26
--- /dev/null
+++ b/src/main/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTicker.java
@@ -0,0 +1,25 @@
+package com.ocelotslovebirds.birdhaus.ticker;
+
+public class FixedIntervalTicker implements Ticker {
+ private final int interval;
+ private int counter;
+
+ /**
+ * @param interval How often the ticker should tick
+ */
+ public FixedIntervalTicker(int interval) {
+ this.interval = interval;
+ this.counter = 0;
+ }
+
+ public boolean tick() {
+ this.counter++;
+
+ if (this.counter == this.interval) {
+ this.counter = 0;
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/com/ocelotslovebirds/birdhaus/ticker/Ticker.java b/src/main/java/com/ocelotslovebirds/birdhaus/ticker/Ticker.java
new file mode 100644
index 0000000..1dfea25
--- /dev/null
+++ b/src/main/java/com/ocelotslovebirds/birdhaus/ticker/Ticker.java
@@ -0,0 +1,11 @@
+package com.ocelotslovebirds.birdhaus.ticker;
+
+// A ticker class helps keep track of when events should happen
+public interface Ticker {
+ /*
+ This function should be called for every tick that passes. It returns
+ true when a particular tick matches the ticker's pattern. Patterns can
+ be things like every 10 ticks or every other tick.
+ */
+ public boolean tick();
+}
diff --git a/src/test/java/com/ocelotslovebirds/birdhaus/HelloWorldTest.java b/src/test/java/com/ocelotslovebirds/birdhaus/HelloWorldTest.java
deleted file mode 100644
index 9116f63..0000000
--- a/src/test/java/com/ocelotslovebirds/birdhaus/HelloWorldTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ocelotslovebirds.birdhaus;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.junit.jupiter.api.Test;
-
-
-public class HelloWorldTest {
- @Test
- public void testGetFourOneTwo() {
- assertEquals(412, HelloWorld.getFourOneTwo());
- }
-}
diff --git a/src/test/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTickerTest.java b/src/test/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTickerTest.java
new file mode 100644
index 0000000..c062ed9
--- /dev/null
+++ b/src/test/java/com/ocelotslovebirds/birdhaus/ticker/FixedIntervalTickerTest.java
@@ -0,0 +1,55 @@
+package com.ocelotslovebirds.birdhaus.ticker;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+
+public class FixedIntervalTickerTest {
+ @Test
+ public void alwaysTicks() {
+ Ticker ticker = new FixedIntervalTicker(1);
+
+ // We assume that if it works 10 times in a row,
+ // it will continue to always work
+ for (int i = 0; i < 10; i++) {
+ assertTrue(ticker.tick());
+ }
+ }
+
+ @Test
+ public void ticksEveryOtherTime() {
+ Ticker ticker = new FixedIntervalTicker(2);
+
+ // We assume that if it works 5 times in a row,
+ // it will continue to always work
+ for (int i = 0; i < 5; i++) {
+ assertFalse(ticker.tick());
+ assertTrue(ticker.tick());
+ }
+ }
+
+ @Test
+ public void ticksEveryTenTicks() {
+ Ticker ticker = new FixedIntervalTicker(10);
+
+ // We assume that if it works 5 times in a row,
+ // it will continue to always work
+ for (int i = 0; i < 5; i++) {
+ // Returns false 9 times
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+ assertFalse(ticker.tick());
+
+ // Returns true once
+ assertTrue(ticker.tick());
+ }
+ }
+}