Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use modules' fishing loot tables to randomly override fished items #294

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
26 changes: 26 additions & 0 deletions vane-core/src/main/java/org/oddlama/vane/core/LootTable.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.oddlama.vane.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -33,6 +35,12 @@ public Map<NamespacedKey, List<LootTableEntry>> possible_loot() {
return possible_loot;
}

public List<LootTableEntry> flat_copy() {
List<LootTableEntry> list = new ArrayList<>();
possible_loot.values().forEach(list::addAll);
return list;
}

public void generate_loot(final List<ItemStack> output, final Random random) {
for (final var set : possible_loot.values()) {
for (final var loot : set) {
Expand All @@ -43,6 +51,24 @@ public void generate_loot(final List<ItemStack> output, final Random random) {
}
}

public ItemStack generate_override(final Random random) {
double total_chance = 0;
final double threshold = random.nextDouble();
final List<ItemStack> result_container = new ArrayList<>(1);
final var loot_list = flat_copy();
Collections.shuffle(loot_list, random);
for (final var loot : loot_list) {
total_chance += loot.chance;
if (total_chance > threshold) {
loot.add_sample(result_container, random);
}
if (!result_container.isEmpty()) {
return result_container.get(0);
}
}
return null;
}

public static class LootTableEntry {

public double chance;
Expand Down
48 changes: 48 additions & 0 deletions vane-core/src/main/java/org/oddlama/vane/core/module/Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@
import org.bstats.bukkit.Metrics;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.world.LootGenerateEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootTables;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
Expand Down Expand Up @@ -515,4 +522,45 @@ public void on_module_loot_generate(final LootGenerateEvent event) {
(loc.getBlockZ() & (0xffff << 48)));
additional_loot_table.generate_loot(event.getLoot(), local_random);
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on_module_player_caught_fish(final PlayerFishEvent event) {
// This is a dirty non-commutative way to apply fishing loot tables
// that skews subtable probabilities,
// consider somehow programmatically generating datapacks or
// modifying loot tables directly instead.
if (event.getState() != PlayerFishEvent.State.CAUGHT_FISH) {
return;
}
if (event.getCaught() instanceof Item item_entity) {
final Player player = event.getPlayer();
final FishHook hook_entity = event.getHook();
final double player_luck = player.getAttribute(Attribute.LUCK).getValue();
final ItemStack rod_stack = player.getInventory().getItem(event.getHand());
final double rod_luck = rod_stack.getEnchantmentLevel(Enchantment.LUCK_OF_THE_SEA); // Can bukkit provide access to fishing_luck_bonus of 1.24 item component system?
final double total_luck = player_luck + rod_luck;
final double weight_fish = Math.max(0, 85 + total_luck * -1);
final double weight_junk = Math.max(0, 10 + total_luck * -2);
final double weight_treasure = hook_entity.isInOpenWater() ? Math.max(0, 5 + total_luck * 2) : 0;
final double roll = random.nextDouble() * (weight_fish + weight_junk + weight_treasure);
NamespacedKey key;
if (roll < weight_fish) {
key = LootTables.FISHING_FISH.getKey();
} else if (roll < weight_fish + weight_junk) {
key = LootTables.FISHING_JUNK.getKey();
} else {
key = LootTables.FISHING_TREASURE.getKey();
}
final var additional_loot_table = additional_loot_tables.get(key);
if (additional_loot_table == null) {
// Do not modify the caught item
return;
}
final var new_item = additional_loot_table.generate_override(new Random(random.nextInt()));
if (new_item == null) {
return;
}
item_entity.setItemStack(new_item);
}
}
}
Loading