#1476: Add MenuType ViewBuilder
This commit is contained in:
parent
c818af1fe7
commit
643b231025
@ -106,8 +106,8 @@
|
||||
+ containerSynchronizer.sendSlotChange(containerMenu, s, getMainHandItem());
|
||||
+ });
|
||||
+ containerSynchronizer.sendSlotChange(inventoryMenu, ContainerPlayer.SHIELD_SLOT, getOffhandItem());
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ // Yes, this doesn't match Vanilla, but it's the best we can do for now.
|
||||
+ // If this is an issue, PRs are welcome
|
||||
+ public final BlockPosition getSpawnPoint(WorldServer worldserver) {
|
||||
@ -144,9 +144,9 @@
|
||||
+ }
|
||||
+
|
||||
+ return blockposition;
|
||||
}
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
@Override
|
||||
public BlockPosition adjustSpawnLocation(WorldServer worldserver, BlockPosition blockposition) {
|
||||
AxisAlignedBB axisalignedbb = this.getDimensions(EntityPose.STANDING).makeBoundingBox(Vec3D.ZERO);
|
||||
@ -328,7 +328,15 @@
|
||||
public void setExperiencePoints(int i) {
|
||||
float f = (float) this.getXpNeededForNextLevel();
|
||||
float f1 = (f - 1.0F) / f;
|
||||
@@ -744,6 +907,11 @@
|
||||
@@ -714,6 +877,7 @@
|
||||
public void initMenu(Container container) {
|
||||
container.addSlotListener(this.containerListener);
|
||||
container.setSynchronizer(this.containerSynchronizer);
|
||||
+ container.startOpen(); // CraftBukkit - don't force startOpen until container actually opens
|
||||
}
|
||||
|
||||
public void initInventoryMenu() {
|
||||
@@ -744,6 +908,11 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@ -340,7 +348,7 @@
|
||||
this.tickClientLoadTimeout();
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
@@ -820,7 +988,7 @@
|
||||
@@ -820,7 +989,7 @@
|
||||
}
|
||||
|
||||
if (this.getHealth() != this.lastSentHealth || this.lastSentFood != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) {
|
||||
@ -349,7 +357,7 @@
|
||||
this.lastSentHealth = this.getHealth();
|
||||
this.lastSentFood = this.foodData.getFoodLevel();
|
||||
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
||||
@@ -851,6 +1019,12 @@
|
||||
@@ -851,6 +1020,12 @@
|
||||
this.updateScoreForCriteria(IScoreboardCriteria.EXPERIENCE, MathHelper.ceil((float) this.lastRecordedExperience));
|
||||
}
|
||||
|
||||
@ -362,7 +370,7 @@
|
||||
if (this.experienceLevel != this.lastRecordedLevel) {
|
||||
this.lastRecordedLevel = this.experienceLevel;
|
||||
this.updateScoreForCriteria(IScoreboardCriteria.LEVEL, MathHelper.ceil((float) this.lastRecordedLevel));
|
||||
@@ -865,6 +1039,20 @@
|
||||
@@ -865,6 +1040,20 @@
|
||||
CriterionTriggers.LOCATION.trigger(this);
|
||||
}
|
||||
|
||||
@ -383,7 +391,7 @@
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking player");
|
||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.addCategory("Player being ticked");
|
||||
@@ -893,7 +1081,7 @@
|
||||
@@ -893,7 +1082,7 @@
|
||||
if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
if (this.getHealth() < this.getMaxHealth()) {
|
||||
@ -392,7 +400,7 @@
|
||||
}
|
||||
|
||||
float f = this.foodData.getSaturationLevel();
|
||||
@@ -946,7 +1134,8 @@
|
||||
@@ -946,7 +1135,8 @@
|
||||
}
|
||||
|
||||
private void updateScoreForCriteria(IScoreboardCriteria iscoreboardcriteria, int i) {
|
||||
@ -402,7 +410,7 @@
|
||||
scoreaccess.set(i);
|
||||
});
|
||||
}
|
||||
@@ -955,9 +1144,47 @@
|
||||
@@ -955,9 +1145,47 @@
|
||||
public void die(DamageSource damagesource) {
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
|
||||
@ -452,7 +460,7 @@
|
||||
|
||||
this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), ichatbasecomponent), PacketSendListener.exceptionallySend(() -> {
|
||||
boolean flag1 = true;
|
||||
@@ -988,12 +1215,18 @@
|
||||
@@ -988,12 +1216,18 @@
|
||||
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_FORGIVE_DEAD_PLAYERS)) {
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
@ -475,7 +483,7 @@
|
||||
EntityLiving entityliving = this.getKillCredit();
|
||||
|
||||
if (entityliving != null) {
|
||||
@@ -1028,10 +1261,12 @@
|
||||
@@ -1028,10 +1262,12 @@
|
||||
public void awardKillScore(Entity entity, DamageSource damagesource) {
|
||||
if (entity != this) {
|
||||
super.awardKillScore(entity, damagesource);
|
||||
@ -490,7 +498,7 @@
|
||||
} else {
|
||||
this.awardStat(StatisticList.MOB_KILLS);
|
||||
}
|
||||
@@ -1049,7 +1284,8 @@
|
||||
@@ -1049,7 +1285,8 @@
|
||||
int i = scoreboardteam.getColor().getId();
|
||||
|
||||
if (i >= 0 && i < aiscoreboardcriteria.length) {
|
||||
@ -500,7 +508,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1093,10 +1329,16 @@
|
||||
@@ -1093,10 +1330,16 @@
|
||||
}
|
||||
|
||||
private boolean isPvpAllowed() {
|
||||
@ -519,7 +527,7 @@
|
||||
BlockPosition blockposition = this.getRespawnPosition();
|
||||
float f = this.getRespawnAngle();
|
||||
boolean flag1 = this.isRespawnForced();
|
||||
@@ -1108,13 +1350,32 @@
|
||||
@@ -1108,13 +1351,32 @@
|
||||
if (optional.isPresent()) {
|
||||
EntityPlayer.RespawnPosAngle entityplayer_respawnposangle = (EntityPlayer.RespawnPosAngle) optional.get();
|
||||
|
||||
@ -555,7 +563,7 @@
|
||||
}
|
||||
|
||||
public static Optional<EntityPlayer.RespawnPosAngle> findRespawnAndUseSpawnBlock(WorldServer worldserver, BlockPosition blockposition, float f, boolean flag, boolean flag1) {
|
||||
@@ -1129,11 +1390,11 @@
|
||||
@@ -1129,11 +1391,11 @@
|
||||
}
|
||||
|
||||
return optional.map((vec3d) -> {
|
||||
@ -569,7 +577,7 @@
|
||||
});
|
||||
} else if (!flag) {
|
||||
return Optional.empty();
|
||||
@@ -1142,7 +1403,7 @@
|
||||
@@ -1142,7 +1404,7 @@
|
||||
IBlockData iblockdata1 = worldserver.getBlockState(blockposition.above());
|
||||
boolean flag3 = iblockdata1.getBlock().isPossibleToRespawnInThis(iblockdata1);
|
||||
|
||||
@ -578,7 +586,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,6 +1421,7 @@
|
||||
@@ -1160,6 +1422,7 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public EntityPlayer teleport(TeleportTransition teleporttransition) {
|
||||
@ -586,7 +594,7 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -1169,18 +1431,38 @@
|
||||
@@ -1169,18 +1432,38 @@
|
||||
|
||||
WorldServer worldserver = teleporttransition.newLevel();
|
||||
WorldServer worldserver1 = this.serverLevel();
|
||||
@ -628,7 +636,7 @@
|
||||
this.isChangingDimension = true;
|
||||
WorldData worlddata = worldserver.getLevelData();
|
||||
|
||||
@@ -1191,17 +1473,31 @@
|
||||
@@ -1191,17 +1474,31 @@
|
||||
playerlist.sendPlayerPermissionLevel(this);
|
||||
worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
|
||||
this.unsetRemoved();
|
||||
@ -662,7 +670,7 @@
|
||||
this.connection.resetPosition();
|
||||
worldserver.addDuringTeleport(this);
|
||||
gameprofilerfiller.pop();
|
||||
@@ -1215,11 +1511,29 @@
|
||||
@@ -1215,11 +1512,29 @@
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@ -692,7 +700,7 @@
|
||||
@Override
|
||||
public void forceSetRotation(float f, float f1) {
|
||||
this.connection.send(new ClientboundPlayerRotationPacket(f, f1));
|
||||
@@ -1228,13 +1542,21 @@
|
||||
@@ -1228,13 +1543,21 @@
|
||||
public void triggerDimensionChangeTriggers(WorldServer worldserver) {
|
||||
ResourceKey<World> resourcekey = worldserver.dimension();
|
||||
ResourceKey<World> resourcekey1 = this.level().dimension();
|
||||
@ -717,7 +725,7 @@
|
||||
this.enteredNetherPosition = null;
|
||||
}
|
||||
|
||||
@@ -1251,19 +1573,17 @@
|
||||
@@ -1251,19 +1574,17 @@
|
||||
this.containerMenu.broadcastChanges();
|
||||
}
|
||||
|
||||
@ -741,7 +749,7 @@
|
||||
if (this.level().isDay()) {
|
||||
return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW);
|
||||
} else {
|
||||
@@ -1280,7 +1600,36 @@
|
||||
@@ -1280,7 +1601,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -779,7 +787,7 @@
|
||||
this.awardStat(StatisticList.SLEEP_IN_BED);
|
||||
CriterionTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
@@ -1293,9 +1642,8 @@
|
||||
@@ -1293,9 +1643,8 @@
|
||||
return either;
|
||||
}
|
||||
}
|
||||
@ -790,7 +798,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1322,13 +1670,31 @@
|
||||
@@ -1322,13 +1671,31 @@
|
||||
|
||||
@Override
|
||||
public void stopSleepInBed(boolean flag, boolean flag1) {
|
||||
@ -823,7 +831,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1387,8 +1753,9 @@
|
||||
@@ -1387,8 +1754,9 @@
|
||||
this.connection.send(new PacketPlayOutOpenSignEditor(tileentitysign.getBlockPos(), flag));
|
||||
}
|
||||
|
||||
@ -834,7 +842,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1396,13 +1763,35 @@
|
||||
@@ -1396,13 +1764,35 @@
|
||||
if (itileinventory == null) {
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@ -870,7 +878,7 @@
|
||||
if (container == null) {
|
||||
if (this.isSpectator()) {
|
||||
this.displayClientMessage(IChatBaseComponent.translatable("container.spectatorCantOpen").withStyle(EnumChatFormat.RED), true);
|
||||
@@ -1410,9 +1799,11 @@
|
||||
@@ -1410,9 +1800,11 @@
|
||||
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@ -884,7 +892,7 @@
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
}
|
||||
}
|
||||
@@ -1425,15 +1816,26 @@
|
||||
@@ -1425,15 +1817,26 @@
|
||||
|
||||
@Override
|
||||
public void openHorseInventory(EntityHorseAbstract entityhorseabstract, IInventory iinventory) {
|
||||
@ -913,7 +921,7 @@
|
||||
this.initMenu(this.containerMenu);
|
||||
}
|
||||
|
||||
@@ -1456,6 +1858,7 @@
|
||||
@@ -1456,6 +1859,7 @@
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
@ -921,7 +929,7 @@
|
||||
this.connection.send(new PacketPlayOutCloseWindow(this.containerMenu.containerId));
|
||||
this.doCloseContainer();
|
||||
}
|
||||
@@ -1485,19 +1888,19 @@
|
||||
@@ -1485,19 +1889,19 @@
|
||||
i = Math.round((float) Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F);
|
||||
if (i > 0) {
|
||||
this.awardStat(StatisticList.SWIM_ONE_CM, i);
|
||||
@ -944,7 +952,7 @@
|
||||
}
|
||||
} else if (this.onClimbable()) {
|
||||
if (d1 > 0.0D) {
|
||||
@@ -1508,13 +1911,13 @@
|
||||
@@ -1508,13 +1912,13 @@
|
||||
if (i > 0) {
|
||||
if (this.isSprinting()) {
|
||||
this.awardStat(StatisticList.SPRINT_ONE_CM, i);
|
||||
@ -961,7 +969,7 @@
|
||||
}
|
||||
}
|
||||
} else if (this.isFallFlying()) {
|
||||
@@ -1557,7 +1960,7 @@
|
||||
@@ -1557,7 +1961,7 @@
|
||||
@Override
|
||||
public void awardStat(Statistic<?> statistic, int i) {
|
||||
this.stats.increment(this, statistic, i);
|
||||
@ -970,7 +978,7 @@
|
||||
scoreaccess.add(i);
|
||||
});
|
||||
}
|
||||
@@ -1565,7 +1968,7 @@
|
||||
@@ -1565,7 +1969,7 @@
|
||||
@Override
|
||||
public void resetStat(Statistic<?> statistic) {
|
||||
this.stats.setValue(this, statistic, 0);
|
||||
@ -979,7 +987,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1597,9 +2000,9 @@
|
||||
@@ -1597,9 +2001,9 @@
|
||||
super.jumpFromGround();
|
||||
this.awardStat(StatisticList.JUMP);
|
||||
if (this.isSprinting()) {
|
||||
@ -991,7 +999,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1625,6 +2028,7 @@
|
||||
@@ -1625,6 +2029,7 @@
|
||||
|
||||
public void resetSentInfo() {
|
||||
this.lastSentHealth = -1.0E8F;
|
||||
@ -999,7 +1007,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1661,7 +2065,7 @@
|
||||
@@ -1661,7 +2066,7 @@
|
||||
this.onUpdateAbilities();
|
||||
if (flag) {
|
||||
this.getAttributes().assignBaseValues(entityplayer.getAttributes());
|
||||
@ -1008,7 +1016,7 @@
|
||||
this.setHealth(entityplayer.getHealth());
|
||||
this.foodData = entityplayer.foodData;
|
||||
Iterator iterator = entityplayer.getActiveEffects().iterator();
|
||||
@@ -1669,7 +2073,7 @@
|
||||
@@ -1669,7 +2074,7 @@
|
||||
while (iterator.hasNext()) {
|
||||
MobEffect mobeffect = (MobEffect) iterator.next();
|
||||
|
||||
@ -1017,7 +1025,7 @@
|
||||
}
|
||||
|
||||
this.getInventory().replaceWith(entityplayer.getInventory());
|
||||
@@ -1680,7 +2084,7 @@
|
||||
@@ -1680,7 +2085,7 @@
|
||||
this.portalProcess = entityplayer.portalProcess;
|
||||
} else {
|
||||
this.getAttributes().assignBaseValues(entityplayer.getAttributes());
|
||||
@ -1026,7 +1034,7 @@
|
||||
if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || entityplayer.isSpectator()) {
|
||||
this.getInventory().replaceWith(entityplayer.getInventory());
|
||||
this.experienceLevel = entityplayer.experienceLevel;
|
||||
@@ -1696,7 +2100,7 @@
|
||||
@@ -1696,7 +2101,7 @@
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@ -1035,7 +1043,7 @@
|
||||
this.seenCredits = entityplayer.seenCredits;
|
||||
this.enteredNetherPosition = entityplayer.enteredNetherPosition;
|
||||
this.chunkTrackingView = entityplayer.chunkTrackingView;
|
||||
@@ -1752,7 +2156,7 @@
|
||||
@@ -1752,7 +2157,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1044,7 +1052,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, true);
|
||||
}
|
||||
@@ -1761,7 +2165,7 @@
|
||||
@@ -1761,7 +2166,7 @@
|
||||
this.setCamera(this);
|
||||
}
|
||||
|
||||
@ -1053,7 +1061,7 @@
|
||||
|
||||
if (flag1) {
|
||||
this.setYHeadRot(set.contains(Relative.Y_ROT) ? this.getYHeadRot() + f : f);
|
||||
@@ -1878,6 +2282,16 @@
|
||||
@@ -1878,6 +2283,16 @@
|
||||
}
|
||||
|
||||
public void updateOptions(ClientInformation clientinformation) {
|
||||
@ -1070,7 +1078,7 @@
|
||||
this.language = clientinformation.language();
|
||||
this.requestedViewDistance = clientinformation.viewDistance();
|
||||
this.chatVisibility = clientinformation.chatVisibility();
|
||||
@@ -1962,7 +2376,7 @@
|
||||
@@ -1962,7 +2377,7 @@
|
||||
if (world instanceof WorldServer) {
|
||||
WorldServer worldserver = (WorldServer) world;
|
||||
|
||||
@ -1079,7 +1087,7 @@
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
@@ -1999,11 +2413,11 @@
|
||||
@@ -1999,11 +2414,11 @@
|
||||
|
||||
@Nullable
|
||||
public IChatBaseComponent getTabListDisplayName() {
|
||||
@ -1093,7 +1101,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2046,6 +2460,32 @@
|
||||
@@ -2046,6 +2461,32 @@
|
||||
}
|
||||
|
||||
public void setRespawnPosition(ResourceKey<World> resourcekey, @Nullable BlockPosition blockposition, float f, boolean flag, boolean flag1) {
|
||||
@ -1126,7 +1134,7 @@
|
||||
if (blockposition != null) {
|
||||
boolean flag2 = blockposition.equals(this.respawnPosition) && resourcekey.equals(this.respawnDimension);
|
||||
|
||||
@@ -2088,12 +2528,38 @@
|
||||
@@ -2088,12 +2529,38 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1166,7 +1174,7 @@
|
||||
this.level().addFreshEntity(entityitem);
|
||||
ItemStack itemstack1 = entityitem.getItem();
|
||||
|
||||
@@ -2375,10 +2841,12 @@
|
||||
@@ -2375,10 +2842,12 @@
|
||||
return TicketType.ENDER_PEARL.timeout();
|
||||
}
|
||||
|
||||
@ -1182,7 +1190,7 @@
|
||||
}
|
||||
|
||||
private static float calculateLookAtYaw(Vec3D vec3d, BlockPosition blockposition) {
|
||||
@@ -2387,4 +2855,146 @@
|
||||
@@ -2387,4 +2856,146 @@
|
||||
return (float) MathHelper.wrapDegrees(MathHelper.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
public abstract class Container {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -67,6 +81,27 @@
|
||||
@@ -67,6 +81,28 @@
|
||||
private ContainerSynchronizer synchronizer;
|
||||
private boolean suppressRemoteUpdates;
|
||||
|
||||
@ -44,12 +44,13 @@
|
||||
+ Preconditions.checkState(this.title == null, "Title already set");
|
||||
+ this.title = title;
|
||||
+ }
|
||||
+ public void startOpen() {}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
protected Container(@Nullable Containers<?> containers, int i) {
|
||||
this.carried = ItemStack.EMPTY;
|
||||
this.remoteSlots = NonNullList.create();
|
||||
@@ -192,6 +227,15 @@
|
||||
@@ -192,6 +228,15 @@
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +66,7 @@
|
||||
public void removeSlotListener(ICrafting icrafting) {
|
||||
this.containerListeners.remove(icrafting);
|
||||
}
|
||||
@@ -417,7 +461,7 @@
|
||||
@@ -417,7 +462,7 @@
|
||||
}
|
||||
} else if (this.quickcraftStatus == 2) {
|
||||
if (!this.quickcraftSlots.isEmpty()) {
|
||||
@ -74,7 +75,7 @@
|
||||
k = ((Slot) this.quickcraftSlots.iterator().next()).index;
|
||||
this.resetQuickCraft();
|
||||
this.doClick(k, this.quickcraftType, InventoryClickType.PICKUP, entityhuman);
|
||||
@@ -433,6 +477,7 @@
|
||||
@@ -433,6 +478,7 @@
|
||||
l = this.getCarried().getCount();
|
||||
Iterator iterator = this.quickcraftSlots.iterator();
|
||||
|
||||
@ -82,7 +83,7 @@
|
||||
while (iterator.hasNext()) {
|
||||
Slot slot1 = (Slot) iterator.next();
|
||||
ItemStack itemstack2 = this.getCarried();
|
||||
@@ -443,12 +488,48 @@
|
||||
@@ -443,12 +489,48 @@
|
||||
int l1 = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemstack1) + j1, k1);
|
||||
|
||||
l -= l1 - j1;
|
||||
@ -134,7 +135,7 @@
|
||||
}
|
||||
|
||||
this.resetQuickCraft();
|
||||
@@ -466,8 +547,11 @@
|
||||
@@ -466,8 +548,11 @@
|
||||
if (i == -999) {
|
||||
if (!this.getCarried().isEmpty()) {
|
||||
if (clickaction == ClickAction.PRIMARY) {
|
||||
@ -147,7 +148,7 @@
|
||||
} else {
|
||||
entityhuman.drop(this.getCarried().split(1), true);
|
||||
}
|
||||
@@ -530,6 +614,15 @@
|
||||
@@ -530,6 +615,15 @@
|
||||
}
|
||||
|
||||
slot.setChanged();
|
||||
@ -163,7 +164,7 @@
|
||||
}
|
||||
} else {
|
||||
int j2;
|
||||
@@ -662,8 +755,9 @@
|
||||
@@ -662,8 +756,9 @@
|
||||
ItemStack itemstack = this.getCarried();
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
@ -174,7 +175,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -893,6 +987,11 @@
|
||||
@@ -893,6 +988,11 @@
|
||||
}
|
||||
|
||||
public ItemStack getCarried() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/ContainerChest.java
|
||||
+++ b/net/minecraft/world/inventory/ContainerChest.java
|
||||
@@ -6,10 +6,39 @@
|
||||
@@ -6,10 +6,44 @@
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@ -36,21 +36,28 @@
|
||||
+ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
|
||||
+ return bukkitEntity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void startOpen() {
|
||||
+ this.container.startOpen(this.player.player);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
private ContainerChest(Containers<?> containers, int i, PlayerInventory playerinventory, int j) {
|
||||
this(containers, i, playerinventory, new InventorySubcontainer(9 * j), j);
|
||||
@@ -53,6 +82,9 @@
|
||||
@@ -52,7 +86,10 @@
|
||||
checkContainerSize(iinventory, j * 9);
|
||||
this.container = iinventory;
|
||||
this.containerRows = j;
|
||||
iinventory.startOpen(playerinventory.player);
|
||||
- iinventory.startOpen(playerinventory.player);
|
||||
+ // iinventory.startOpen(playerinventory.player); // CraftBukkit - don't startOpen until menu actually opens
|
||||
+ // CraftBukkit start - Save player
|
||||
+ this.player = playerinventory;
|
||||
+ // CraftBukkit end
|
||||
boolean flag = true;
|
||||
|
||||
this.addChestGrid(iinventory, 8, 18);
|
||||
@@ -72,6 +104,7 @@
|
||||
@@ -72,6 +109,7 @@
|
||||
|
||||
@Override
|
||||
public boolean stillValid(EntityHuman entityhuman) {
|
||||
|
@ -37,7 +37,15 @@
|
||||
this.addStandardInventorySlots(playerinventory, 108, 84);
|
||||
}
|
||||
|
||||
@@ -143,7 +159,7 @@
|
||||
@@ -62,6 +78,7 @@
|
||||
|
||||
@Override
|
||||
public boolean stillValid(EntityHuman entityhuman) {
|
||||
+ if (!checkReachable) return true; // CraftBukkit - checkReachable
|
||||
return this.trader.stillValid(entityhuman);
|
||||
}
|
||||
|
||||
@@ -143,7 +160,7 @@
|
||||
}
|
||||
|
||||
private void playTradeSound() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/ContainerShulkerBox.java
|
||||
+++ b/net/minecraft/world/inventory/ContainerShulkerBox.java
|
||||
@@ -6,10 +6,29 @@
|
||||
@@ -6,10 +6,34 @@
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@ -26,19 +26,26 @@
|
||||
+ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new CraftInventory(this.container), this);
|
||||
+ return bukkitEntity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void startOpen() {
|
||||
+ container.startOpen(player.player);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
public ContainerShulkerBox(int i, PlayerInventory playerinventory) {
|
||||
this(i, playerinventory, new InventorySubcontainer(27));
|
||||
@@ -19,6 +38,7 @@
|
||||
@@ -19,7 +43,8 @@
|
||||
super(Containers.SHULKER_BOX, i);
|
||||
checkContainerSize(iinventory, 27);
|
||||
this.container = iinventory;
|
||||
- iinventory.startOpen(playerinventory.player);
|
||||
+ this.player = playerinventory; // CraftBukkit - save player
|
||||
iinventory.startOpen(playerinventory.player);
|
||||
+ // iinventory.startOpen(playerinventory.player); // CraftBukkit - don't startOpen until menu actually opens
|
||||
boolean flag = true;
|
||||
boolean flag1 = true;
|
||||
@@ -34,6 +54,7 @@
|
||||
|
||||
@@ -34,6 +59,7 @@
|
||||
|
||||
@Override
|
||||
public boolean stillValid(EntityHuman entityhuman) {
|
||||
|
@ -1,6 +1,11 @@
|
||||
--- a/net/minecraft/world/level/block/BlockChest.java
|
||||
+++ b/net/minecraft/world/level/block/BlockChest.java
|
||||
@@ -91,24 +91,7 @@
|
||||
@@ -87,28 +87,11 @@
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
- private static final DoubleBlockFinder.Combiner<TileEntityChest, Optional<ITileInventory>> MENU_PROVIDER_COMBINER = new DoubleBlockFinder.Combiner<TileEntityChest, Optional<ITileInventory>>() {
|
||||
+ public static final DoubleBlockFinder.Combiner<TileEntityChest, Optional<ITileInventory>> MENU_PROVIDER_COMBINER = new DoubleBlockFinder.Combiner<TileEntityChest, Optional<ITileInventory>>() { // PAIL private -> public
|
||||
public Optional<ITileInventory> acceptDouble(final TileEntityChest tileentitychest, final TileEntityChest tileentitychest1) {
|
||||
final InventoryLargeChest inventorylargechest = new InventoryLargeChest(tileentitychest, tileentitychest1);
|
||||
|
||||
|
@ -22,6 +22,7 @@ import net.minecraft.world.entity.EnumMainHand;
|
||||
import net.minecraft.world.entity.player.EntityHuman;
|
||||
import net.minecraft.world.entity.projectile.EntityFireworks;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerMerchant;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.item.ItemCooldown;
|
||||
import net.minecraft.world.item.crafting.CraftingManager;
|
||||
@ -49,6 +50,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMerchantCustom;
|
||||
import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.util.CraftMenus;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.Firework;
|
||||
@ -403,6 +405,11 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
// Now open the window
|
||||
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory());
|
||||
// we can open these now delegeate for now
|
||||
if (windowType == Containers.MERCHANT) {
|
||||
CraftMenus.openMerchantMenu(player, (ContainerMerchant) container);
|
||||
return;
|
||||
}
|
||||
String title = inventory.getTitle();
|
||||
player.connection.send(new PacketPlayOutOpenWindow(container.containerId, windowType, CraftChatMessage.fromString(title)[0]));
|
||||
player.containerMenu = container;
|
||||
|
@ -127,7 +127,7 @@ public class CraftContainer extends Container {
|
||||
if (menu == null) {
|
||||
return Containers.GENERIC_9x3;
|
||||
} else {
|
||||
return ((CraftMenuType<?>) menu).getHandle();
|
||||
return ((CraftMenuType<?, ?>) menu).getHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,25 @@
|
||||
package org.bukkit.craftbukkit.inventory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Suppliers;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.util.CraftMenus;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
||||
|
||||
public class CraftMenuType<V extends InventoryView> implements MenuType.Typed<V>, Handleable<Containers<?>> {
|
||||
public class CraftMenuType<V extends InventoryView, B extends InventoryViewBuilder<V>> implements MenuType.Typed<V, B>, Handleable<Containers<?>> {
|
||||
|
||||
private final NamespacedKey key;
|
||||
private final Containers<?> handle;
|
||||
private final Supplier<CraftMenus.MenuTypeData<V>> typeData;
|
||||
private final Supplier<CraftMenus.MenuTypeData<V, B>> typeData;
|
||||
|
||||
public CraftMenuType(NamespacedKey key, Containers<?> handle) {
|
||||
this.key = key;
|
||||
@ -38,28 +34,23 @@ public class CraftMenuType<V extends InventoryView> implements MenuType.Typed<V>
|
||||
|
||||
@Override
|
||||
public V create(final HumanEntity player, final String title) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof EntityPlayer, "The given player must be an EntityPlayer");
|
||||
final EntityPlayer serverPlayer = (EntityPlayer) craftHuman.getHandle();
|
||||
|
||||
final Container container = typeData.get().menuBuilder().build(serverPlayer, this.handle);
|
||||
container.setTitle(CraftChatMessage.fromString(title)[0]);
|
||||
container.checkReachable = false;
|
||||
return (V) container.getBukkitView();
|
||||
return builder().title(title).build(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Typed<InventoryView> typed() {
|
||||
public B builder() {
|
||||
return typeData.get().viewBuilder().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Typed<InventoryView, InventoryViewBuilder<InventoryView>> typed() {
|
||||
return this.typed(InventoryView.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V extends InventoryView> Typed<V> typed(Class<V> clazz) {
|
||||
public <V extends InventoryView, B extends InventoryViewBuilder<V>> Typed<V, B> typed(Class<V> clazz) {
|
||||
if (clazz.isAssignableFrom(typeData.get().viewClass())) {
|
||||
return (Typed<V>) this;
|
||||
return (Typed<V, B>) this;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Cannot type InventoryView " + this.key.toString() + " to InventoryView type " + clazz.getSimpleName());
|
||||
|
@ -1,38 +0,0 @@
|
||||
package org.bukkit.craftbukkit.inventory.util;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.ITileInventory;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerAccess;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
|
||||
public interface CraftMenuBuilder {
|
||||
|
||||
Container build(EntityPlayer player, Containers<?> type);
|
||||
|
||||
static CraftMenuBuilder worldAccess(LocationBoundContainerBuilder builder) {
|
||||
return (EntityPlayer player, Containers<?> type) -> {
|
||||
return builder.build(player.nextContainerCounter(), player.getInventory(), ContainerAccess.create(player.level(), player.blockPosition()));
|
||||
};
|
||||
}
|
||||
|
||||
static CraftMenuBuilder tileEntity(TileEntityObjectBuilder objectBuilder, Block block) {
|
||||
return (EntityPlayer player, Containers<?> type) -> {
|
||||
return objectBuilder.build(player.blockPosition(), block.defaultBlockState()).createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
};
|
||||
}
|
||||
|
||||
interface TileEntityObjectBuilder {
|
||||
|
||||
ITileInventory build(BlockPosition blockPosition, IBlockData blockData);
|
||||
}
|
||||
|
||||
interface LocationBoundContainerBuilder {
|
||||
|
||||
Container build(int syncId, PlayerInventory inventory, ContainerAccess access);
|
||||
}
|
||||
}
|
@ -1,15 +1,20 @@
|
||||
package org.bukkit.craftbukkit.inventory.util;
|
||||
|
||||
import static org.bukkit.craftbukkit.inventory.util.CraftMenuBuilder.*;
|
||||
import net.minecraft.network.chat.IChatBaseComponent;
|
||||
import net.minecraft.world.TileInventory;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutOpenWindow;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.entity.npc.EntityVillager;
|
||||
import net.minecraft.world.inventory.ContainerAnvil;
|
||||
import net.minecraft.world.inventory.ContainerCartography;
|
||||
import net.minecraft.world.inventory.ContainerEnchantTable;
|
||||
import net.minecraft.world.inventory.ContainerGrindstone;
|
||||
import net.minecraft.world.inventory.ContainerMerchant;
|
||||
import net.minecraft.world.inventory.ContainerSmithing;
|
||||
import net.minecraft.world.inventory.ContainerStonecutter;
|
||||
import net.minecraft.world.inventory.ContainerWorkbench;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.item.trading.IMerchant;
|
||||
import net.minecraft.world.item.trading.MerchantRecipeList;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.CrafterBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.TileEntityBeacon;
|
||||
@ -21,6 +26,12 @@ import net.minecraft.world.level.block.entity.TileEntityHopper;
|
||||
import net.minecraft.world.level.block.entity.TileEntityLectern;
|
||||
import net.minecraft.world.level.block.entity.TileEntitySmoker;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMenuType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMerchant;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftAccessLocationInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftBlockEntityInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftDoubleChestInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftMerchantInventoryViewBuilder;
|
||||
import org.bukkit.craftbukkit.inventory.view.builder.CraftStandardInventoryViewBuilder;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.bukkit.inventory.view.AnvilView;
|
||||
@ -33,83 +44,110 @@ import org.bukkit.inventory.view.LecternView;
|
||||
import org.bukkit.inventory.view.LoomView;
|
||||
import org.bukkit.inventory.view.MerchantView;
|
||||
import org.bukkit.inventory.view.StonecutterView;
|
||||
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
||||
|
||||
public final class CraftMenus {
|
||||
|
||||
public record MenuTypeData<V extends InventoryView>(Class<V> viewClass, CraftMenuBuilder menuBuilder) {
|
||||
public record MenuTypeData<V extends InventoryView, B extends InventoryViewBuilder<V>>(Class<V> viewClass, Supplier<B> viewBuilder) {
|
||||
}
|
||||
|
||||
private static final CraftMenuBuilder STANDARD = (player, menuType) -> menuType.create(player.nextContainerCounter(), player.getInventory());
|
||||
// This is a temporary measure that will likely be removed with the rewrite of HumanEntity#open[] methods
|
||||
public static void openMerchantMenu(EntityPlayer player, ContainerMerchant merchant) {
|
||||
final IMerchant minecraftMerchant = ((CraftMerchant) merchant.getBukkitView().getMerchant()).getMerchant();
|
||||
int level = 1;
|
||||
if (minecraftMerchant instanceof EntityVillager villager) {
|
||||
level = villager.getVillagerData().getLevel();
|
||||
}
|
||||
minecraftMerchant.setTradingPlayer(player);
|
||||
|
||||
public static <V extends InventoryView> MenuTypeData<V> getMenuTypeData(CraftMenuType<?> menuType) {
|
||||
player.connection.send(new PacketPlayOutOpenWindow(merchant.containerId, Containers.MERCHANT, merchant.getTitle()));
|
||||
player.containerMenu = merchant;
|
||||
player.initMenu(merchant);
|
||||
// Copy IMerchant#openTradingScreen
|
||||
MerchantRecipeList merchantrecipelist = minecraftMerchant.getOffers();
|
||||
|
||||
if (!merchantrecipelist.isEmpty()) {
|
||||
player.sendMerchantOffers(merchant.containerId, merchantrecipelist, level, minecraftMerchant.getVillagerXp(), minecraftMerchant.showProgressBar(), minecraftMerchant.canRestock());
|
||||
}
|
||||
// End Copy IMerchant#openTradingScreen
|
||||
}
|
||||
|
||||
public static <V extends InventoryView, B extends InventoryViewBuilder<V>> MenuTypeData<V, B> getMenuTypeData(CraftMenuType<?, ?> menuType) {
|
||||
final Containers<?> handle = menuType.getHandle();
|
||||
// this sucks horribly but it should work for now
|
||||
if (menuType == MenuType.GENERIC_9X6) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
if (menuType == MenuType.GENERIC_9X3) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, null)));
|
||||
}
|
||||
// this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9
|
||||
// this needs to be removed when inventory creation is overhauled
|
||||
if (menuType == MenuType.GENERIC_3X3) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, tileEntity(TileEntityDispenser::new, Blocks.DISPENSER)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.DISPENSER, TileEntityDispenser::new)));
|
||||
}
|
||||
if (menuType == MenuType.CRAFTER_3X3) {
|
||||
return asType(new MenuTypeData<>(CrafterView.class, tileEntity(CrafterBlockEntity::new, Blocks.CRAFTER)));
|
||||
return asType(new MenuTypeData<>(CrafterView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CRAFTER, CrafterBlockEntity::new)));
|
||||
}
|
||||
if (menuType == MenuType.ANVIL) {
|
||||
return asType(new MenuTypeData<>(AnvilView.class, worldAccess(ContainerAnvil::new)));
|
||||
return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerAnvil::new)));
|
||||
}
|
||||
if (menuType == MenuType.BEACON) {
|
||||
return asType(new MenuTypeData<>(BeaconView.class, tileEntity(TileEntityBeacon::new, Blocks.BEACON)));
|
||||
return asType(new MenuTypeData<>(BeaconView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BEACON, TileEntityBeacon::new)));
|
||||
}
|
||||
if (menuType == MenuType.BLAST_FURNACE) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntityBlastFurnace::new, Blocks.BLAST_FURNACE)));
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BLAST_FURNACE, TileEntityBlastFurnace::new)));
|
||||
}
|
||||
if (menuType == MenuType.BREWING_STAND) {
|
||||
return asType(new MenuTypeData<>(BrewingStandView.class, tileEntity(TileEntityBrewingStand::new, Blocks.BREWING_STAND)));
|
||||
return asType(new MenuTypeData<>(BrewingStandView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BREWING_STAND, TileEntityBrewingStand::new)));
|
||||
}
|
||||
if (menuType == MenuType.CRAFTING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerWorkbench::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerWorkbench::new)));
|
||||
}
|
||||
if (menuType == MenuType.ENCHANTMENT) {
|
||||
return asType(new MenuTypeData<>(EnchantmentView.class, (player, type) -> {
|
||||
return new TileInventory((syncId, inventory, human) -> {
|
||||
return worldAccess(ContainerEnchantTable::new).build(player, type);
|
||||
}, IChatBaseComponent.empty()).createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}));
|
||||
return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerEnchantTable::new)));
|
||||
}
|
||||
if (menuType == MenuType.FURNACE) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntityFurnaceFurnace::new, Blocks.FURNACE)));
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.FURNACE, TileEntityFurnaceFurnace::new)));
|
||||
}
|
||||
if (menuType == MenuType.GRINDSTONE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerGrindstone::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerGrindstone::new)));
|
||||
}
|
||||
// We really don't need to be creating a tile entity for hopper but currently InventoryType doesn't have capacity
|
||||
// to understand otherwise
|
||||
if (menuType == MenuType.HOPPER) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, tileEntity(TileEntityHopper::new, Blocks.HOPPER)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.HOPPER, TileEntityHopper::new)));
|
||||
}
|
||||
// We also don't need to create a tile entity for lectern, but again InventoryType isn't smart enough to know any better
|
||||
if (menuType == MenuType.LECTERN) {
|
||||
return asType(new MenuTypeData<>(LecternView.class, tileEntity(TileEntityLectern::new, Blocks.LECTERN)));
|
||||
return asType(new MenuTypeData<>(LecternView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.LECTERN, TileEntityLectern::new)));
|
||||
}
|
||||
if (menuType == MenuType.LOOM) {
|
||||
return asType(new MenuTypeData<>(LoomView.class, STANDARD));
|
||||
return asType(new MenuTypeData<>(LoomView.class, () -> new CraftStandardInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
if (menuType == MenuType.MERCHANT) {
|
||||
return asType(new MenuTypeData<>(MerchantView.class, STANDARD));
|
||||
return asType(new MenuTypeData<>(MerchantView.class, () -> new CraftMerchantInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
if (menuType == MenuType.SHULKER_BOX) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SHULKER_BOX, null)));
|
||||
}
|
||||
if (menuType == MenuType.SMITHING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerSmithing::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerSmithing::new)));
|
||||
}
|
||||
if (menuType == MenuType.SMOKER) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntitySmoker::new, Blocks.SMOKER)));
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SMOKER, TileEntitySmoker::new)));
|
||||
}
|
||||
if (menuType == MenuType.CARTOGRAPHY_TABLE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerCartography::new)));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerCartography::new)));
|
||||
}
|
||||
if (menuType == MenuType.STONECUTTER) {
|
||||
return asType(new MenuTypeData<>(StonecutterView.class, worldAccess(ContainerStonecutter::new)));
|
||||
return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, ContainerStonecutter::new)));
|
||||
}
|
||||
|
||||
return asType(new MenuTypeData<>(InventoryView.class, STANDARD));
|
||||
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftStandardInventoryViewBuilder<>(handle)));
|
||||
}
|
||||
|
||||
private static <V extends InventoryView> MenuTypeData<V> asType(MenuTypeData<?> data) {
|
||||
return (MenuTypeData<V>) data;
|
||||
private static <V extends InventoryView, B extends InventoryViewBuilder<V>> MenuTypeData<V, B> asType(MenuTypeData<?, ?> data) {
|
||||
return (MenuTypeData<V, B>) data;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class CraftAbstractInventoryViewBuilder<V extends InventoryView> implements InventoryViewBuilder<V> {
|
||||
|
||||
protected final Containers<?> handle;
|
||||
|
||||
protected boolean checkReachable = false;
|
||||
protected String title = null;
|
||||
|
||||
public CraftAbstractInventoryViewBuilder(Containers<?> handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InventoryViewBuilder<V> title(@NotNull final String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V build(final HumanEntity player) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(this.title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof EntityPlayer, "The given player must be an EntityPlayer");
|
||||
final EntityPlayer serverPlayer = (EntityPlayer) craftHuman.getHandle();
|
||||
final Container container = buildContainer(serverPlayer);
|
||||
container.checkReachable = this.checkReachable;
|
||||
container.setTitle(CraftChatMessage.fromString(title)[0]);
|
||||
return (V) container.getBukkitView();
|
||||
}
|
||||
|
||||
protected abstract Container buildContainer(EntityPlayer player);
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.level.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
|
||||
public abstract class CraftAbstractLocationInventoryViewBuilder<V extends InventoryView> extends CraftAbstractInventoryViewBuilder<V> implements LocationInventoryViewBuilder<V> {
|
||||
|
||||
protected World world;
|
||||
protected BlockPosition position;
|
||||
|
||||
public CraftAbstractLocationInventoryViewBuilder(final Containers<?> handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> checkReachable(final boolean checkReachable) {
|
||||
super.checkReachable = checkReachable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> location(final Location location) {
|
||||
Preconditions.checkArgument(location != null, "The provided location must not be null");
|
||||
Preconditions.checkArgument(location.getWorld() != null, "The provided location must be associated with a world");
|
||||
this.world = ((CraftWorld) location.getWorld()).getHandle();
|
||||
this.position = CraftLocation.toBlockPosition(location);
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerAccess;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
|
||||
public class CraftAccessLocationInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
private final CraftAccessContainerObjectBuilder containerBuilder;
|
||||
|
||||
public CraftAccessLocationInventoryViewBuilder(final Containers<?> handle, CraftAccessContainerObjectBuilder containerBuilder) {
|
||||
super(handle);
|
||||
this.containerBuilder = containerBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Container buildContainer(final EntityPlayer player) {
|
||||
ContainerAccess access;
|
||||
if (super.position == null) {
|
||||
access = ContainerAccess.create(player.level(), player.blockPosition());
|
||||
} else {
|
||||
access = ContainerAccess.create(super.world, super.position);
|
||||
}
|
||||
|
||||
return this.containerBuilder.build(player.nextContainerCounter(), player.getInventory(), access);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
CraftAccessLocationInventoryViewBuilder<V> copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.containerBuilder);
|
||||
copy.world = super.world;
|
||||
copy.position = super.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
copy.title = title;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public interface CraftAccessContainerObjectBuilder {
|
||||
|
||||
Container build(final int syncId, final PlayerInventory inventory, ContainerAccess access);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.ITileInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.inventory.ITileEntityContainer;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
|
||||
public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
private final Block block;
|
||||
private final CraftTileInventoryBuilder builder;
|
||||
|
||||
public CraftBlockEntityInventoryViewBuilder(final Containers<?> handle, final Block block, final CraftTileInventoryBuilder builder) {
|
||||
super(handle);
|
||||
this.block = block;
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Container buildContainer(final EntityPlayer player) {
|
||||
if (this.world == null) {
|
||||
this.world = player.level();
|
||||
}
|
||||
|
||||
if (this.position == null) {
|
||||
this.position = player.blockPosition();
|
||||
}
|
||||
|
||||
final TileEntity entity = this.world.getBlockEntity(position);
|
||||
if (!(entity instanceof ITileEntityContainer container)) {
|
||||
return buildFakeTile(player);
|
||||
}
|
||||
|
||||
final Container atBlock = container.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
if (atBlock.getType() != super.handle) {
|
||||
return buildFakeTile(player);
|
||||
}
|
||||
|
||||
return atBlock;
|
||||
}
|
||||
|
||||
private Container buildFakeTile(EntityPlayer player) {
|
||||
if (this.builder == null) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
final ITileInventory inventory = this.builder.build(this.position, this.block.defaultBlockState());
|
||||
if (inventory instanceof TileEntity tile) {
|
||||
tile.setLevel(this.world);
|
||||
}
|
||||
return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder);
|
||||
copy.world = this.world;
|
||||
copy.position = this.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
copy.title = title;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public interface CraftTileInventoryBuilder {
|
||||
|
||||
ITileInventory build(BlockPosition blockPosition, IBlockData blockData);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.ITileInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.level.block.BlockChest;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.DoubleBlockFinder;
|
||||
import net.minecraft.world.level.block.entity.TileEntityChest;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder;
|
||||
|
||||
public class CraftDoubleChestInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {
|
||||
|
||||
public CraftDoubleChestInventoryViewBuilder(final Containers<?> handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Container buildContainer(final EntityPlayer player) {
|
||||
if (super.world == null) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
||||
BlockChest chest = (BlockChest) Blocks.CHEST;
|
||||
final DoubleBlockFinder.Result<? extends TileEntityChest> result = chest.combine(super.world.getBlockState(super.position), super.world, super.position, false);
|
||||
if (result instanceof DoubleBlockFinder.Result.Single<? extends TileEntityChest>) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
||||
final ITileInventory combined = result.apply(BlockChest.MENU_PROVIDER_COMBINER).orElse(null);
|
||||
if (combined == null) {
|
||||
return handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
return combined.createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationInventoryViewBuilder<V> copy() {
|
||||
final CraftDoubleChestInventoryViewBuilder<V> copy = new CraftDoubleChestInventoryViewBuilder<>(super.handle);
|
||||
copy.world = this.world;
|
||||
copy.position = this.position;
|
||||
copy.checkReachable = super.checkReachable;
|
||||
copy.title = title;
|
||||
return copy;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerMerchant;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.item.trading.IMerchant;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMerchant;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMerchantCustom;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CraftMerchantInventoryViewBuilder<V extends InventoryView> extends CraftAbstractInventoryViewBuilder<V> implements MerchantInventoryViewBuilder<V> {
|
||||
|
||||
private IMerchant merchant;
|
||||
|
||||
public CraftMerchantInventoryViewBuilder(final Containers<?> handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantInventoryViewBuilder<V> merchant(final Merchant merchant) {
|
||||
this.merchant = ((CraftMerchant) merchant).getMerchant();
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MerchantInventoryViewBuilder<V> checkReachable(final boolean checkReachable) {
|
||||
super.checkReachable = checkReachable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V build(final HumanEntity player) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(this.title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof EntityPlayer, "The given player must be an EntityPlayer");
|
||||
final EntityPlayer serverPlayer = (EntityPlayer) craftHuman.getHandle();
|
||||
|
||||
final ContainerMerchant container;
|
||||
if (this.merchant == null) {
|
||||
container = new ContainerMerchant(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), new CraftMerchantCustom(title).getMerchant());
|
||||
} else {
|
||||
container = new ContainerMerchant(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant);
|
||||
}
|
||||
|
||||
container.checkReachable = super.checkReachable;
|
||||
container.setTitle(CraftChatMessage.fromString(title)[0]);
|
||||
return (V) container.getBukkitView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Container buildContainer(final EntityPlayer player) {
|
||||
throw new UnsupportedOperationException("buildContainer is not supported for CraftMerchantInventoryViewBuilder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantInventoryViewBuilder<V> copy() {
|
||||
CraftMerchantInventoryViewBuilder<V> copy = new CraftMerchantInventoryViewBuilder<>(super.handle);
|
||||
copy.checkReachable = super.checkReachable;
|
||||
copy.merchant = this.merchant;
|
||||
copy.title = title;
|
||||
return copy;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.bukkit.craftbukkit.inventory.view.builder;
|
||||
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.view.builder.InventoryViewBuilder;
|
||||
|
||||
public class CraftStandardInventoryViewBuilder<V extends InventoryView> extends CraftAbstractInventoryViewBuilder<V> {
|
||||
|
||||
public CraftStandardInventoryViewBuilder(final Containers<?> handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Container buildContainer(final EntityPlayer player) {
|
||||
return super.handle.create(player.nextContainerCounter(), player.getInventory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryViewBuilder<V> copy() {
|
||||
final CraftStandardInventoryViewBuilder<V> copy = new CraftStandardInventoryViewBuilder<>(handle);
|
||||
copy.title = this.title;
|
||||
return copy;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user