feat(tamer): release mobs after class loss
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class BukkitCapturedMobSpawner implements CapturedMobSpawner {
|
||||
private final Server server;
|
||||
private final PluginSettings settings;
|
||||
|
||||
public BukkitCapturedMobSpawner(Server server, PluginSettings settings) {
|
||||
this.server = server;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawn(Player player, CapturedMob mob) {
|
||||
Location location = player.getLocation();
|
||||
if (!safe(location)
|
||||
|| "ENDER_DRAGON".equals(mob.entityType())
|
||||
|| settings.deniedMobTypes().contains(mob.entityType())) {
|
||||
return false;
|
||||
}
|
||||
String serialized = mob.data().get("snapshot");
|
||||
if (serialized == null || serialized.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
EntitySnapshot snapshot = server.getEntityFactory().createEntitySnapshot(serialized);
|
||||
if (!snapshot.getEntityType().name().equals(mob.entityType())) {
|
||||
return false;
|
||||
}
|
||||
snapshot.createEntity(location);
|
||||
return true;
|
||||
} catch (IllegalArgumentException | IllegalStateException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean safe(Location location) {
|
||||
return location.getWorld() != null
|
||||
&& location.getBlock().isPassable()
|
||||
&& location.clone().add(0.0, 1.0, 0.0).getBlock().isPassable()
|
||||
&& location.getWorld().getWorldBorder().isInside(location);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CapturedMobCustodyRelease {
|
||||
PlayerState releaseAll(Player player, PlayerState state);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CapturedMobSpawner {
|
||||
boolean spawn(Player player, CapturedMob mob);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class DefaultCapturedMobCustodyRelease implements CapturedMobCustodyRelease {
|
||||
private final CapturedMobSpawner spawner;
|
||||
|
||||
public DefaultCapturedMobCustodyRelease(CapturedMobSpawner spawner) {
|
||||
this.spawner = spawner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerState releaseAll(Player player, PlayerState state) {
|
||||
List<CapturedMob> retained = new ArrayList<>();
|
||||
for (CapturedMob mob : state.capturedMobs()) {
|
||||
if (!spawner.spawn(player, mob)) {
|
||||
retained.add(mob);
|
||||
}
|
||||
}
|
||||
if (retained.size() == state.capturedMobs().size()) {
|
||||
return state;
|
||||
}
|
||||
return new PlayerState(
|
||||
state.playerId(), state.latestName(), state.lastLogin(), state.optedOutUntil(),
|
||||
state.tyrantClass(), state.followerOf(), state.cooldownEnds(),
|
||||
state.readyAbilityItems(), retained
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package games.dmg.spigottyrant;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class FormerTamerReleaseTask implements Runnable {
|
||||
private final TyrantStateManager stateManager;
|
||||
private final Server server;
|
||||
private final CapturedMobCustodyRelease release;
|
||||
private final CapturedMobInventoryService inventory;
|
||||
|
||||
public FormerTamerReleaseTask(
|
||||
TyrantStateManager stateManager,
|
||||
Server server,
|
||||
CapturedMobCustodyRelease release
|
||||
) {
|
||||
this(stateManager, server, release, null);
|
||||
}
|
||||
|
||||
public FormerTamerReleaseTask(
|
||||
TyrantStateManager stateManager,
|
||||
Server server,
|
||||
CapturedMobCustodyRelease release,
|
||||
CapturedMobInventoryService inventory
|
||||
) {
|
||||
this.stateManager = stateManager;
|
||||
this.server = server;
|
||||
this.release = release;
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Map<UUID, Player> online = server.getOnlinePlayers().stream()
|
||||
.collect(Collectors.toMap(Player::getUniqueId, player -> player));
|
||||
for (PlayerState state : stateManager.players().values()) {
|
||||
if (state.tyrantClass() == TyrantClass.TAMER || state.capturedMobs().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Player player = online.get(state.playerId());
|
||||
if (player == null || player.isDead()) {
|
||||
continue;
|
||||
}
|
||||
PlayerState released = release.releaseAll(player, state);
|
||||
if (released.equals(state)) {
|
||||
continue;
|
||||
}
|
||||
stateManager.updatePlayer(
|
||||
state.playerId(), state.latestName(), current -> released
|
||||
);
|
||||
stateManager.saveIfDirty();
|
||||
if (inventory != null) {
|
||||
inventory.reconcile(player, released);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,10 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
CapturedMobInventoryService capturedMobInventory = new CapturedMobInventoryService(
|
||||
capturedMobItems, settings
|
||||
);
|
||||
CapturedMobCustodyRelease formerTamerRelease =
|
||||
new DefaultCapturedMobCustodyRelease(
|
||||
new BukkitCapturedMobSpawner(getServer(), settings)
|
||||
);
|
||||
AssassinAbilityService assassinAbilities = new AssassinAbilityService(
|
||||
readiness, settings
|
||||
);
|
||||
@@ -246,6 +250,14 @@ public final class SpigotTyrantPlugin extends JavaPlugin {
|
||||
1L,
|
||||
10L
|
||||
);
|
||||
getServer().getScheduler().runTaskTimer(
|
||||
this,
|
||||
new FormerTamerReleaseTask(
|
||||
stateManager, getServer(), formerTamerRelease, capturedMobInventory
|
||||
),
|
||||
1L,
|
||||
10L
|
||||
);
|
||||
getServer().getScheduler().runTaskTimer(this, stateManager::saveIfDirty, 600L, 600L);
|
||||
getLogger().info("Spigot Tyrant enabled.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user