Skip to content

Commit caa59c6

Browse files
authored
Merge pull request #158 from balugaq/fix/fireproof-rune
Fireproof Rune Fixes
2 parents cc6d279 + 14f2419 commit caa59c6

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

src/main/java/io/github/pylonmc/pylon/base/PylonBase.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
import lombok.Getter;
1212
import org.bukkit.Bukkit;
1313
import org.bukkit.Material;
14+
import org.bukkit.plugin.Plugin;
1415
import org.bukkit.plugin.PluginManager;
1516
import org.bukkit.plugin.java.JavaPlugin;
1617
import org.bukkit.scheduler.BukkitTask;
1718
import org.jetbrains.annotations.NotNull;
1819

1920
import java.util.Locale;
2021
import java.util.Set;
22+
import java.util.function.Consumer;
2123

2224
@SuppressWarnings("UnstableApiUsage")
2325
public class PylonBase extends JavaPlugin implements PylonAddon {
@@ -68,8 +70,7 @@ public void onEnable() {
6870
return Material.COPPER_INGOT;
6971
}
7072

71-
@NotNull
72-
public static BukkitTask runSync(@NotNull Runnable runnable) {
73-
return Bukkit.getScheduler().runTask(instance, runnable);
73+
public static void runSyncTimer(@NotNull Consumer<BukkitTask> task, long delay, long period) {
74+
Bukkit.getScheduler().runTaskTimer(instance, task, delay, period);
7475
}
7576
}

src/main/java/io/github/pylonmc/pylon/base/content/magic/FireproofRune.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package io.github.pylonmc.pylon.base.content.magic;
22

33
import com.destroystokyo.paper.ParticleBuilder;
4-
import io.github.pylonmc.pylon.base.BaseConfig;
54
import io.github.pylonmc.pylon.base.content.magic.base.Rune;
5+
import io.github.pylonmc.pylon.core.item.builder.ItemStackBuilder;
66
import io.papermc.paper.datacomponent.DataComponentTypes;
77
import io.papermc.paper.datacomponent.item.DamageResistant;
88
import io.papermc.paper.registry.keys.tags.DamageTypeTagKeys;
99
import net.kyori.adventure.text.Component;
10-
import org.bukkit.FluidCollisionMode;
10+
import net.kyori.adventure.translation.GlobalTranslator;
1111
import org.bukkit.Location;
1212
import org.bukkit.Particle;
1313
import org.bukkit.Sound;
@@ -20,14 +20,31 @@
2020
/**
2121
* @author balugaq
2222
*/
23-
@SuppressWarnings("UnstableApiUsage")
2423
public class FireproofRune extends Rune {
2524
public static final Component SUCCESS = Component.translatable("pylon.pylonbase.message.fireproof_result.success");
25+
public static final Component TOOLTIP = Component.translatable("pylon.pylonbase.message.fireproof_result.tooltip");
26+
2627

2728
public FireproofRune(@NotNull ItemStack stack) {
2829
super(stack);
2930
}
3031

32+
/**
33+
* Fixes #156 - Fireproof rune can be applied multiple times
34+
* <p>
35+
* Checks if the rune is applicable to the target item.
36+
*
37+
* @param event The event
38+
* @param rune The rune item, amount may be > 1
39+
* @param target The item to handle, amount may be > 1
40+
* @return true if applicable, false otherwise
41+
*/
42+
public boolean isApplicableToTarget(@NotNull PlayerDropItemEvent event, @NotNull ItemStack rune, @NotNull ItemStack target) {
43+
DamageResistant data = target.getData(DataComponentTypes.DAMAGE_RESISTANT);
44+
if (data == null) return true;
45+
return !data.types().equals(DamageTypeTagKeys.IS_FIRE);
46+
}
47+
3148
/**
3249
* Handles contacting between an item and a rune.
3350
*
@@ -40,28 +57,30 @@ public void onContactItem(@NotNull PlayerDropItemEvent event, @NotNull ItemStack
4057
// As many runes as possible to consume
4158
int consume = Math.min(rune.getAmount(), target.getAmount());
4259

43-
ItemStack handle = target.asQuantity(consume);
44-
handle.setData(DataComponentTypes.DAMAGE_RESISTANT, DamageResistant.damageResistant(DamageTypeTagKeys.IS_FIRE));
60+
Player player = event.getPlayer();
61+
ItemStack handle = ItemStackBuilder.of(target.asQuantity(consume)) // Already cloned in `asQuantity`
62+
.set(DataComponentTypes.DAMAGE_RESISTANT, DamageResistant.damageResistant(DamageTypeTagKeys.IS_FIRE))
63+
.lore(GlobalTranslator.render(TOOLTIP, player.locale()))
64+
.build();
4565

4666
// (N)Either left runes or targets
4767
int leftRunes = rune.getAmount() - consume;
4868
int leftTargets = target.getAmount() - consume;
4969

50-
Player player = event.getPlayer();
51-
Location explodeLoc = player.getTargetBlockExact((int) Math.ceil(BaseConfig.RUNE_CHECK_RANGE), FluidCollisionMode.NEVER).getLocation();
70+
Location explodeLoc = event.getItemDrop().getLocation();
5271
World world = explodeLoc.getWorld();
5372
if (leftRunes > 0) {
54-
world.dropItemNaturally(explodeLoc, rune.asQuantity(leftRunes));
73+
world.dropItemNaturally(explodeLoc, rune.asQuantity(leftRunes)).setGlowing(true);
5574
}
5675
if (leftTargets > 0) {
57-
world.dropItemNaturally(explodeLoc, target.asQuantity(leftTargets));
76+
world.dropItemNaturally(explodeLoc, target.asQuantity(leftTargets)).setGlowing(true);
5877
}
59-
world.dropItemNaturally(explodeLoc, handle);
78+
world.dropItemNaturally(explodeLoc, handle).setGlowing(true);
6079

6180
// simple particles
6281
spawnParticle(Particle.EXPLOSION, explodeLoc, 1);
63-
spawnParticle(Particle.FLAME, explodeLoc, 20);
64-
spawnParticle(Particle.SMOKE, explodeLoc, 1);
82+
spawnParticle(Particle.FLAME, explodeLoc, 50);
83+
spawnParticle(Particle.SMOKE, explodeLoc, 40);
6584
world.playSound(explodeLoc, Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f);
6685

6786
target.setAmount(0);

src/main/java/io/github/pylonmc/pylon/base/content/magic/base/Rune.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,19 @@ void onRuneDrop(@NotNull PlayerDropItemEvent event) {
8080
return;
8181
}
8282

83+
// Fix #155 - Fireproof rune only checks proximity at the moment it's dropped
8384
// Force run synchronously for entity handling
84-
PylonBase.runSync(() -> {
85-
Block lookingAt = player.getTargetBlockExact((int) Math.ceil(BaseConfig.RUNE_CHECK_RANGE), FluidCollisionMode.NEVER);
86-
if (lookingAt == null) {
87-
// The player may drop runes in the sky, skip it.
85+
PylonBase.runSyncTimer(task -> {
86+
if (runeEntity.isDead() || !runeEntity.isValid()) {
87+
task.cancel();
8888
return;
8989
}
9090

91-
Collection<Item> nearbyEntities = player.getWorld().getNearbyEntitiesByType(Item.class, lookingAt.getLocation(), BaseConfig.RUNE_CHECK_RANGE, item -> rune.isApplicableToTarget(event, runeStack, item.getItemStack()));
91+
if (!runeEntity.isOnGround()) {
92+
return;
93+
}
94+
95+
Collection<Item> nearbyEntities = player.getWorld().getNearbyEntitiesByType(Item.class, runeEntity.getLocation(), BaseConfig.RUNE_CHECK_RANGE, item -> rune.isApplicableToTarget(event, runeStack, item.getItemStack()));
9296
Item targetEntity = nearbyEntities
9397
.stream()
9498
.findFirst()
@@ -105,7 +109,7 @@ void onRuneDrop(@NotNull PlayerDropItemEvent event) {
105109
rune.onContactItem(event, runeStack, target);
106110
runeEntity.setItemStack(runeStack);
107111
targetEntity.setItemStack(target);
108-
});
112+
}, 1, 2);
109113
}
110114
}
111115
}

src/main/resources/lang/en.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,8 @@ message:
13091309
working_with_reduced_efficiency: "<green>Working with reduced efficiency"
13101310
no_sunlight: "<red>No sunlight"
13111311
fireproof_result:
1312-
success: "Your item has been fire-proofed"
1312+
tooltip: "<red><bold>Fire-proofed"
1313+
success: "<red>Your item has been fire-proofed"
13131314

13141315
gui:
13151316
fluid-selector-title: "Select Fluid"

0 commit comments

Comments
 (0)