mirror of
https://github.com/BentoBoxWorld/Boxed.git
synced 2024-12-12 14:47:13 +01:00
Store and trigger advancements for entering structures.
This commit is contained in:
parent
d130e02167
commit
8e8da27f98
@ -30,6 +30,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
|||||||
import org.bukkit.event.player.PlayerPortalEvent;
|
import org.bukkit.event.player.PlayerPortalEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.events.island.IslandNewIslandEvent;
|
import world.bentobox.bentobox.api.events.island.IslandNewIslandEvent;
|
||||||
import world.bentobox.bentobox.api.events.team.TeamJoinedEvent;
|
import world.bentobox.bentobox.api.events.team.TeamJoinedEvent;
|
||||||
import world.bentobox.bentobox.api.events.team.TeamLeaveEvent;
|
import world.bentobox.bentobox.api.events.team.TeamLeaveEvent;
|
||||||
@ -66,7 +67,7 @@ public class AdvancementListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Advancement getAdvancement(String string) {
|
public static Advancement getAdvancement(String string) {
|
||||||
return StreamSupport.stream(
|
return StreamSupport.stream(
|
||||||
Spliterators.spliteratorUnknownSize(Bukkit.advancementIterator(), Spliterator.ORDERED), false)
|
Spliterators.spliteratorUnknownSize(Bukkit.advancementIterator(), Spliterator.ORDERED), false)
|
||||||
.filter(a -> a.getKey().toString().equals(string))
|
.filter(a -> a.getKey().toString().equals(string))
|
||||||
@ -191,14 +192,28 @@ public class AdvancementListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void giveAdv(Player player, Advancement adv) {
|
public static void giveAdv(Player player, Advancement adv) {
|
||||||
|
//BentoBox.getInstance().logDebug("Give Adv " + adv.getKey() + " done status " + player.getAdvancementProgress(adv).isDone());
|
||||||
if (adv != null && !player.getAdvancementProgress(adv).isDone()) {
|
if (adv != null && !player.getAdvancementProgress(adv).isDone()) {
|
||||||
|
BentoBox.getInstance().logDebug("Awarding ");
|
||||||
|
//adv.getCriteria().forEach(c -> BentoBox.getInstance().logDebug("Criteria = " + c));
|
||||||
adv.getCriteria().forEach(player.getAdvancementProgress(adv)::awardCriteria);
|
adv.getCriteria().forEach(player.getAdvancementProgress(adv)::awardCriteria);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||||
|
/*
|
||||||
|
StreamSupport.stream(
|
||||||
|
Spliterators.spliteratorUnknownSize(Bukkit.advancementIterator(), Spliterator.ORDERED), false).forEach(a-> {
|
||||||
|
AdvancementProgress progress = e.getPlayer().getAdvancementProgress(a);
|
||||||
|
BentoBox.getInstance().logDebug(a.getKey() + " " + progress.isDone());
|
||||||
|
BentoBox.getInstance().logDebug("Awarded");
|
||||||
|
progress.getAwardedCriteria().forEach(c -> BentoBox.getInstance().logDebug(c));
|
||||||
|
BentoBox.getInstance().logDebug("Remaining");
|
||||||
|
progress.getRemainingCriteria().forEach(c -> BentoBox.getInstance().logDebug(c));
|
||||||
|
});
|
||||||
|
*/
|
||||||
User user = User.getInstance(e.getPlayer());
|
User user = User.getInstance(e.getPlayer());
|
||||||
if (Util.sameWorld(addon.getOverWorld(), e.getPlayer().getWorld())) {
|
if (Util.sameWorld(addon.getOverWorld(), e.getPlayer().getWorld())) {
|
||||||
// Set advancements to same as island
|
// Set advancements to same as island
|
||||||
|
@ -2,10 +2,12 @@ package world.bentobox.boxed.listeners;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@ -26,9 +28,11 @@ import org.bukkit.configuration.ConfigurationSection;
|
|||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.loot.LootTables;
|
import org.bukkit.loot.LootTables;
|
||||||
import org.bukkit.structure.Structure;
|
import org.bukkit.structure.Structure;
|
||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.util.BoundingBox;
|
||||||
@ -45,12 +49,14 @@ import world.bentobox.bentobox.BentoBox;
|
|||||||
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
||||||
import world.bentobox.bentobox.api.events.island.IslandCreatedEvent;
|
import world.bentobox.bentobox.api.events.island.IslandCreatedEvent;
|
||||||
import world.bentobox.bentobox.api.events.island.IslandResettedEvent;
|
import world.bentobox.bentobox.api.events.island.IslandResettedEvent;
|
||||||
|
import world.bentobox.bentobox.database.Database;
|
||||||
import world.bentobox.bentobox.database.objects.Island;
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
import world.bentobox.bentobox.util.Pair;
|
import world.bentobox.bentobox.util.Pair;
|
||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
import world.bentobox.boxed.Boxed;
|
import world.bentobox.boxed.Boxed;
|
||||||
import world.bentobox.boxed.objects.BoxedJigsawBlock;
|
import world.bentobox.boxed.objects.BoxedJigsawBlock;
|
||||||
import world.bentobox.boxed.objects.BoxedStructureBlock;
|
import world.bentobox.boxed.objects.BoxedStructureBlock;
|
||||||
|
import world.bentobox.boxed.objects.IslandStructures;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
@ -59,6 +65,14 @@ import world.bentobox.boxed.objects.BoxedStructureBlock;
|
|||||||
public class NewAreaListener implements Listener {
|
public class NewAreaListener implements Listener {
|
||||||
|
|
||||||
private static final List<BlockFace> CARDINALS = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
private static final List<BlockFace> CARDINALS = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
||||||
|
private static final List<String> STRUCTURES = List.of("ancient_city", "bastion_remnant", "bastion",
|
||||||
|
"buried_treasure", "desert_pyramid", "end_city",
|
||||||
|
"fortress", "igloo", "jungle_pyramid", "mansion", "mineshaft", "mineshaft_mesa",
|
||||||
|
"monument", "nether_fossil", "ocean_ruin_cold", "ocean_ruin_warm", "pillager_outpost",
|
||||||
|
"ruined_portal_desert", "ruined_portal_jungle", "ruined_portal_mountain", "ruined_portal_nether",
|
||||||
|
"ruined_portal_ocean", "ruined_portal_swamp", "ruined_portal", "shipwreck_beached",
|
||||||
|
"shipwreck", "stronghold", "swamp_hut", "village_desert", "village_plains",
|
||||||
|
"village_savanna", "village_snowy", "village_taiga");
|
||||||
private final Boxed addon;
|
private final Boxed addon;
|
||||||
private File structureFile;
|
private File structureFile;
|
||||||
private Queue<Item> itemsToBuild = new LinkedList<>();
|
private Queue<Item> itemsToBuild = new LinkedList<>();
|
||||||
@ -68,6 +82,10 @@ public class NewAreaListener implements Listener {
|
|||||||
private record Item(String name, Structure structure, Location location, StructureRotation rot, Mirror mirror) {};
|
private record Item(String name, Structure structure, Location location, StructureRotation rot, Mirror mirror) {};
|
||||||
Pair<Integer, Integer> min = new Pair<Integer, Integer>(0,0);
|
Pair<Integer, Integer> min = new Pair<Integer, Integer>(0,0);
|
||||||
Pair<Integer, Integer> max = new Pair<Integer, Integer>(0,0);
|
Pair<Integer, Integer> max = new Pair<Integer, Integer>(0,0);
|
||||||
|
// Database handler for structure data
|
||||||
|
private final Database<IslandStructures> handler;
|
||||||
|
private Map<String, IslandStructures> islandStructureCache = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +96,8 @@ public class NewAreaListener implements Listener {
|
|||||||
addon.saveResource("structures.yml", false);
|
addon.saveResource("structures.yml", false);
|
||||||
// Load the config
|
// Load the config
|
||||||
structureFile = new File(addon.getDataFolder(), "structures.yml");
|
structureFile = new File(addon.getDataFolder(), "structures.yml");
|
||||||
|
// Get database ready
|
||||||
|
handler = new Database<>(addon, IslandStructures.class);
|
||||||
// Try to build something every second
|
// Try to build something every second
|
||||||
Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> BuildItem(), 20, 20);
|
Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> BuildItem(), 20, 20);
|
||||||
}
|
}
|
||||||
@ -96,7 +115,7 @@ public class NewAreaListener implements Listener {
|
|||||||
* Build a list of structures
|
* Build a list of structures
|
||||||
* @param event event
|
* @param event event
|
||||||
*/
|
*/
|
||||||
@EventHandler()
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onBentoBoxReady(BentoBoxReadyEvent event) {
|
public void onBentoBoxReady(BentoBoxReadyEvent event) {
|
||||||
addon.saveResource("templates.yml", false);
|
addon.saveResource("templates.yml", false);
|
||||||
File templateFile = new File(addon.getDataFolder(), "templates.yml");
|
File templateFile = new File(addon.getDataFolder(), "templates.yml");
|
||||||
@ -113,6 +132,58 @@ public class NewAreaListener implements Listener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent e) {
|
||||||
|
// Ignore head movements
|
||||||
|
if (!addon.inWorld(e.getFrom().getWorld()) || e.getFrom().toVector().equals(e.getTo().toVector())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check where the player is
|
||||||
|
addon.getIslands().getIslandAt(e.getTo()).ifPresent(island -> {
|
||||||
|
// See if island is in cache
|
||||||
|
final String islandId = island.getUniqueId();
|
||||||
|
IslandStructures is = getIslandStructData(islandId);
|
||||||
|
// Check if player is in any of the structures
|
||||||
|
Map<BoundingBox, String> structures = e.getTo().getWorld().getEnvironment().equals(Environment.NETHER) ?
|
||||||
|
is.getNetherStructureBoundingBoxMap():is.getStructureBoundingBoxMap();
|
||||||
|
for (Map.Entry<BoundingBox, String> en:structures.entrySet()) {
|
||||||
|
if (en.getKey().contains(e.getTo().toVector())) {
|
||||||
|
for (String s: STRUCTURES) {
|
||||||
|
if (en.getValue().startsWith(s)) {
|
||||||
|
giveAdvFromCriteria(e.getPlayer(), s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//STRUCTURES.stream().filter(en.getValue()::startsWith).forEach(s -> giveAdvFromCriteria(e.getPlayer(), s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives a player all the advancements that have string as a named criteria
|
||||||
|
* @param player - player
|
||||||
|
* @param string - criteria
|
||||||
|
*/
|
||||||
|
private void giveAdvFromCriteria(Player player, String string) {
|
||||||
|
// Give every advancement that requires a bastion
|
||||||
|
Bukkit.advancementIterator().forEachRemaining(ad -> {
|
||||||
|
if (!player.getAdvancementProgress(ad).isDone()) {
|
||||||
|
for (String crit: ad.getCriteria()) {
|
||||||
|
if (crit.equals(string)) {
|
||||||
|
// Set the criteria (it may not complete the advancement completely
|
||||||
|
player.getAdvancementProgress(ad).awardCriteria(crit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private IslandStructures getIslandStructData(String islandId) {
|
||||||
|
return this.islandStructureCache.computeIfAbsent(islandId, k -> Objects.requireNonNullElse(handler.loadObject(k), new IslandStructures(islandId)));
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onIslandCreated(IslandCreatedEvent event) {
|
public void onIslandCreated(IslandCreatedEvent event) {
|
||||||
setUpIsland(event.getIsland());
|
setUpIsland(event.getIsland());
|
||||||
@ -185,7 +256,18 @@ public class NewAreaListener implements Listener {
|
|||||||
item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand);
|
item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand);
|
||||||
addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " " + Util.xyz(item.location().toVector()));
|
addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " " + Util.xyz(item.location().toVector()));
|
||||||
// Find it
|
// Find it
|
||||||
removeJigsaw(item.location(), item.structure(), item.rot(), item.name());
|
BoundingBox bb = removeJigsaw(item.location(), item.structure(), item.rot(), item.name());
|
||||||
|
// Store it
|
||||||
|
addon.getIslands().getIslandAt(item.location()).map(Island::getUniqueId).ifPresent(id -> {
|
||||||
|
addon.log("Saved " + item.name());
|
||||||
|
if (item.location().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
||||||
|
getIslandStructData(id).addNetherStructure(bb, item.name());
|
||||||
|
} else {
|
||||||
|
getIslandStructData(id).addStructure(bb, item.name());
|
||||||
|
}
|
||||||
|
handler.saveObjectAsync(getIslandStructData(id));
|
||||||
|
});
|
||||||
|
|
||||||
pasting = false;
|
pasting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +277,9 @@ public class NewAreaListener implements Listener {
|
|||||||
* @param structure - structure that was placed
|
* @param structure - structure that was placed
|
||||||
* @param structureRotation - rotation of structure
|
* @param structureRotation - rotation of structure
|
||||||
* @param key
|
* @param key
|
||||||
|
* @return the resulting bounding box of the structure
|
||||||
*/
|
*/
|
||||||
public static void removeJigsaw(Location loc, Structure structure, StructureRotation structureRotation, String key) {
|
public static BoundingBox removeJigsaw(Location loc, Structure structure, StructureRotation structureRotation, String key) {
|
||||||
Location otherCorner = switch (structureRotation) {
|
Location otherCorner = switch (structureRotation) {
|
||||||
|
|
||||||
case CLOCKWISE_180 -> loc.clone().add(new Vector(-structure.getSize().getX(), structure.getSize().getY(), -structure.getSize().getZ()));
|
case CLOCKWISE_180 -> loc.clone().add(new Vector(-structure.getSize().getX(), structure.getSize().getY(), -structure.getSize().getZ()));
|
||||||
@ -227,7 +310,7 @@ public class NewAreaListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package world.bentobox.boxed.objects;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.util.BoundingBox;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.database.objects.DataObject;
|
||||||
|
import world.bentobox.bentobox.database.objects.Table;
|
||||||
|
|
||||||
|
@Table(name = "IslandStructures")
|
||||||
|
public class IslandStructures implements DataObject {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
String uniqueId;
|
||||||
|
@Expose
|
||||||
|
Map<BoundingBox, String> structureBoundingBoxMap = new HashMap<>();
|
||||||
|
@Expose
|
||||||
|
Map<BoundingBox, String> netherStructureBoundingBoxMap = new HashMap<>();
|
||||||
|
|
||||||
|
public IslandStructures(String islandId) {
|
||||||
|
this.uniqueId = islandId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueId() {
|
||||||
|
return uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUniqueId(String uniqueId) {
|
||||||
|
this.uniqueId = uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a structure for this island
|
||||||
|
* @param bb - bounding box of the structure
|
||||||
|
* @param key - structure namespace key
|
||||||
|
*/
|
||||||
|
public void addStructure(BoundingBox bb, String key) {
|
||||||
|
getStructureBoundingBoxMap().put(bb, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BoundingBox, String> getStructureBoundingBoxMap() {
|
||||||
|
if (structureBoundingBoxMap == null) {
|
||||||
|
structureBoundingBoxMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
return structureBoundingBoxMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStructureBoundingBoxMap(Map<BoundingBox, String> structureBoundingBoxMap) {
|
||||||
|
this.structureBoundingBoxMap = structureBoundingBoxMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a structure for this island
|
||||||
|
* @param bb - bounding box of the structure
|
||||||
|
* @param key - structure namespace key
|
||||||
|
*/
|
||||||
|
public void addNetherStructure(BoundingBox bb, String key) {
|
||||||
|
getNetherStructureBoundingBoxMap().put(bb, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BoundingBox, String> getNetherStructureBoundingBoxMap() {
|
||||||
|
if (netherStructureBoundingBoxMap == null) {
|
||||||
|
netherStructureBoundingBoxMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
return netherStructureBoundingBoxMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetherStructureBoundingBoxMap(Map<BoundingBox, String> netherStructureBoundingBoxMap) {
|
||||||
|
this.netherStructureBoundingBoxMap = netherStructureBoundingBoxMap;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user