use of com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo in project BKCommonLib by bergerhealer.
the class MapSession method onOwnerRemoved.
private void onOwnerRemoved(Owner owner) {
// Remove map display from by-player mapping
MapDisplayInfo info = this.display.getMapInfo();
if (info != null) {
MapDisplayInfo.ViewStack views = info.getOrCreateViewStack(owner.player);
if (!views.stack.isEmpty() && views.stack.getLast() == this.display) {
// Stop intercepting input
owner.interceptInput = false;
owner.input.handleDisplayUpdate(this.display, false);
// Remove self
views.stack.removeLast();
// If an older display is in the stack, switch to it
if (!views.stack.isEmpty()) {
views.stack.getLast().addOwner(owner.player);
}
} else {
// Simply remove the player from anywhere in the view stack
views.stack.remove(this.display);
}
}
}
use of com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo in project BKCommonLib by bergerhealer.
the class MapSession method update.
/**
* Updates the session. Returns false if the session should be ended.
*
* @return False when the session should be ended
*/
public boolean update() {
MapDisplayInfo info = this.display.getMapInfo();
if (info == null) {
// can't keep a session around for a map that does not exist!
return false;
}
// Update players and their input
this.hasHolders = false;
this.hasViewers = false;
this.hasNewViewers = false;
if (!this.onlineOwners.isEmpty()) {
Iterator<Owner> onlineIter = this.onlineOwners.iterator();
while (onlineIter.hasNext()) {
Owner owner = onlineIter.next();
// Update input
owner.input.handleDisplayUpdate(this.display, owner.interceptInput);
// Check if online. Remove offline players if not set FOREVER
if (!owner.player.isOnline()) {
if (this.mode != MapSessionMode.FOREVER) {
this.owners.remove(owner.player.getUniqueId());
}
onOwnerRemoved(owner);
onlineIter.remove();
continue;
}
// Check if holding the map
owner.controlling = info.isMap(HumanHand.getItemInMainHand(owner.player));
owner.holding = owner.controlling || info.isMap(HumanHand.getItemInOffHand(owner.player));
if (!owner.holding && this.mode == MapSessionMode.HOLDING) {
this.owners.remove(owner.player.getUniqueId());
onOwnerRemoved(owner);
onlineIter.remove();
continue;
}
// Check if viewing the map at all
owner.wasViewing = owner.viewing;
owner.viewing = owner.holding || info.getViewers().contains(owner.player);
if (!owner.viewing && this.mode == MapSessionMode.VIEWING) {
this.owners.remove(owner.player.getUniqueId());
onOwnerRemoved(owner);
onlineIter.remove();
continue;
}
// Update state
this.hasHolders |= owner.holding;
this.hasViewers |= owner.viewing;
this.hasNewViewers |= owner.isNewViewer();
}
}
// Session end condition
switch(this.mode) {
case FOREVER:
return true;
case ONLINE:
return !onlineOwners.isEmpty();
case VIEWING:
return this.hasViewers;
case HOLDING:
return this.hasHolders;
}
return true;
}
use of com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method handleMapShowEvent.
@SuppressWarnings("deprecation")
protected synchronized void handleMapShowEvent(MapShowEvent event) {
// Check if there are other map displays that should be shown to the player automatically
// This uses the 'isGlobal()' property of the display
MapDisplayInfo info = CommonMapController.this.getInfo(event.getMapUUID());
boolean hasDisplay = false;
if (info != null) {
for (MapSession session : info.getSessions()) {
if (session.display.isGlobal()) {
session.display.addOwner(event.getPlayer());
hasDisplay = true;
break;
}
}
}
// When defined in the NBT of the item, construct the Map Display automatically
// Do not do this when one was already assigned (global, or during event handling)
// We initialize the display the next tick using the plugin owner's task to avoid
// BKCommonLib showing up in timings when onAttached() is slow.
MapDisplayProperties properties = MapDisplayProperties.of(event.getMapItem());
if (!hasDisplay && !event.hasDisplay() && properties != null) {
Class<? extends MapDisplay> displayClass = properties.getMapDisplayClass();
if (displayClass != null) {
Plugin plugin = properties.getPlugin();
if (plugin instanceof JavaPlugin) {
try {
MapDisplay display = displayClass.newInstance();
event.setDisplay((JavaPlugin) plugin, display);
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
CommonUtil.callEvent(event);
}
use of com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method findLookingAt.
private LookAtSearchResult findLookingAt(Player player, ItemFrame itemFrame, Vector startPosition, Vector lookDirection) {
MapDisplayInfo info = getInfo(itemFrame);
if (info == null) {
// no map here
return null;
}
// Find the Display this player is sees on this map
MapDisplayInfo.ViewStack stack = info.getViewStackByPlayerUUID(player.getUniqueId());
if (stack == null || stack.stack.isEmpty()) {
// no visible display for this player
return null;
}
// Find the item frame metadata information
ItemFrameInfo frameInfo = this.itemFrames.get(itemFrame.getEntityId());
if (frameInfo == null) {
// not tracked
return null;
}
// Ask item frame to compute look-at information
// If looking further than 16 map pixels away from the edge, fail
MapLookPosition position = frameInfo.findLookPosition(startPosition, lookDirection);
final double limit = 16.0;
if (position == null || position.getEdgeDistance() > (limit / 128.0)) {
return null;
}
// Keep position within bounds of the display
// If very much out of bounds (>16 pixels) fail the looking-at check
// This loose-ness allows for smooth clicking between frames without failures
MapDisplay display = stack.stack.getLast();
double new_x = position.getDoubleX();
double new_y = position.getDoubleY();
if (new_x < -limit || new_y < -limit || new_x > (display.getWidth() + limit) || new_y >= (display.getHeight() + limit)) {
return null;
} else if (new_x < 0.0 || new_y < 0.0 || new_x >= display.getWidth() || new_y >= display.getHeight()) {
new_x = MathUtil.clamp(new_x, 0.0, (double) display.getWidth() - 1e-10);
new_y = MathUtil.clamp(new_y, 0.0, (double) display.getHeight() - 1e-10);
position = new MapLookPosition(position.getItemFrameInfo(), new_x, new_y, position.getDistance(), position.getEdgeDistance());
}
return new LookAtSearchResult(display, position);
}
use of com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method updateMapItem.
/**
* Updates the information of a map item, refreshing all item frames
* and player inventories storing the item. Map displays are also
* updated.
*
* @param oldItem that was changed
* @param newItem the old item was changed into
*/
public synchronized void updateMapItem(ItemStack oldItem, ItemStack newItem) {
if (oldItem == null) {
throw new IllegalArgumentException("oldItem is null");
} else if (!CraftItemStackHandle.T.isAssignableFrom(oldItem)) {
// Ensure CraftItemStack
oldItem = ItemUtil.createItem(oldItem);
}
if (newItem != null && !CraftItemStackHandle.T.isAssignableFrom(newItem)) {
// Ensure CraftItemStack
newItem = ItemUtil.createItem(newItem);
}
boolean unchanged = isItemUnchanged(oldItem, newItem);
UUID oldMapUUID = CommonMapUUIDStore.getMapUUID(oldItem);
if (oldMapUUID != null) {
// Change in the inventories of all player owners
for (Player player : Bukkit.getOnlinePlayers()) {
PlayerInventory inv = player.getInventory();
for (int i = 0; i < inv.getSize(); i++) {
UUID mapUUID = CommonMapUUIDStore.getMapUUID(inv.getItem(i));
if (oldMapUUID.equals(mapUUID)) {
if (unchanged) {
PlayerUtil.setItemSilently(player, i, newItem);
} else {
inv.setItem(i, newItem);
}
}
}
}
// All item frames that show this same map
for (ItemFrameInfo itemFrameInfo : CommonPlugin.getInstance().getMapController().getItemFrames()) {
if (itemFrameInfo.lastMapUUID != null && oldMapUUID.equals(itemFrameInfo.lastMapUUID.getUUID())) {
if (unchanged) {
// When unchanged set the item in the metadata without causing a refresh
DataWatcher data = EntityHandle.fromBukkit(itemFrameInfo.itemFrame).getDataWatcher();
DataWatcher.Item<ItemStack> dataItem = data.getItem(EntityItemFrameHandle.DATA_ITEM);
dataItem.setValue(newItem, dataItem.isChanged());
} else {
// When changed, set it normally so the item is refreshed
itemFrameInfo.itemFrameHandle.setItem(newItem);
this.itemFrameUpdateList.prioritize(itemFrameInfo.updateEntry);
}
}
}
// All map displays showing this item
MapDisplayInfo info = maps.get(oldMapUUID);
if (info != null) {
for (MapSession session : info.getSessions()) {
session.display.setMapItemSilently(newItem);
}
}
}
}
Aggregations