Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

> Follow the signal, find the source, and uncover loot in TF-Minecraft.

Geiger Counters turns exploration into a treasure hunt. Each character has their own hidden radioactive source a few hundred blocks away. A signal bar, particle rings and clicking lead them to it. Reaching the source awards loot and drains the counter, and the next counter starts a new hunt near wherever the character is.
Geiger Counters turns exploration into a treasure hunt. Each character has their own cache buried a few hundred blocks away. A signal bar, particle rings and clicking lead them to it, and a close reading shows where to dig. Opening the cache gives loot and drains the counter, and the next counter starts a new hunt near wherever the character is.

## Features

- **A source per character** — each character's source is placed near them and kept until they find it.
- **Signal bar** — a boss bar fills as the player closes in and peaks when they face the source.
- **A source per character** — each character's cache is buried near them and kept until they dig it up.
- **Buried caches** — the cache is a chest only its hunter sees, and only while holding a live detector.
- **Signal bar** — a boss bar fills as the player closes in and peaks when they face the source; close by it shows where to dig.
- **Visual tracking** — particle rings change in color and number as the player approaches the source.
- **Audible feedback** — irregular counter clicks become more frequent at closer distances.
- **Tiered discoveries** — weighted reward tiers give each successful hunt a chance of different loot.
- **Consumable counters** — a successful collection replaces the active counter with a dead one.
- **Consumable counters** — opening the cache replaces the active counter with a dead one.
- **Collection limits** — each account may collect a set number of sources per time window.

Originally created by [Justinas Launikonis](https://github.com/JustinasLa).
Expand All @@ -29,8 +30,8 @@ Tests use JUnit 5, Mockito, and MockBukkit. Surefire test results are in
`target/surefire-reports/`; JaCoCo HTML and XML reports are in `target/site/jacoco/`.
The Build workflow uploads both. Verification requires 100% line, branch, and instruction
coverage of production code, with no coverage exclusions.
Client sounds and particles, live world generation, and installed item and region
plugins require separate in-game checks.
Client sounds and particles, the client-side chest, live world generation, and
installed item and region plugins require separate in-game checks.

## License

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ private void handleLocate(CommandSender sender, String[] args) {

sender.sendMessage(messages().get("admin.source-located",
"%player%", target.getName(),
"%x%", Messages.coordinate(source.getX()),
"%z%", Messages.coordinate(source.getZ()),
"%x%", source.getBlockX(),
"%y%", source.getBlockY(),
"%z%", source.getBlockZ(),
"%world%", source.getWorld().getName()));
}

// /geiger move <player> -> clear it; a new one is placed near them on their next hold
// /geiger move <player> <x> <z> -> specific coordinates
// /geiger move <player> <x> <z> -> buried under these coordinates
private void handleMove(CommandSender sender, String[] args) {
if (args.length != 2 && args.length != 4) {
sender.sendMessage(messages().get("admin.move-usage"));
Expand Down Expand Up @@ -173,8 +174,9 @@ private void sendNewLocation(CommandSender sender, String name, Location source)

sender.sendMessage(messages().get("admin.move-success",
"%player%", name,
"%x%", Messages.coordinate(source.getX()),
"%z%", Messages.coordinate(source.getZ())));
"%x%", source.getBlockX(),
"%y%", source.getBlockY(),
"%z%", source.getBlockZ()));
}

// /geiger limits <player> -> how many collections that player has left
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public class ConfigMigrator {
// v4: messages.yml split into player/admin sections
// v5: drops.tiers -> drops.lists.<name>.tiers, selected by drops.active-list
// v6: a source per character - source distances, bar section, detection range capped
public static final int CURRENT_VERSION = 6;
// v7: buried caches - burial depths, pinpoint range, ring moved out, collection-distance gone
public static final int CURRENT_VERSION = 7;

public static final String MESSAGES_FILE = "messages.yml";

Expand Down Expand Up @@ -87,6 +88,9 @@ public void migrate() {
if (liveVersion < 6) {
capDetectionRange(live);
}
if (liveVersion < 7) {
moveRingOut(live);
}
boolean versionChanged = liveVersion != CURRENT_VERSION;

if (addedKeys.isEmpty() && !versionChanged && !movedDropList) {
Expand Down Expand Up @@ -238,6 +242,28 @@ private void capDetectionRange(FileConfiguration live) {
+ " to match source.reroll-distance.");
}

// ====================================
// v6 shipped a 150-500 block ring, which proved too close. Only values
// still at those defaults move; a ring the admin chose is kept. Caches are
// opened by hand now, so collection-distance no longer means anything.
// ====================================
private void moveRingOut(FileConfiguration live) {
raiseDefault(live, "source.min-distance", 150.0, 300.0);
raiseDefault(live, "source.max-distance", 500.0, 600.0);
if (live.contains("detection.collection-distance", true)) {
live.set("detection.collection-distance", null);
plugin.getLogger().info("Removed detection.collection-distance - caches are dug up and opened now.");
}
}

private void raiseDefault(FileConfiguration live, String path, double oldDefault, double newDefault) {
if (live.getDouble(path) != oldDefault) {
return;
}
live.set(path, newDefault);
plugin.getLogger().info("Raised " + path + " from " + oldDefault + " to " + newDefault + ".");
}

// ====================================
// Copy every leaf key the packaged config has and the live one lacks.
//
Expand Down
Loading