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
5 changes: 5 additions & 0 deletions src/main/java/net/tfminecraft/magic/gear/GearKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ public static NamespacedKey rift() {
public static NamespacedKey partPick() {
return new NamespacedKey(Magic.plugin, "gear_part_id");
}

/** Marks the ItemDisplay that shows the weapon resting on a gear station. */
public static NamespacedKey stationDisplay() {
return new NamespacedKey(Magic.plugin, "gear_station_display");
}
}
56 changes: 51 additions & 5 deletions src/main/java/net/tfminecraft/magic/gear/GearStationListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;

import dev.lone.itemsadder.api.Events.FurnitureBreakEvent;
import net.tfminecraft.tlibs.TLibs;
import net.tfminecraft.magic.Magic;
import net.tfminecraft.magic.Messages;
import net.tfminecraft.magic.charge.ChargeIds;
import net.tfminecraft.magic.gear.gui.GearInventoryManager;
Expand All @@ -32,6 +34,9 @@ public final class GearStationListener implements Listener {
/** ItemsAdder breaks furniture two ticks after the swing, so an abort swing needs cover. */
private static final long ABORT_BREAK_GUARD_MILLIS = 1000L;

/** Reaches a frame in this station's block and not the center of a neighbouring block. */
private static final double STATION_REACH = 0.75;

private final GearInventoryManager inventory = new GearInventoryManager();
private final Map<String, Long> recentAborts = new HashMap<>();

Expand All @@ -52,15 +57,56 @@ public void onFurnitureBreak(FurnitureBreakEvent event) {
if (entity == null) {
return;
}
Location location = entity.getLocation().getBlock().getLocation();
Long aborted = recentAborts.get(GearStationStore.key(location));
boolean justAborted = aborted != null
&& System.currentTimeMillis() - aborted < ABORT_BREAK_GUARD_MILLIS;
if (justAborted || GearStationStore.isOccupied(location) || GearOrbService.isActive(location)) {
Location at = entity.getLocation();
if (recentlyAbortedNear(at) || GearStationStore.occupiedWithin(at, STATION_REACH) != null) {
event.setCancelled(true);
}
}

/**
* A break that was not cancelled has removed the furniture. Drop that station's
* weapon instead of leaving the display in the air.
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onFurnitureBroken(FurnitureBreakEvent event) {
if (!isStationFurniture(event.getNamespacedID())) {
return;
}
Entity entity = event.getBukkitEntity();
if (entity == null) {
return;
}
Location station = GearStationStore.occupiedWithin(entity.getLocation(), STATION_REACH);
if (station == null) {
return;
}
GearOrbService.abort(station);
ItemStack weapon = GearStationStore.takeForAbort(station);
if (weapon != null && station.getWorld() != null) {
station.getWorld().dropItem(station.clone().add(0.5, 1.0, 0.5), weapon);
Magic.plugin.getLogger().warning("[Magic] Gear station at " + GearStationStore.key(station)
+ " lost its furniture. Dropped the weapon and removed its display.");
}
}

@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
GearStationStore.reconcile(event.getChunk());
}

private boolean recentlyAbortedNear(Location at) {
long now = System.currentTimeMillis();
recentAborts.entrySet().removeIf(entry -> now - entry.getValue() >= ABORT_BREAK_GUARD_MILLIS);
for (Map.Entry<String, Long> entry : recentAborts.entrySet()) {
Location station = GearStationStore.locationFromKey(entry.getKey());
if (station != null
&& GearStationStore.distanceSquaredToCenter(station, at) <= STATION_REACH * STATION_REACH) {
return true;
}
}
return false;
}

private static boolean isStationFurniture(String namespacedId) {
String station = GearCache.station == null ? "" : GearCache.station.trim();
int open = station.indexOf('(');
Expand Down
Loading