diff --git a/Events.md b/Events.md
new file mode 100644
index 0000000..c9c73ad
--- /dev/null
+++ b/Events.md
@@ -0,0 +1,138 @@
+# KillQuestPlugin Custom Events
+
+The `KillQuestPlugin` provides several custom events that other plugins can listen to and handle. These events are dispatched at various points during the execution of quests and jumping puzzles.
+
+## Events Overview
+
+### JumpPuzzleStartEvent
+
+- **Description**: This event is triggered when a player starts a jumping puzzle.
+- **Class**: `com.digitalwm.killquest.events.JumpPuzzleStartEvent`
+- **Methods**:
+ - `Player getPlayer()`: Returns the player who started the puzzle.
+ - `String getPuzzleName()`: Returns the name of the puzzle.
+- **Usage**:
+ ```java
+ @EventHandler
+ public void onJumpPuzzleStart(JumpPuzzleStartEvent event) {
+ Player player = event.getPlayer();
+ String puzzleName = event.getPuzzleName();
+ // Handle the event
+ }
+ ```
+
+### JumpPuzzleEndEvent
+
+- **Description**: This event is triggered when a player completes a jumping puzzle.
+- **Class**: `com.digitalwm.killquest.events.JumpPuzzleEndEvent`
+- **Methods**:
+ - `Player getPlayer()`: Returns the player who completed the puzzle.
+ - `String getPuzzleName()`: Returns the name of the puzzle.
+- **Usage**:
+ ```java
+ @EventHandler
+ public void onJumpPuzzleEnd(JumpPuzzleEndEvent event) {
+ Player player = event.getPlayer();
+ String puzzleName = event.getPuzzleName();
+ // Handle the event
+ }
+ ```
+
+### JumpPuzzleTimeoutEvent
+
+- **Description**: This event is triggered when the timer for a jumping puzzle expires.
+- **Class**: `com.digitalwm.killquest.events.JumpPuzzleTimeoutEvent`
+- **Methods**:
+ - `Player getPlayer()`: Returns the player whose puzzle timed out.
+ - `String getPuzzleName()`: Returns the name of the puzzle.
+- **Usage**:
+ ```java
+ @EventHandler
+ public void onJumpPuzzleTimeout(JumpPuzzleTimeoutEvent event) {
+ Player player = event.getPlayer();
+ String puzzleName = event.getPuzzleName();
+ // Handle the event
+ }
+ ```
+
+### QuestStartEvent
+
+- **Description**: This event is triggered when a player starts a quest.
+- **Class**: `com.digitalwm.killquest.events.QuestStartEvent`
+- **Methods**:
+ - `Player getPlayer()`: Returns the player who started the quest.
+ - `String getQuestName()`: Returns the name of the quest.
+- **Usage**:
+ ```java
+ @EventHandler
+ public void onQuestStart(QuestStartEvent event) {
+ Player player = event.getPlayer();
+ String questName = event.getQuestName();
+ // Handle the event
+ }
+ ```
+
+### QuestEndEvent
+
+- **Description**: This event is triggered when a player completes a quest.
+- **Class**: `com.digitalwm.killquest.events.QuestEndEvent`
+- **Methods**:
+ - `Player getPlayer()`: Returns the player who completed the quest.
+ - `String getQuestName()`: Returns the name of the quest.
+- **Usage**:
+ ```java
+ @EventHandler
+ public void onQuestEnd(QuestEndEvent event) {
+ Player player = event.getPlayer();
+ String questName = event.getQuestName();
+ // Handle the event
+ }
+ ```
+
+## Registering Event Listeners
+
+To listen for these events, you need to register an event listener in your plugin. Here is an example of how to do this:
+
+```java
+import cn.nukkit.plugin.PluginBase;
+import cn.nukkit.event.Listener;
+import cn.nukkit.event.EventHandler;
+import com.digitalwm.killquest.events.JumpPuzzleStartEvent;
+import com.digitalwm.killquest.events.JumpPuzzleEndEvent;
+import com.digitalwm.killquest.events.JumpPuzzleTimeoutEvent;
+import com.digitalwm.killquest.events.QuestStartEvent;
+import com.digitalwm.killquest.events.QuestEndEvent;
+
+public class YourPlugin extends PluginBase implements Listener {
+
+ @Override
+ public void onEnable() {
+ getServer().getPluginManager().registerEvents(this, this);
+ }
+
+ @EventHandler
+ public void onJumpPuzzleStart(JumpPuzzleStartEvent event) {
+ // Handle the jump puzzle start event
+ }
+
+ @EventHandler
+ public void onJumpPuzzleEnd(JumpPuzzleEndEvent event) {
+ // Handle the jump puzzle end event
+ }
+
+ @EventHandler
+ public void onJumpPuzzleTimeout(JumpPuzzleTimeoutEvent event) {
+ // Handle the jump puzzle timeout event
+ }
+
+ @EventHandler
+ public void onQuestStart(QuestStartEvent event) {
+ // Handle the quest start event
+ }
+
+ @EventHandler
+ public void onQuestEnd(QuestEndEvent event) {
+ // Handle the quest end event
+ }
+}
+```
\ No newline at end of file
diff --git a/README.md b/README.md
index 98590db..d2eb5db 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,18 @@
---
-## Changes to 1.0.1
+## Changes in 1.0.2
+- Added regenaration of puzzle when a user finishes it
+- Added regeneration of puzzle, using a reset block. You must stay at least 5 seconds on it
+- Added 2 Doors around the start block so the players can enter and exit the puzzle
+- Added 5 Events to be triggered from within the plugin
+ - JumpPuzzleEndEvent
+ - JumpPuzzleStartEvent
+ - JumpPuzzleTimeoutEvent
+ - QuestEndEvent
+ - QuestStartEvent
+
+## Changes in 1.0.1
- Added Handling of onPlayerFish event so fishing quests can be created
- Added complete new loging of generating jumping puzzles
@@ -26,17 +37,19 @@
---
## **π Features**
-β **Quest System:** Kill entities and gather items to complete quests.
-β **Dynamic Quest Selection:** Players can select quests using a UI (`/quests`).
-β **Scoreboard Tracking:** Displays active quest progress in the top-right.
-β **Auto-Saving:** Quest progress is saved to files per player.
-β **EconomyAPI Integration:** Players earn credits upon completion.
-β **Multilingual Support:** Uses Minecraftβs translations for entity/item names.
-β **Jumping Puzzles:** Procedurally generate jumping puzzles with varying heights and difficulties.
-β **Puzzle Persistence:** Puzzles are saved and can be reloaded after server restarts.
-β **Player Movement Tracking:** Detect when players start and complete puzzles.
-β **Block Restrictions:** Prevent players from modifying puzzle areas.
-β **Puzzle Management Commands:** Create, list, and remove puzzles dynamically.
+- **Quest System:** Kill entities and gather items to complete quests.
+- **Dynamic Quest Selection:** Players can select quests using a UI (`/quests`).
+- **Scoreboard Tracking:** Displays active quest progress in the top-right.
+- **Auto-Saving:** Quest progress is saved to files per player.
+- **EconomyAPI Integration:** Players earn credits upon completion.
+- **Multilingual Support:** Uses Minecraftβs translations for entity/item names.
+- **Jumping Puzzles:** Procedurally generate jumping puzzles with varying heights and difficulties.
+- **Puzzle Persistence:** Puzzles are saved and can be reloaded after server restarts.
+- **Player Movement Tracking:** Detect when players start and complete puzzles.
+- **Block Restrictions:** Prevent players from modifying puzzle areas.
+- **Puzzle Management Commands:** Create, list, and remove puzzles dynamically.
+- **Puzzle Regen Logic:** Regenerate the given puzzle, when the user completes it or using reset block.
+- **Server Events:** The plugin sends events when changes are on Quests and Jumping Puzzles.
---
@@ -65,6 +78,14 @@
3. Players must jump across blocks that are generated to be challenging but solvable.
4. A tracking system monitors when a player starts and completes the puzzle.
5. Upon completion, the player receives 100 credits via EconomyAPI.
+6. Once completed, the user is teleported to the center and the puzzle regenerates
+7. If puzzle is imposible, use the green block to regenerate it. Stay on it more than 5 seconds
+
+---
+
+## **For coders**
+
+For more information about the custom events provided by this plugin, see the [Events Documentation](Events.md).
---
@@ -134,7 +155,7 @@ translations:
[INFO ] [KillQuestPlugin] βββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββ
[INFO ] [KillQuestPlugin] βββ ββββββββββββββββββββββ βββββββ βββββββ ββββββββββββββββ βββ
[INFO ] [KillQuestPlugin]
- [INFO ] [KillQuestPlugin] Version: 1.0.0
+ [INFO ] [KillQuestPlugin] Version: 1.0.2
[INFO ] [KillQuestPlugin] Developed by digitalwm
[INFO ] [KillQuestPlugin]
[INFO ] [KillQuestPlugin] Loaded language: en_US with 41 keys.
@@ -143,12 +164,14 @@ translations:
[INFO ] [KillQuestPlugin] Total translation keys loaded: 82
[INFO ] [KillQuestPlugin] KillQuestPlugin enabled with 23 available quests.
[INFO ] [KillQuestPlugin] EconomyAPI found. Rewards enabled.
+ [INFO ] [KillQuestPlugin] Loading saved puzzles...
+ [INFO ] [KillQuestPlugin] Loaded puzzle: test
```
---
## **π‘ Future Improvements**
-- β
**More Quest Types:** Crafting
+- β
**More Quest Types:** Crafting, Shooting
- β
**Permissions Support**
- β
**More Customization Options**
- β
**SQL Database support**
diff --git a/pom.xml b/pom.xml
index 7e69fe2..53d0503 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
com.digitalwm.killquestplugin
KillQuestPlugin
- 1.0.1
+ 1.0.2
package
diff --git a/src/main/java/com/digitalwm/killquest/JumpPuzzleGenerator.java b/src/main/java/com/digitalwm/killquest/JumpPuzzleGenerator.java
index 434c001..316ac3b 100644
--- a/src/main/java/com/digitalwm/killquest/JumpPuzzleGenerator.java
+++ b/src/main/java/com/digitalwm/killquest/JumpPuzzleGenerator.java
@@ -2,9 +2,11 @@
import cn.nukkit.Player;
import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockDoor;
import cn.nukkit.level.Level;
import cn.nukkit.math.Vector3;
import cn.nukkit.event.player.PlayerMoveEvent;
+import cn.nukkit.block.BlockDoorWood;
import me.onebone.economyapi.EconomyAPI;
import java.util.HashMap;
import java.util.Map;
@@ -26,6 +28,7 @@ public class JumpPuzzleGenerator {
private Vector3 endBlock;
private final Map playerStartTimes = new HashMap<>();
+ private final Map playerGreenBlockTimes = new HashMap<>();
// List to track all blocks generated in the puzzle
@@ -177,6 +180,42 @@ private void generatePuzzle() {
level.setBlock(startBlock, Block.get(Block.GOLD_BLOCK));
trackBlock(startBlock, "START"); // β
Track start block
+ // β
Create wooden doors
+ BlockDoorWood doorBottom1 = new BlockDoorWood();
+ BlockDoorWood doorTop1 = new BlockDoorWood();
+ doorTop1.setDamage(8);
+
+ BlockDoorWood doorBottom2 = new BlockDoorWood();
+ BlockDoorWood doorTop2 = new BlockDoorWood();
+ doorTop2.setDamage(8); // β
Set as upper part of the door
+
+ // Door base positions (1 block above start block, placed at the corner)
+ Vector3 doorBase1 = new Vector3(startBlock.x - 1, startBlock.y + 1, startBlock.z);
+ Vector3 doorBase2 = new Vector3(startBlock.x, startBlock.y + 1, startBlock.z - 1);
+
+ // Door top positions (1 block above door bases)
+ Vector3 doorTop1Pos = new Vector3(doorBase1.x, doorBase1.y + 1, doorBase1.z);
+ Vector3 doorTop2Pos = new Vector3(doorBase2.x, doorBase2.y + 1, doorBase2.z);
+
+ // β
Place bottom and top door parts
+ level.setBlock(doorBase1, doorBottom1);
+ level.setBlock(doorTop1Pos, doorTop1);
+
+ level.setBlock(doorBase2, doorBottom2);
+ level.setBlock(doorTop2Pos, doorTop2);
+
+ // β
Track doors for removal
+ trackBlock(doorBase1, "DOOR_BOTTOM");
+ trackBlock(doorTop1Pos, "DOOR_TOP");
+
+ trackBlock(doorBase2, "DOOR_BOTTOM");
+ trackBlock(doorTop2Pos, "DOOR_TOP");
+
+ // β
Add a single green block diagonally opposite to the start block on the same height plane
+ Vector3 greenBlock = new Vector3(puzzleMax.x - 1, startBlock.y, puzzleMax.z - 1);
+ level.setBlock(greenBlock, Block.get(Block.EMERALD_BLOCK));
+ trackBlock(greenBlock, "GREEN"); // β
Track green block
+
int currentHeight = 0;
int blocksAtCurrentHeight = 0;
@@ -276,13 +315,31 @@ public void handlePlayerMovement(PlayerMoveEvent event) {
if (pos.equals(startBlock) && !playerStartTimes.containsKey(player)) {
player.sendMessage("Β§eYou started the jump puzzle! Reach the end within 15 minutes!");
+ plugin.onJumpPuzzleStart(player, puzzleName); // Trigger start event
playerStartTimes.put(player, System.currentTimeMillis());
}
+ // Check if the player is on the green block
+ if (puzzleBlocks.containsKey(pos) && "GREEN".equals(puzzleBlocks.get(pos))) {
+ long currentTime = System.currentTimeMillis();
+ if (!playerGreenBlockTimes.containsKey(player)) {
+ playerGreenBlockTimes.put(player, currentTime);
+ } else {
+ long timeOnGreenBlock = currentTime - playerGreenBlockTimes.get(player);
+ if (timeOnGreenBlock > 5000) { // 5 seconds
+ player.sendMessage("Β§cYou stayed on the green block for too long! The puzzle has been reset.");
+ resetPuzzleForPlayer(player);
+ }
+ }
+ } else {
+ playerGreenBlockTimes.remove(player);
+ }
+
if (playerStartTimes.containsKey(player)) {
long startTime = playerStartTimes.get(player);
if (System.currentTimeMillis() - startTime > 15 * 60 * 1000) {
player.sendMessage("Β§cYou ran out of time for the jump puzzle!");
+ plugin.onJumpPuzzleTimeout(player, puzzleName); // Trigger timeout event
playerStartTimes.remove(player);
return;
}
@@ -290,7 +347,9 @@ public void handlePlayerMovement(PlayerMoveEvent event) {
if (pos.equals(endBlock)) {
player.sendMessage("Β§aCongratulations! You completed the jump puzzle!");
EconomyAPI.getInstance().addMoney(player, 100);
+ plugin.onJumpPuzzleEnd(player, puzzleName); // Trigger end event
playerStartTimes.remove(player);
+ resetPuzzleForPlayer(player);
}
}
}
@@ -412,4 +471,18 @@ public void setPuzzleBlocks(Map newBlocks) {
this.puzzleBlocks.clear();
this.puzzleBlocks.putAll(newBlocks);
}
+
+ private void resetPuzzleForPlayer(Player player) {
+ // Teleport the player to the center of the puzzle
+ Vector3 centerBlock = new Vector3(
+ startPos.x,
+ startPos.y,
+ startPos.z
+ );
+ player.teleport(centerBlock);
+
+ // Regenerate the puzzle
+ removePuzzle();
+ generate();
+ }
}
diff --git a/src/main/java/com/digitalwm/killquest/JumpPuzzleListener.java b/src/main/java/com/digitalwm/killquest/JumpPuzzleListener.java
index 4fb47fe..dbe8f67 100644
--- a/src/main/java/com/digitalwm/killquest/JumpPuzzleListener.java
+++ b/src/main/java/com/digitalwm/killquest/JumpPuzzleListener.java
@@ -2,9 +2,11 @@
import cn.nukkit.Player;
import cn.nukkit.event.EventHandler;
+import cn.nukkit.block.BlockDoor;
import cn.nukkit.event.Listener;
import cn.nukkit.math.Vector3;
import cn.nukkit.event.block.BlockBreakEvent;
+import cn.nukkit.event.player.PlayerInteractEvent;
import cn.nukkit.event.block.BlockPlaceEvent;
import cn.nukkit.event.player.PlayerMoveEvent;
@@ -16,6 +18,13 @@ public JumpPuzzleListener(KillQuestPlugin plugin) {
this.plugin = plugin;
}
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (event.getBlock() instanceof BlockDoor) {
+ // plugin.getLogger().info(event.getPlayer().getName() + " interacted with a door at " + event.getBlock().getLocation());
+ }
+ }
+
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
diff --git a/src/main/java/com/digitalwm/killquest/KillQuestPlugin.java b/src/main/java/com/digitalwm/killquest/KillQuestPlugin.java
index 04ad006..94ca9d2 100644
--- a/src/main/java/com/digitalwm/killquest/KillQuestPlugin.java
+++ b/src/main/java/com/digitalwm/killquest/KillQuestPlugin.java
@@ -47,6 +47,14 @@
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
+// Own Events
+
+import com.digitalwm.killquest.events.JumpPuzzleStartEvent;
+import com.digitalwm.killquest.events.JumpPuzzleEndEvent;
+import com.digitalwm.killquest.events.JumpPuzzleTimeoutEvent;
+import com.digitalwm.killquest.events.QuestStartEvent;
+import com.digitalwm.killquest.events.QuestEndEvent;
+
public class KillQuestPlugin extends PluginBase implements Listener, CommandExecutor {
// List of all available quests (loaded from quests.yml)
@@ -141,6 +149,36 @@ public void run() {
loadJumpPuzzles(); // β
Load puzzles AFTER ensuring file exists
}
+ public void onJumpPuzzleStart(Player player, String puzzleName) {
+ JumpPuzzleStartEvent event = new JumpPuzzleStartEvent(player, puzzleName);
+ getServer().getInstance().getPluginManager().callEvent(event);
+ getLogger().info("Jump puzzle started by " + player.getName() + " for puzzle: " + puzzleName);
+ }
+
+ public void onJumpPuzzleEnd(Player player, String puzzleName) {
+ JumpPuzzleEndEvent event = new JumpPuzzleEndEvent(player, puzzleName);
+ getServer().getInstance().getPluginManager().callEvent(event);
+ getLogger().info("Jump puzzle ended by " + player.getName() + " for puzzle: " + puzzleName);
+ }
+
+ public void onJumpPuzzleTimeout(Player player, String puzzleName) {
+ JumpPuzzleTimeoutEvent event = new JumpPuzzleTimeoutEvent(player, puzzleName);
+ getServer().getInstance().getPluginManager().callEvent(event);
+ getLogger().info("Jump puzzle timed out for player: " + player.getName() + " for puzzle: " + puzzleName);
+ }
+
+ public void onQuestStart(Player player, String questName) {
+ QuestStartEvent event = new QuestStartEvent(player, questName);
+ getServer().getInstance().getPluginManager().callEvent(event);
+ getLogger().info("Quest started by " + player.getName() + ": " + questName);
+ }
+
+ public void onQuestEnd(Player player, String questName) {
+ QuestEndEvent event = new QuestEndEvent(player, questName);
+ getServer().getInstance().getPluginManager().callEvent(event);
+ getLogger().info("Quest ended by " + player.getName() + ": " + questName);
+ }
+
public Map getActiveJumpPuzzles() {
return activeJumpPuzzles;
}
@@ -463,6 +501,10 @@ private void updateQuestProgressForPlayer(Player player) {
player.sendMessage("Β§aQuest complete: " + quest.getName() +
"Β§r! You've earned Β§e" + quest.getReward() + " coinsΒ§r.");
getLogger().debug("Active quest '" + quest.getName() + "' completed for player " + playerName);
+
+ // Trigger Quest End Event
+ onQuestEnd(player, quest.getName());
+
activeQuests.remove(playerName);
clearActiveQuestProgress(playerName);
} else {
@@ -695,6 +737,9 @@ public void onPlayerFormResponse(PlayerFormRespondedEvent event) {
saveActiveQuestProgress(player.getName());
player.sendMessage("Β§aActive quest set to: " + selectedQuest.getName());
+ // Trigger Quest Start Event
+ onQuestStart(player, selectedQuest.getName());
+
// β
**Update the Scoreboard Immediately**
if (hasActiveQuest) {
destroyScoreboard(player); // Remove old scoreboard
diff --git a/src/main/java/com/digitalwm/killquest/events/JumpPuzzleEndEvent.java b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleEndEvent.java
new file mode 100644
index 0000000..3e43ea2
--- /dev/null
+++ b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleEndEvent.java
@@ -0,0 +1,28 @@
+package com.digitalwm.killquest.events;
+import cn.nukkit.event.Event;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.Player;
+
+// Event for when a user finishes a jumping puzzle
+public class JumpPuzzleEndEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final Player player;
+ private final String puzzleName;
+
+ public JumpPuzzleEndEvent(Player player, String puzzleName) {
+ this.player = player;
+ this.puzzleName = puzzleName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public String getPuzzleName() {
+ return puzzleName;
+ }
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/digitalwm/killquest/events/JumpPuzzleStartEvent.java b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleStartEvent.java
new file mode 100644
index 0000000..eee66f4
--- /dev/null
+++ b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleStartEvent.java
@@ -0,0 +1,28 @@
+package com.digitalwm.killquest.events;
+import cn.nukkit.event.Event;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.Player;
+
+// Event for when a user starts a jumping puzzle
+public class JumpPuzzleStartEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final Player player;
+ private final String puzzleName;
+
+ public JumpPuzzleStartEvent(Player player, String puzzleName) {
+ this.player = player;
+ this.puzzleName = puzzleName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public String getPuzzleName() {
+ return puzzleName;
+ }
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/digitalwm/killquest/events/JumpPuzzleTimeoutEvent.java b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleTimeoutEvent.java
new file mode 100644
index 0000000..cd8eeb0
--- /dev/null
+++ b/src/main/java/com/digitalwm/killquest/events/JumpPuzzleTimeoutEvent.java
@@ -0,0 +1,28 @@
+package com.digitalwm.killquest.events;
+import cn.nukkit.event.Event;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.Player;
+
+// Event for when the jumping puzzle timer expires
+public class JumpPuzzleTimeoutEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final Player player;
+ private final String puzzleName;
+
+ public JumpPuzzleTimeoutEvent(Player player, String puzzleName) {
+ this.player = player;
+ this.puzzleName = puzzleName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public String getPuzzleName() {
+ return puzzleName;
+ }
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/com/digitalwm/killquest/events/QuestEndEvent.java b/src/main/java/com/digitalwm/killquest/events/QuestEndEvent.java
new file mode 100644
index 0000000..a48b1bb
--- /dev/null
+++ b/src/main/java/com/digitalwm/killquest/events/QuestEndEvent.java
@@ -0,0 +1,28 @@
+package com.digitalwm.killquest.events;
+import cn.nukkit.event.Event;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.Player;
+
+// Event for when a user finishes a quest
+public class QuestEndEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final Player player;
+ private final String questName;
+
+ public QuestEndEvent(Player player, String questName) {
+ this.player = player;
+ this.questName = questName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public String getQuestName() {
+ return questName;
+ }
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/digitalwm/killquest/events/QuestStartEvent.java b/src/main/java/com/digitalwm/killquest/events/QuestStartEvent.java
new file mode 100644
index 0000000..e73b70d
--- /dev/null
+++ b/src/main/java/com/digitalwm/killquest/events/QuestStartEvent.java
@@ -0,0 +1,28 @@
+package com.digitalwm.killquest.events;
+import cn.nukkit.event.Event;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.Player;
+
+// Event for when a user starts a quest
+public class QuestStartEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private final Player player;
+ private final String questName;
+
+ public QuestStartEvent(Player player, String questName) {
+ this.player = player;
+ this.questName = questName;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public String getQuestName() {
+ return questName;
+ }
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 94961f8..dedf5d1 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,6 @@
name: KillQuestPlugin
-version: 1.0.1
+version: 1.0.2
+author: digitalwm
main: com.digitalwm.killquest.KillQuestPlugin
api: [1.1.0]
commands: