Compare commits

899 Commits
1.2.5 ... main

Author SHA1 Message Date
bendude56
a4805dbd77 Allow teleportation of entities on vehicles. Fixes BUKKIT-4210
Up until Minecraft version 1.5 it was not possible to teleport entities
within vehicles. With the 1.5 update came the change in the Minecraft
teleportation logic to dismount before teleporting the entity, if
applicable.

This commit ammends the existing CraftBukkit logic for rejecting
teleportation for entities in vehicles to permit the action. Due to this
change, CraftBukkit is now in-line with Minecraft 1.5 teleportation logic.
2014-08-17 11:49:27 -06:00
Jerom van der Sar
80e8f2ab87 Implement ability to keep items on death via plugins. Adds BUKKIT-5724
When a player dies their inventory is normally scattered over the the area
in which they died. Plugins should be able to modify this behaviour by
defining whether or not the player's inventory will be dropped on the ground or waiting for the player when they eventually respawn.

This commit implements the methods included in the Bukkit half for the new
behaviour by acting upon the boolean flag. The boolean flag is tested
prior to clearing the inventory as well as prior to dropping the items on
the ground. If the flag is true (indicating "keep inventory"), the items
are not removed from the player's inventory and are not dropped on the
ground.
2014-08-17 11:41:40 -06:00
Starbuck Johnson
3626720d53 Modify the invalid item set to permit command blocks. Fixes BUKKIT-4342
When using a "vanilla" Minecraft server using the "pick block" key on a
command block yields the invoker with a command block within their
inventory while in creative mode. Implications of the invalid items set
containing the command block also include having a "ghost" item that
cannot be placed due to it not actually existing.

This commit resolves the problem and brings Craftbukkit closer to vanilla
behaviour by removing the command block item ID, 137, from the invalid
items set.
2014-08-17 11:23:28 -06:00
myiume
4507cec090 Fix PlayerFishEvent not correctly cancelling. Fixes BUKKIT-5396
Prior to this commit cancelling the PlayerFishEvent would cause various
states of the fishing routine to be incorrectly or wrongly fired. This
incorrect behaviour was due to the miscommunication between the server and
client regarding the fishing state. When the event was cancelled, the
bobber entity was removed and caused the client to incorrectly determine
what the "next state" was to logically be.

This commit resolves the issue by ensuring the client is made aware of the
correct changes at the correct time regarding the bobber entity, therefore
keeping the logical steps of "fishing" proper and in-tact.
2014-08-17 00:17:02 -06:00
Wesley Wolfe
b3e83b00fc Implement deprecated methods. Adds BUKKIT-5752 2014-08-07 19:35:16 -05:00
Wesley Wolfe
1f0c791444 Use sensible AssertionError instead of ambiguous RuntimeException 2014-08-07 19:29:35 -05:00
ase34
87f6fa7bc9 Fix cancelling PlayerDropItemEvent. Fixes BUKKIT-3313
Up until this commit the PlayerDropItemEvent, if cancelled, would return
items to the first available slot in the inventory - which is clearly
undesirable as a player and plugin author to deal with.

This commit changes that by ensuring that the item is returned to where
it came from in the player's inventory. This still supports modifying the
drop from the player and will default to "first available slot" if the
item has changed since the event was fired. Other remaining behaviour of
the event is still in tact and has not been modified.
2014-08-04 12:27:50 -06:00
feildmaster
971329c42b Fix removal of items from Item Frames. Fixes BUKKIT-5736 2014-08-02 16:12:03 -05:00
Travis Watkins
594d7cb8c9 Don't confuse client with sound coordinates outside view distance. 2014-07-15 21:28:10 -05:00
Wesley Wolfe
c7398b9fdf Provide modifier functions to EntityDamageEvent. Fixes BUKKIT-5688 2014-07-13 00:07:38 -05:00
Travis Watkins
319a9c20eb Handle uniform block ids greater than 127. Fixes BUKKIT-5686 2014-07-10 19:19:48 -05:00
Travis Watkins
13482ac7f6 Put damage modifiers in Functions for event. Fixes BUKKIT-5681 2014-07-09 18:21:59 -05:00
Travis Watkins
dbb5e6e3cd Update CraftBukkit to Minecraft 1.7.10 2014-07-08 14:31:10 -05:00
Wesley Wolfe
a8628fd645 Use 4787c23dce0f5ac856d8d398225828971a93a3ff Guava patch for onlinePlayers
This change improves the quality of life for plugin developers using
iterator iteration with side-effects. In the specified Guava patch, the
internal iterator no longer relies on the AbstractList iterator which
iterates by index, and will instead wrap the provided iterator in a
transformer given the Function.
2014-07-01 00:48:07 -05:00
Wesley Wolfe
b602b5efa4 Implement new getOnlinePlayers. Adds BUKKIt-5668 2014-06-25 15:59:58 -05:00
t00thpick1
83e934b3bd [Bleeding] Fix checks for non-living entities. Fixes BUKKIT-5667 2014-06-24 18:24:29 -05:00
t00thpick1
9099e48e74 [Bleeding] Ignore damage done by LivingEntity.damage(). Fixes BUKKIT-5666
This matches behavior previous to new damage event API of not throwing
events for plugin-triggered damage.
2014-06-23 16:42:31 -05:00
Travis Watkins
6364f59ac4 Use compact memory format for uniform chunk section data.
Many chunk sections contain parts of their data that are the same for
every block they contain. In these cases we can save memory by saving
a single value instead of an array of 4096 copies of that value. Block light
and block data are most likely to be uniform followed closely by sky light
data. Block ids are far less likely to be uniform but give the largest
saving when they are. Because of this we use a compact format for every
part of the chunk. Memory saved from this technique will vary based on the
world but seems to be about 50% on normal Minecraft generated chunks.
2014-06-23 16:24:39 -05:00
t00thpick1
5adbab524d [Bleeding] Set projectile source for reflected fireballs. Fixes BUKKIT-5661 2014-06-22 16:52:52 -05:00
t00thpick1
6f21d3ca8f [Bleeding] Implement new damage api. Fixes BUKKIT-5326, BUKKIT-3878.
This commit centralizes event handling to where damage is actually applied
to the entity to avoid bugs that have resulted from nodamageticks,
modifications to damage after the event has been called, and similar
mishaps. This also implements new API for getting and setting of
modifications made to the damage amount actually applied to the entity.
This is done by storing the change in the damage amount as each modifier
is applied by vanilla code.

The method that actually damages the armor worn by an entity has been
relocated beneath the event called as to not apply durability loss when
the event has been cancelled.
2014-06-22 15:23:16 -05:00
t00thpick1
bed3f7f8f5 [Bleeding] Repair missing diff in Explosion. Fixes BUKKIT-5662
The blast protection enchantment dampers explosions, however
the functionality was only added to block explosions, and not
entity explosions.
2014-06-22 15:23:15 -05:00
Travis Watkins
5b9950b5f7 Avoid checking for loaded chunks for lighting and entity ticking.
When a chunk is loaded the server tries to ensure it has its initial light
calculations done before sending it to the player. When ticking entities
the server tries to ensure the entity does not walk into an unloaded chunk.
To accomplish these the server checks a one chunk radius around the chunk
to be lit or a two chunk radius around the chunk the entity is in. These
lookups happen every tick even though their result is unlikely to change
that often. To reduce the cost of these checks we replace them with a
system to keep track of what neighbor chunks a chunk has loaded and update
it when chunks load or unload which is a much less frequent action. On a
server with ten players this change removes about 100,000 calls a tick to
LongObjectHashMap's containsKey method.
2014-06-21 21:12:46 -05:00
Travis Watkins
ea126f98ad Don't check unload queue before ticking things anymore.
In commits 71a238ee and c8591397 we added checks while ticking to ensure
we never ticked anything in a chunk meant to be unloaded. We did this to
prevent these chunks being removed from the unload queue and leaked.
However, this causes a ridiculously large number of lookups on the queue
for a somewhat rare occurance. We also now have the chunk GC which will
take care of these leaked chunks when they do happen. With this in mind
we now remove these checks which removes almost all uses of the
LongHashSet backing the unload queue.
2014-06-21 21:03:00 -05:00
EvilSeph
e6a2feda20 Updated version to 1.7.9-R0.3-SNAPSHOT for development towards next release. 2014-06-01 02:36:02 -04:00
EvilSeph
080edc16be Updated version to 1.7.9-R0.2 in pom.xml for Beta. 2014-06-01 01:45:55 -04:00
bloodshot
1b48298d25 Add special case for handling place event with lilies. Fixes BUKKIT-5641 2014-06-01 00:23:06 -05:00
Travis Watkins
1c13d076af Improve ItemStack filtering. 2014-06-01 00:23:06 -05:00
Nate Mortensen
47b57e6bcf Some assumptions are better than others. 2014-06-01 00:22:58 -05:00
Daniel Naylor
0a45c3ebf7 Use UUIDs in CraftPlayer equals and hashCode methods. Fixes BUKKIT-5634 2014-05-26 19:45:07 -05:00
Travis Watkins
38fbe60d46 Handle null targets in target event. Fixes BUKKIT-5635 2014-05-26 19:34:45 -05:00
Nate Mortensen
3fbf4d3b5f Fix ItemStack state during BlockPlaceEvent. Fixes BUKKIT-5632 2014-05-26 17:54:51 -06:00
Travis Watkins
e080bafa58 Rework mob item dropping on death. Fixes BUKKIT-5625
After the changes in d611cff2 we started including a mob's equipment when
calling EntityDeathEvent so plugins can access this data. However, the
changes to enable this triggered a bug that makes skeletons and pig zombies
no longer drop equipment because they handle this differently than the rest.
On top of this we don't handle dropping equipment for mobs that cannot
pick up items in vanilla even though vanilla does drop equipment for them
if you summon them with it. We also do not include a horse's inventory
in the event so they drop their saddle, armor, chest, and chest contents
with no way for a plugin to control this.

To solve this issues we revert mob item dropping back to vanilla logic
and instead just capture all their drops in the method they all call to
spawn them into the world. We also move horse inventory dropping so it
happens at a time when we're capturing these drops. With these changes
all items mobs drop on death should now be included in the event and
we have less diff to worry about for future updates.
2014-05-26 18:42:47 -05:00
Wesley Wolfe
4ab4fa5bb1 Fix polarity of Bat.isAwake() and Bat.setAwake(boolean). Fixes BUKKIT-5624 2014-05-20 03:18:26 -05:00
EvilSeph
a1f3d35808 Updated version to 1.7.9-R0.2-SNAPSHOT for development towards next release. 2014-05-14 23:38:50 -04:00
EvilSeph
07a5465058 Updated version to 1.7.9-R0.1 in pom.xml for Beta. 2014-05-14 22:40:51 -04:00
Travis Watkins
89d5265da6 Ensure we always log commands and log the right thing.
Waiting to log until after PlayerCommandPreprocessEvent makes the server
not log anything if the event is cancelled. It also makes the server log
what a plugin changed the command to instead of what the player actually
tried to run. As the point of the log is to have a record of every command
a player attempts to run these are both not desirable.
2014-05-14 14:28:52 -05:00
Wesley Wolfe
fa1b6ba834 Update CraftBukkit to use new YamlConfiguration encoding changes 2014-05-14 05:49:04 -05:00
Wesley Wolfe
8daacb9017 Implement awake flag for bats. Adds BUKKIT-5606 2014-05-13 20:38:42 -05:00
Wesley Wolfe
730a62c96a Handle chat packets correctly 2014-05-13 20:13:16 -05:00
Travis Watkins
65a6e97785 Handle inventory max stack sizes even better. Fixes BUKKIT-5595
In 7e37cf96 we modified the container logic to handle custom max stack
sizes better and ensure the client stays in sync with this scenario. This
had the effect of sending an extra set slot packet for every inventory
click a player did which was not wanted. These extra packets also cause the
client to recalculate recipes which breaks the result slot for custom
recipes. To avoid the extra packets in general we now only send them if the
max stack is not the one we started with. In the case of a setting a custom
max stack size on a workbench this is still not enough so we also now send
another extra packet to make sure the result slot is always correct.
2014-05-13 00:01:23 -05:00
Travis Watkins
5610337b4f Only set skull profile if it is a player skull. Fixes BUKKIT-5605 2014-05-12 23:22:04 -05:00
Travis Watkins
690a908b97 Avoid using the user cache in skull meta.
To handle changes in 1.7.9 we changed skull meta to use GameProfile
instances instead of strings of player names. This reflects what vanilla is
actually storing for skulls now. As skulls still require a name our API was
not changed and we instead look up the rest of the profile information from
the name. The way this was implemented made it so that deserializing a skull
or setting its name potentially involved a network request. As skull meta
itself does not actually require a complete profile we now simply create one
that only contains a name and leave populating it to the server when it is
actually needed.
2014-05-03 17:49:59 -05:00
GJ
33e472229e [Bleeding] Fix stack overflow with Ender Crystals. Fixes BUKKIT-5583 2014-05-03 10:59:32 -05:00
eueln
2bf22a9c49 Implement inventory creation by type and title. Fixes BUKKIT-4045
With the current API it is possible to create an inventory with a specific
type, but it is not possible to give such an inventory a title other than
the default.

The commit changes that by adding a method to optionally supply the title
for the given inventory type and holder, creating the functionality to
display any supported inventory type with a 32 character length String.

If the inventory title supplied is larger than 32 characters then an
IllegalArgumentException is thrown stating so.
2014-04-30 22:50:58 -06:00
GJ
c3e4767a79 [Bleeding] Recheck persistence for chicken jockeys each tick. Fixes BUKKIT-5577 2014-04-29 17:29:07 -06:00
GJ
5195513866 [Bleeding] Include equipment in EntityDeathEvent loot. Fixes BUKKIT-5566 2014-04-29 17:28:47 -06:00
GJ
76e6277175 [Bleeding] Allow generation of cocoa trees. 2014-04-28 10:18:55 -04:00
GJ
d91ee7d7ab [Bleeding] Correct issues with MEGA_REDWOOD trees. Fixes BUKKIT-5568
In commit 6efeddfe57, TALL_REDWOOD was used instead of the proper TreeType
of MEGA_REDWOOD. Additionally, this fixes an issue in CraftWorld with an
improper boolean flag related to the generation of MEGA_REDWOOD trees.
2014-04-28 09:49:33 -04:00
bloodshot
576758bc55 Refactored BlockPlaceEvent and BlockChangeDelegate. Adds BUKKIT-5558
23 classes have been removed as they are no longer needed using the new
capture logic. This should help quite a bit with future MC updates.

BlockPlaceEvent Refactor

Before calling Item.interactWith, a recording flag is turned on for
setTypeAndData to capture a blockstate for each block that attempts to be set.
When a block place event is cancelled, the recorded blockstate, stack
size, and metadata will revert back to the captured state. If the event is
not cancelled, a notification will be sent to clients and block physics
will be updated.

BlockChangeDelegate Refactor

Now that we have the ability to capture blockstates through world, there
is no need to modify world gen classes with BlockChangeDelegate. Instead
we will simply capture blocks during world generation in order to "replay"
all of the captured blockstates to send back to delegates.
StructureGrowDelegate and BlockSapling.TreeGenerator have also been
removed as part of this change. BlockSapling and BlockMushroom will
capture blockstates the same as block placement and revert back any grow
events if needed.
2014-04-23 21:25:55 -06:00
Travis Watkins
de97b62b89 Don't limit anvil stack size.
After the changes in c549609d anvils started incorrectly limiting their
inputs to single item stacks. Vanilla allows for full size stacks here and
this is useful for using materials to repair items so now we do too.
2014-04-23 20:48:37 -05:00
Travis Watkins
5dfb74032c Handle inventory max stack sizes better. Fixes BUKKIT-5564
Make sure we check the inventory's max stack size where appropriate and
don't assume the inventory slot is able to take our entire stack just
because it is empty. We also ensure the client is updated with the correct
slot contents and cursor contents in cases where the max stack changes
result in different behavior than the client expected.
2014-04-23 20:48:32 -05:00
Yariv Livay
c99de378c6 Faux sleepers wake up normally. Fixes BUKKIT-3667 2014-04-18 13:24:28 -05:00
Andre LeBlanc
5d24f2b9c0 Make AnvilInventory.getItem() use both containers. Fixes BUKKIT-2788
The AnvilInventory reports its size as the sum of the ingredient and
result inventories, but when trying to access the slots, only the
ingredient inventory is used, leading to an ArrayIndexOutOfBounds exception.

This change overrides getItem(I) and setItem(I) to use both inventories,
with the slot number adjusted based on their size.
2014-04-18 13:21:21 -05:00
Andre LeBlanc
47367210f3 Allow plugins to enchant normally unenchantable items. Adds BUKKIT-1849
It's currently not possible for a plugin to allow enchanting of an
otherwise un-enchantable item using the enchanting table. This commit
causes EnchantItemEvent to be called with an empty list of enchantments,
allowing a plugin to provide it's own set of enchantments when vanilla
Minecraft would not allow any. It also bypasses the unsafe enchantment check
since a plugin should be permitted to apply any enchantments they like, and
vanilla should not generate unsafe enchantments of its own.
2014-04-18 13:13:01 -05:00
PaulBGD
941650b9b2 Fix setting entity's target. Fixes BUKKIT-1358
Setting the goal target overrides the entity's will to do something
else. This makes it so entities like wolves with attack another player
with .setTarget(), instead of hanging next to their owner.
2014-04-18 12:55:07 -05:00
bloodshot
4c9bf34bf3 Update client stack when block place is cancelled. Fixes BUKKIT-5284
Currently, whenever a player places a block in a protected area the
equipped itemstack size on client is never updated properly since the
client thinks the block was placed. The reason this happens is because
ItemStack.matches returns true since the server does not decrement stack
size if a BlockPlaceEvent is cancelled. To correct this on cancel we set
the flag to always update the client regardless of matching.
2014-04-18 12:52:13 -05:00
bloodshot
5c115116ef Update chest animation after cancelling open event. Fixes BUKKIT-1440
Currently if a plugin cancels an InventoryOpenEvent for vanilla chests,
the chest animation for clients is stuck in the open state since
IInventory's closeContainer method is never called. To fix the issue,
closeContainer is called before exiting the display GUI method.
2014-04-18 12:47:32 -05:00
Devin Ryan
d0be633ed9 Catch exceptions when abandoning conversions. Fixes BUKKIT-5436
If a conversation is abandoned due to a player disconnecting and an
exception is thrown in a ConversationAbandonedListener, the server will
crash. This commit prevents the exception from propagating further up
the stack and instead just logs the error.
2014-04-18 12:33:56 -05:00
Des Herriott
8a6ed3a88b Check that item in hand is not null after book event. Fixes BUKKIT-5443 2014-04-18 12:30:53 -05:00
Brokkonaut
a86bc7aeb3 Call event when boat is destroyed by falling. Fixes BUKKIT-5500 2014-04-18 12:25:41 -05:00
Brokkonaut
0092460086 Removing broken chunk caching from World. Fixes BUKKIT-5425
Chunk caching in the World class does not know about outdated cache values.
This caused various problems when accessing previously unloaded chunks. The
caching also did not improve the performance so it is removed.
Synchronization is also not necessary, because all accesses to getChunkAt
may only come from the main thread.
2014-04-18 12:17:48 -05:00
GJ
890a4af12f [Bleeding] Call EntityTargetEvent in many new places.
Adds BUKKIT-5388, BUKKIT-5387, BUKKIT-5386, BUKKIT-5483, BUKKIT-5484.
Fixes BUKKIT-5389.
2014-04-18 10:43:06 -05:00
GJ
3abba82315 Add files from mc-dev for diff visibility. 2014-04-18 10:42:54 -05:00
GJ
7df7778ccb [Bleeding] Call BlockRedstoneEvent for all rails. Adds BUKKIT-4080
Previously, Detector Rails were the only rails that properly called
BlockRedstoneEvent when they changed from powered to unpowered. This commit
adds BlockRedstoneEvent calls for both Powered Rails and Activator Rails.
2014-04-18 10:29:07 -05:00
GJ
610c58c733 Add BlockPoweredRail.java from mc-dev for diff visibility. 2014-04-18 10:28:58 -05:00
GJ
730adbbf42 [Bleeding] Don't allow null display names. Fixes BUKKIT-5254
Currently, plugins can set a player's display name to null, which could
cause issues for other calls to getDisplayName that aren't expecting a null
value. This changes setDisplayName to follow the same logic as
setPlayerListName, which sets the player's name back to their unmodified
"vanilla" name if it receives a null value as a parameter.
2014-04-18 10:21:33 -05:00
GJ
2a2cdd4885 [Bleeding] Ice in the nether fades to air. Fixes BUKKIT-5373
Previously, whenever BlockFadeEvent was called for ice melting, it returned
the new BlockState with a type of Material.STATIONARY_WATER. However, in
the Nether, ice melting does not form water, but is simply replaced by air
instead. This changes the event to use the proper BlockState based on
whether the block is located in the Nether or not.
2014-04-18 10:18:52 -05:00
GJ
0a179711aa [Bleeding] Fix some inventories not using maxStack. Fixes BUKKIT-2883
CraftBukkit adds the ability to specify the maxStack size for most
inventories. However, some inventories were not overriding the getMaxStack
method properly, and so the functionality was unavailable. This fixes the
maxStack setting for Anvils, Minecarts, PlayerInventory, and Hoppers.
2014-04-18 10:11:23 -05:00
GJ
a4fe7cd3c4 [Bleeding] Return correct player SlotType. Fixes BUKKIT-3188
Previously, the SlotType for the last 4 slots in a player's inventory
returned QUICKBAR when it should have returned SlotType.CONTAINER. This
updates the code for determining slot type to return the proper value.
2014-04-18 10:01:31 -05:00
GJ
9c251595d4 [Bleeding] Return correct furnace SlotType. Fixes BUKKIT-5400
Previously, the SlotType for the 0 slot in a furnace returned CONTAINER,
when it should have returned SlotType.CRAFTING. This updates the code for
determining slot type to return the proper value.
2014-04-18 10:01:24 -05:00
GJ
ec41228fb5 [Bleeding] Ensure skeletons spawn with equipment. Fixes BUKKIT-2836
Previously, when a skeleton was spawned via the spawn(...) function, the
resulting skeleton had no equipped bow and therefore could not properly
attack. This fix gives all skeletons the proper equipment and ensures that
they are able to attack.
2014-04-18 09:52:04 -05:00
GJ
81e560621f [Bleeding] Add all blocks needed to PortalCreateEvent. Fixes BUKKIT-5464
Due to changes in how portals were created in Minecraft 1.7, the code that
was previously used to find the blocks involved in the PortalCreateEvent
no longer detected all blocks. Additionally, in the process of updating to
1.7.2, a missed diff resulted in some blocks that were found not being
properly added to the blocklist. This commit corrects that missed diff,
while also adding a check to ensure that the top and bottom of the portal
frame are included in the blocklist.
2014-04-18 09:42:02 -05:00
GJ
729df1a734 [Bleeding] Add many missing SpawnReasons.
Adds BUKKIT-5370, BUKKIT-5377, BUKKIT-5378, BUKKIT-5379, BUKKIT-5380,
BUKKIT-5381, BUKKIT-5382. Adds reasons for zombies infecting villagers and
zombie villagers being cured. Readds reason for a skeleton being spawned as
a spider jockey. Adds reason to distinguish ocelot babies from the parent
they spawned with. Adds reasons for chunk generation causing the ender
dragon, villagers, and witches to spawn. And finally, adds a reason for
spawning a chicken mount for a baby zombie.
2014-04-18 09:34:08 -05:00
GJ
b6831792ec Add files from mc-dev for diff visibility. 2014-04-18 09:28:18 -05:00
GJ
d4fe10394a [Bleeding] Add many missing event calls. 2014-04-18 09:01:11 -05:00
GJ
286c71329d Add BlockTallPlant.java from mc-dev for diff visibility. 2014-04-18 09:01:04 -05:00
GJ
eb43d0637c [Bleeding] Add missing HangingBreakEvent. Fixes BUKKIT-3943
The old PaintingBreakByEntityEvent was deprecated and replaced by
HangingBreakByEntityEvent. However, in the case of being struck by
lightning, only the deprecated event was being called. This fixes that so
that both the new and old events are called appropriately.
2014-04-18 08:45:35 -05:00
Travis Watkins
a81f26716d Handle profiles in SkullMeta, they don't store a string anymore. 2014-04-17 14:09:53 -05:00
Nate Mortensen
7e54acc8bd Update CraftBukkit to Minecraft 1.7.9 2014-04-17 13:44:03 -05:00
Travis Watkins
98555224aa Handle expired bans correctly. Fixes BUKKIT-5541 2014-04-17 11:03:51 -05:00
Travis Watkins
3e911dba54 Make bans pretend to use names like before 1.7.8.
Bans require a name and UUID but our API only allows for a single string
identifier for a ban entry. Until this is sorted out go back to the old
name based setup since we can always get a UUID given a name.
2014-04-17 10:45:10 -05:00
Travis Watkins
a8d5c1224f Make skulls pretend to only use names like before 1.7.8.
Any new API here needs more thought, skulls require a name but OfflinePlayer
is not guaranteed to have one. There is a Mojang approved way to get a
complete profile from a name but not from a UUID so for now just pretend
this still only uses names.
2014-04-17 08:41:29 -05:00
Travis Watkins
6ad36f09e5 Fix getting white list, ban list, and op list. Fixes BUKKIT-5538
The getEntries methods on these return player names instead of UUIDs.
As we need the UUIDs for our API we add a getValues method to get at
the data we need. To further ensure we get the most data possible we
also add a way to get at the stored GameProfile to ensure we always
have both the UUID and the name from the list.
2014-04-17 03:31:49 -05:00
Travis Watkins
5cbbcae9a9 Import files from mc-dev for diff visibility 2014-04-17 03:17:55 -05:00
t00thpick1
dc194a97bb [Bleeding] Re-add missed diff in 1.7.5 update. Fixes BUKKIT-5536
In the 1.7.5 update the diff that called book edit events when editing
books was accidentally dropped because of nms changes within the file.
This commit re-adds the craftbukkit call to restore event behavior.
2014-04-17 02:17:25 -05:00
Travis Watkins
fc39b27d7c Don't do a lookup for obviously invalid usernames 2014-04-17 01:57:35 -05:00
Travis Watkins
5557856144 Add methods to use arbitrary entries in scoreboards. Adds BUKKIT-3977 2014-04-13 23:21:36 -05:00
Travis Watkins
3dcf159ec1 Fix missed diff and other small things 2014-04-13 04:29:21 -05:00
Travis Watkins
d82e34da59 Use world-container when finding players to convert. Fixes BUKKIT-5530 2014-04-13 00:13:42 -05:00
Travis Watkins
b689cfa83a Check actual whitelist for CraftOfflinePlayer too 2014-04-12 07:45:32 -05:00
Travis Watkins
f6a93775bf Check the actual whitelist for Player#isWhitelisted()
The server's check is for whether or not a player can pass the whitelist
not just if the player is on it. That seems like more useful information
but the API has always just checked if they are on it so this commit
restores that.
2014-04-12 07:21:01 -05:00
Travis Watkins
7b409ed4e9 Use fetched GameProfile for getOfflinePlayer(String)
When getting an OfflinePlayer by name we lookup their UUID and then
use that to fetch the OfflinePlayer. If the player has not played on
this server before the resulting OfflinePlayer will return null for
getName(). As this is unintuitive we now create the OfflinePlayer directly
using the profile we looked up and make OfflinePlayer prefer that data.
2014-04-12 03:12:26 -05:00
Travis Watkins
8f771c7378 Update CraftBukkit to Minecraft 1.7.8 2014-04-11 22:28:35 -05:00
Patrick Seidel
0df7555cec Add method to send fake sign updates to players. Adds BUKKIT-2300 2014-04-02 18:05:03 -05:00
BlackHole
903575ff2e Add player unique ID to (Async)PlayerPreLoginEvent. Adds BUKKIT-5108 2014-04-02 17:28:18 -05:00
Jeremy Wood
8d77687e7a Add equals for CraftInventory objects. Adds BUKKIT-4110
When working with inventories you regularly end up with different
Inventory objects that have the same underlying Minecraft inventory.
Currently, even those these point to the same thing, they are not
considered equal. With this commit comparing any Inventory object that
represents the same inventory will result in equals(Object) returning
true.
2014-04-02 17:26:11 -05:00
feildmaster
434f15c847 Store last known player names in preparation for name changing 2014-03-31 14:42:33 -05:00
Travis Watkins
21e7ba8d22 Implement API for dealing with player UUIDs. Adds BUKKIT-5071 2014-03-29 16:50:17 -05:00
Travis Watkins
acc9f20b00 Fix issues with leashes and weather due to missed diff 2014-03-26 04:39:39 -05:00
Travis Watkins
4992df25ec Correct missed diff 2014-03-24 15:22:15 -05:00
Nate Mortensen
d51463d162 Fix PotionEffect removal.
The method in EntityLiving to remove a potion effect was remapped during
the 1.7.5 update.  The method invocation in CraftLivingEntity was not
updated to invoke the remapped method, which has led to a random method in
LivingEntity being called in its place.

This commit corrects the behavior of removePotionEffect by changing the
method to invoke the remapped method as opposed to EntityLiving#m(float).

Thanks to @gabizou for finding this issue.
2014-03-23 21:25:14 -06:00
Travis Watkins
58267995eb Fix missed diff making horses lose their saddle 2014-03-22 22:52:03 -05:00
Travis Watkins
019a33f50d Fix teleport failing right after join. Fixes BUKKIT-5479
Teleporting a player checks to see if the player is disconnected to
try to avoid creating ghost players. The check it uses, however, randomly
fails when the player is in the middle of joining the server. The check
that would work correctly here does not work correctly when the player
actually disconnects. To work around this we add a new flag which is
cleared on the first tick of the new player and assume they are connected
if the flag is set.
2014-03-22 19:39:03 -05:00
WolfieMario
4873b12890 Increment loop index whether or not command succeeded. Fixes BUKKIT-5455
When VanillaCommandWrapper dispatches a command containing a
PlayerSelector wtih c>-1 (implicitly true for @a), it loops over the
selected players and exectures the command with each player. However, the
loop index is only incremented if the command fails. As a result, a
successful command is repeated on the same player indefinitely, locking up
the server. This commit fixes the issue by incrementing the loop index
regardless of whether the command succeeds, ensuring the command is only
executed once per player identified by the PlayerSelector.
2014-03-22 13:55:20 -06:00
Nate Mortensen
385ace970e Update CraftBukkit to Minecraft 1.7.5 2014-03-21 23:56:34 -04:00
Travis Watkins
afb3511a4a Remove chunks from queue if we don't need them anymore. 2014-02-12 02:05:12 -05:00
EvilSeph
f6f0cf338a Updated version to 1.7.2-R0.4-SNAPSHOT for development towards next release. 2014-02-12 01:59:10 -05:00
EvilSeph
081fe9c41b Updated version to 1.7.2-R0.3 in pom.xml for Beta. 2014-02-12 01:33:33 -05:00
EvilSeph
d9e04a5b24 Check if entity is in list before decrementing. Fixes BUKKIT-5404 2014-02-11 14:55:59 -05:00
EvilSeph
00b3721f07 Update/improve configuration documentation. 2014-02-11 00:49:07 -05:00
EvilSeph
9131f5b550 Ignore player selectors if not a Command Block. 2014-02-11 00:49:07 -05:00
EvilSeph
776e256ff1 Add PlayerSelector.java for diff visibility. 2014-02-11 00:49:06 -05:00
EvilSeph
8234570795 Rename Minecraft command permission nodes to meet fallback spec. 2014-02-11 00:48:39 -05:00
Travis Watkins
533c48996b Hide message from connection throttle on startup. Fixes BUKKIT-5403 2014-02-10 16:23:42 -06:00
Travis Watkins
393ece9ec5 Readd diff missed in the 1.7 update. 2014-02-10 15:43:56 -06:00
Travis Watkins
826643c606 Handle removing entity while ticking. Fixes BUKKIT-1331
If a plugin causes an entity to be removed from the world while the
world is ticking entities the ticking loop gets out of sync and fails due
to trying to go beyond the end of the entity array. To ensure this doesn't
happen we store the loop position as a field so we can fix it up in the
entity remove method just like the tick method does when it removes an
entity.
2014-02-10 15:43:49 -06:00
Wesley Wolfe
1113d54dae Add method to forget callbacks in AsynchronousExecutor 2014-02-10 09:33:20 -06:00
Aikar
ce4b13c1a5 Readd BlockPlaceEvent for half slab to full block. Fixes BUKKIT-5390 2014-02-09 02:40:43 -06:00
Travis Watkins
219f4e2c25 Match old alias behavior when migrating.
Previously the alias system would pass all arguments from the alias
to its command(s) implicitly. The new system requires arguments to be
explicitly passed so server owners can have more control over where and
how they are passed. To ensure this isn't a breaking change during the
migration from bukkit.yml to commands.yml we now add the $1- argument
to the alias commands to match the previous behavior.
2014-02-08 15:02:44 -06:00
t00thpick1
553acdf0cd [Bleeding] Implement Mojang command fallback system. Adds BUKKIT-5385 2014-02-08 03:17:14 -06:00
mbax
b18bedd848 Implement banning API. Adds BUKKIT-3535
Previously no implementation existed to access various additional
information fields regarding bans. This implementation expands on the
information outlined in the sister Bukkit commit to provide access to
the Minecraft implementation of the ban system.

This implementation of the banning API contains 2 new classes which
provide access to the internal workings of the built-in banning
system within Minecraft.

The CraftBanEntry class simply supports the representation of an internal
Minecraft BanEntry object. The data that may be modified within this new
object must be manually saved to the list contained within the
CraftBanEntry using it's save() method.

The CraftBanList class supports the representation of an internal
Minecraft BanList object through proxy methods. These methods do
validation on the passed objects where needed to ensure safe input to the
backed Minecraft objects.

These changes additionally re-route the existing banning API to the newer,
more detailed, system. Functionality prior to this change still behaves
as documented by the contract defined by the methods changed.
2014-02-08 00:03:14 -07:00
t00thpick1
66471a5326 [Bleeding] Correctly enchant books. Fixes BUKKIT-5302
Books can now recieve more than one enchantment.  As such, breaking out of
the loop after only 1 enchantment is applied is not the correct behavior.

This commit also reworks some of the logic surrounding the application of
enchantments to the item. By checking if the event doesn't add any
enchantments rather than if the original enchantments list is empty, the
application code is only reached if enchantments are applied, rendering
the "applied" boolean no longer necessary. The ItemStack's Item should only
be set once, so it is now set outside of the loop based upon whether or not
"flag" is true (with "flag" being whether or not the ItemStack's Item is a
book).
2014-02-06 16:49:10 -07:00
EdGruberman
068d8a807b Update clients when ItemFrame direction is set. Fixes BUKKIT-3371
Hanging entities are placed into the entity tracker and updates are sent
out to clients for the initial placement. Thereafter data watchers are
configured to monitor the item inside the frame. However, if the
direction the ItemFrame facing changes the entity tracker will not send
out updates.

This commit removes and recreates the ItemFrame entity in the same way
that was already done for Painting entities. This causes clients to
be updated appropriately.
2014-02-02 00:37:59 -07:00
Kodekpl
3e896afe6b Implement SpawnReason.NETHER_PORTAL and DISPENSE_EGG. Fixes BUKKIT-3148
Previously any entities spawned through dispensers (monster eggs) or
by nether portals were given the incorrect SpawnReason of SPAWNER_EGG.
This made it impossible to distinguish what exactly happened in regards
to the creature being spawned.

A method in ItemMonsterEgg has been added to further fine tune reasons
for spawning creatures. This permits the DISPENSE_EGG reason to be used
correctly and accuratly as well as the NETHER_PORTAL reason due to how
BlockPortal spawns the mobs.

The redirected method, a(World, int, double, double, double), is still
called by the ItemMonsterEgg itself and therefore uses the default reason
of SPAWNER_EGG. This does not change previous behaviour.
2014-02-01 22:29:15 -07:00
turt2live
c59ba98ae6 [Bleeding] Handle players disconnecting during respawn. Fixes BUKKIT-4327
Prior to this commit, a player disconnected during a respawn event would
remain in memory. This causes a ghosting issue of players in the slot
count and player list, as well as a reference leak.

This commit avoids re-adding the player to the player list (and world) if
they are disconnected. This ensures that the remainder of the respawn
logic is completed as well as ensuring a duplicate player is not left on
the server.

This commit also saves the player's file at the end of the method if they
have been disconnected to ensure that their next login is accurate to the
respawn event's actions. A player that was revived and disconnected will
reconnect as revived.
2014-02-01 22:52:01 -06:00
Travis Watkins
d7d81fa68f Load all already generated chunks via async chunk system
Currently we use the async chunk loading system only when players trigger
chunk loading. If a chunk is loaded for any other reason it goes through
a separate codepath. This means if a player has trigged a chunk load and
before the chunk loads something else wants the same chunk we will load it
twice and throw away the second result. With this change we instead use
the sync processing feature of the AsynchronousExecutor to load the chunk
which will pull it out of the queue if it was already queued to load. This
means we only ever load a chunk once. Because chunk generation is not
thread safe we still fallback to the vanilla chunk loading system if the
chunk does not currently exist.
2014-02-01 22:03:04 -06:00
Wesley Wolfe
4a6a81e724 Allow AsynchronousExecutor.getSkipQueue() to pull tasks from the queue 2014-02-01 17:57:52 -06:00
Travis Watkins
842962530a Don't call duplicate interact air events. Fixes BUKKIT-5359
Previously we attempted to call interact events in cases that were missing
by modifying the arm swing logic. This, however, was too broad and started
triggering events in cases we already covered leading to duplicates. Since
the only case we can handle cleanly and the primary point of the previous
fix was fluids we now instead simply treat fluids as air for this check.
This also ensures we do not get duplicate events when the player is in a
fluid and hits a normal block, unlike the previous change.

This reverts commit 68b702f7 and replaces it with a better fix.
2014-01-31 14:55:01 -06:00
t00thpick1
9907271071 [Bleeding] Store correct block type when hitting blocks. Fixes BUKKIT-5209
The block obtained and stored within the block object higher up does not
reflect the block at the location being hit, rather it is the air block
the arrow was previously in.  Thusly when the variable is used to check
if the arrow is still in the block, it fails.
2014-01-30 21:47:44 -07:00
t00thpick1
e0da846352 [Bleeding] Fix support for several entities in World.spawn(). Fixes BUKKIT-3284 2014-01-30 21:47:44 -07:00
t00thpick1
2fc5d59303 [Bleeding] Use correct yaw and pitch when spawning arrows. Fixes BUKKIT-3320 2014-01-30 21:47:44 -07:00
t00thpick1
b4c4c8ed78 [Bleeding] Directly set direction in EntityFireball. Fixes BUKKIT-1154
Because EntityFireball.setDirection() adds a random offset to passed
parameters, it is not appropriate for use in an API method. As such,
the values need to be directly set to remain accurate.
2014-01-30 21:47:44 -07:00
t00thpick1
1fa4b69bd8 [Bleeding] Implement setCharged and getCharged for WitherSkull. Addresses BUKKIT-3060 2014-01-30 21:47:44 -07:00
t00thpick1
8a5ad89a68 [Bleeding] Implement ProjectileSource API. Addresses BUKKIT-1038, BUKKIT-1156 2014-01-30 21:47:44 -07:00
MorphanOne
ac53442e7e Add setCritical and isCritical methods to CraftArrow.java. Adds BUKKIT-5113 2014-01-30 21:47:44 -07:00
Likaos
fb8c5547b3 Add methods to get and set arrow knockback. Adds BUKKIT-5103 2014-01-30 21:47:44 -07:00
GJ
7f22899456 [Bleeding] Re-add EntityShootBowEvent lost in e93a3eb3b4c5234e3e3936bc697d566a42d3b30e. Fixes BUKKIT-4214
In the 1.2 update for CraftBukkit, a missed diff resulted in Skeletons no longer firing an EntityShootBowEvent when they shoot an arrow.
2014-01-30 21:47:44 -07:00
GJ
e962b1bc09 [Bleeding] Add support for ThrownExpBottle and Fish to launchProjectile(...). Fixes BUKKIT-1536
Previously, trying to launch a ThrownExpBottle or Fish projectile would
result in an IllegalArgumentException. This commit adds support for both
ThrownExpBottle and Fish, which means that all current projectiles are
now properly supported by this method.
2014-01-30 21:47:44 -07:00
GJ
855b5f8ae3 [Bleeding] Instantiate logger earlier in CraftServer. Fixes BUKKIT-4253.
Previously, if an error occurred during CraftServer initialization before the
logger was instantiated, it would cause an NPE and the server would never
finish loading properly. By instantiating the logger before attempting to
load anything else in CraftServer, we ensure that a logger will always be
available in the case of any errors.
2014-01-30 21:44:36 -07:00
GJ
19521b7f1c [Bleeding] Fire interact events for Weighted Pressure Plates. Fixes BUKKIT-5053
In 1.7, Minecraft changed Weighted Pressure Plates to allow players and
entities to interact with them, rather than simply changing redstone signal
based on the number of items on the pressure plate. This commit adds calls to
PlayerInteractEvent or EntityInteractEvent for every entity that steps on the
plate.
2014-01-30 21:44:36 -07:00
GJ
6a00959980 Add BlockPressurePlateWeighted.java for diff visibility 2014-01-30 21:44:36 -07:00
Nate Mortensen
e4ba663d2a Relocate NaN check on PacketPlayInFlying. 2014-01-29 18:13:14 -07:00
Travis Watkins
6e6ad530e7 Readd connection throttle 2014-01-28 14:54:53 -06:00
Wesley Wolfe
516a02b8bb Fix stacking for items after setting empty meta. Fixes BUKKIT-5331
ItemStacks do not stack if one has null for a tag, while the other has an
empty tag. In CraftItemStack, if you set an item to an empty ItemMeta, it
will create an empty tag for the internal ItemStack.

This changes the setItemMeta function to check for empty meta, and then
use null for the tag instead of an empty NBTTagCompound.
2014-01-23 23:24:59 -06:00
Wesley Wolfe
a46eac8bce Implement API for ServerListPingEvent. Adds BUKKIT-5121, BUKKIT-2465 2014-01-19 15:56:27 -06:00
t00thpick1
030cf5a6d1 [Bleeding] Properly handle EntityBreakDoor event canceling. Fixes BUKKIT-5318
The method being called was renamed during the 1.4.2 update process
but the function call was not replaced accordingly, leading to a
missed diff from 314051580a0a8e4745d3a539f232b552916eb302.
2014-01-18 15:52:54 -06:00
t00thpick1
771c41c691 [Bleeding] Account for null in EntityDamageEvent handling. Fixes BUKKIT-5317
Damage caused by explosions will return null for the event as of
6588d6f72bbca74bf150de65593ac575b846111b. As such, a null check is
now necessary when handling non-living entity damage events.
2014-01-18 15:52:54 -06:00
t00thpick1
fef9f9692f [Bleeding] Check that vanilla recipes actually exist. Fixes BUKKIT-5277
When falling back to vanilla recipes in the iteration of recipes,
a check is necessary to ensure that vanilla recipes are present.
RecipeIterator has been modified to account for the multi-map setup.
2014-01-18 15:52:22 -06:00
t00thpick1
b8143c63c2 [Bleeding] Implement methods for /achievement command. Addresses BUKKIT-4932 2014-01-16 00:51:09 -06:00
t00thpick1
622a2976d9 [Bleeding] Fix Achievements and Statistics API. Fixes BUKKIT-5305 2014-01-16 00:51:04 -06:00
t00thpick1
dd12820c58 Add StatisticManager.java for diff visibility. 2014-01-16 00:50:57 -06:00
Wesley Wolfe
05ed0a3139 Implement UnsafeValues for give command. Addresses BUKKIT-5286 2014-01-14 22:38:03 -06:00
t00thpick1
81919478fc [Bleeding] Implement setIdleTimeout and getIdleTimeout. Addresses BUKKIT-4932. 2014-01-14 17:38:07 -07:00
Wesley Wolfe
fd65b29a0c Consider repair cost when checking ItemMeta emptiness. Fixes BUKKIT-5304 2014-01-14 18:15:04 -06:00
Wesley Wolfe
1f9f6a51c2 Add failing unit test for ItemMeta-repairability 2014-01-14 18:13:13 -06:00
Travis Watkins
32d9db82e5 Only delay removing containers. Fixes BUKKIT-5238
In commit f94b7af8 I delay removing the block until after running the
block's cleanup code to avoid errors. However, this causes problems of
its own due to blocks not being written with this in mind. To avoid blocks
getting recursively removed we now only delay removing containers since
they are the only ones we had problems with to begin with.
2013-12-24 21:51:15 -06:00
Travis Watkins
c57e45dcdc Process block cleanup first. Fixes BUKKIT-4103
When setting a block the server sets the new block ID, calls the cleanup
on the old block, then calls the placement logic for the new block. This
would normally work correctly but we have logic to prevent errors that is
causing one here. When trying to clean up the old block we notice the block
ID has changed and try to fix things, this causes the cleanup logic to
fail. To ensure cleanup happens correctly we now do all the cleanup before
changing the block which avoids triggering the fixup code.
2013-12-24 15:24:35 -05:00
EvilSeph
4a5de4249c Updated version to 1.7.2-R0.3-SNAPSHOT for development towards next release. 2013-12-21 03:08:41 -05:00
EvilSeph
025548445d Updated version to 1.7.2-R0.2 in pom.xml for Beta. 2013-12-21 02:51:50 -05:00
t00thpick1
1ecc59d4d9 [Bleeding] Handle custom furnace recipes separately. Fixes BUKKIT-1657, BUKKIT-3846
Due to vanilla blanket comparing data values, and the unspecified
order of hashmap iterators, we need to run through custom recipes
first, and therefore separately, to ensure that they are actually
used. By not adding the custom results to the experience table, we do
not override the experience gains from vanilla smelting recipes.
2013-12-20 23:37:58 -06:00
t00thpick1
3c209a9884 [Bleeding] Fix crash involving horse passengers. Fixes BUKKIT-5212
Setting a horse's passenger to a non-living entity will cause a
server crash when the horse ticks, we need to check that it is
a living entity before casting, and skip otherwise.
2013-12-20 23:37:57 -06:00
t00thpick1
9bc3b7df24 [Bleeding] Call event when reflecting fireballs. Adds BUKKIT-5214 2013-12-20 23:37:56 -06:00
t00thpick1
624603cd41 [Bleeding] Send short version string on ping. Addresses BUKKIT-5206
With the update in 1.7 that improved the server ping, it was made to
include a long version string for CraftBukkit. This value is too long
for proper display so we now send a shortened string consisting of
the server implementation and the minecraft version.
2013-12-20 23:37:56 -06:00
EvilSeph
dfcff7eabf Account for different reach limit in Survival/Creative. Fixes BUKKIT-4257
When we first added the reach limiter in CraftBukkit there was no
difference between how far the client could reach in vanilla while in
Survival or Creative. At some point in Minecraft's cycle Creative was
given a block extra to work with and our protection was not updated to
account for this. We need to respect the possibility of different game
modes in Minecraft providing the client with varying reach distances.
2013-12-20 23:38:18 -05:00
EvilSeph
6d9a6fbb4b Fix attributes not clearing on death. Fixes BUKKIT-5213
Due to an incorrect mapping of this method to a friendly name, we're
unfortunately calling the wrong method within EntityPlayer.reset() to
reset attributes. Instead of what we've mapped as "removeAllEffects", we
should be calling EntityLiving.aP(). This mapping should be corrected in
the next naming version.
2013-12-20 15:33:06 -05:00
EvilSeph
330dbbf78c Updated version to 1.7.2-R0.2-SNAPSHOT for development towards next release. 2013-12-18 01:01:25 -05:00
EvilSeph
bda2179ae9 Updated version to 1.7.2-R0.1 in pom.xml for Beta. 2013-12-18 00:23:43 -05:00
t00thpick1
3cd64185a9 [Bleeding] Correctly generate torches on portal. Fixes BUKKIT-746
In the CraftBlockState implementation, updating the blockstate onto
a block will force the block state data value onto the block.
Unlike vanilla which relied on block data being set when the type
changed, we must instead explicitely set the data in the blockstate.
2013-12-17 22:29:12 -05:00
Nate Mortensen
8da5126282 Add new setResourcePack method. Fixes BUKKIT-5015
Minecraft now uses resource packs instead of texture packs, which broke
the setTexturePack method, as the client no longer listens on the MC|TPack
channel.

This commit fixes the issue by adding in a setResourcePack method, and by
deprecating setTexturePack and rewriting it to call the newly added
setResourcePack.  In order to simplify the method and prevent this from
happening in the future, setResourcePack calls EntityPlayer.a(String) to use
the same logic as minecraft when sending resource packs.
2013-12-17 20:17:38 -07:00
mbax
091fb2ea9e Process URLs as clickable. Adds BUKKIT-4917
In Minecraft 1.7, URL processing was removed from the client while the
server gained the ability to designate a URL to be launched in response to
clicking text. However, this functionality is not implemented in the
vanilla server. This commit adds that functionality to messages sent to
the client, processing URLs as clickable.

Additionally, char array iteration is replaced with regex.
2013-12-17 21:15:11 -05:00
Travis Watkins
0f48e9b06d Check pending blocks before falling back to world. Fixes BUKKIT-5122
When growing trees we use a BlockChangeDelegate which queues up the block
changes so plugins can modify/block/log tree growing. However, we always
check the actual world when checking for existing blocks. This means when
the tree growing code checks to see if putting a leaf in a block is valid
it may incorrectly overwrite a log block that should exist in that
location. To ensure trees grow correctly we now check the delegate itself
for blocks that match the queried location before checking the world.
2013-12-17 17:36:49 -06:00
EvilSeph
4f63a5f255 Fix mistranslation issue for PlayerToggleFlightEvent. Fixes BUKKIT-5172
Thanks for pointing it out RingOfStorms!
2013-12-17 18:05:56 -05:00
frymaster
fbdc3a7a74 Remove references to chunklist. Fixes BUKKIT-5190
Commit c576054539790bdeb35285f62863d74b48c0782d removed the chunklist
collection stored in ChunkProviderServer, however it has been partially
restored in some places by 7e1ac0a77129b169704c1e222ff2deb3ab6cd2d2. As
not all references to this were restored, this has caused the chunklist
and chunks collections to become out of sync, resulting in a memory leak.

This commit removes chunklist from ChunkProviderServer again.
2013-12-17 16:55:57 -06:00
t00thpick1
0e809d8318 [Bleeding] Fix incorrect Cocoa Bean orientation. Addresses BUKKIT-5182
When ItemDye is used to place a Cocoa Block, the postPlace() method
should not be called, as data is handled within the ItemDye class.
However, if Cocoa is placed via its block item, postPlace() should
still be called to mirror vanilla behavior.
2013-12-17 16:49:38 -06:00
BlackHole
9a6d035998 Add missed tree types for Minecraft 1.7. Adds BUKKIT-5042
This commit adds support for the Tree Types that weren't added in the
initial update to Minecraft 1.7.

Pulled from PR #1277
2013-12-16 19:47:49 -07:00
BlackHole
2191599f4b Fix generation of jungle trees. Fixes BUKKIT-5043
Due to changes in the generation of trees, the name of the class responsible
for the generation of jungle trees has changed from WorldGenMegaTree to
WorldGenJungleTree.  As such, references to WorldGenMegaTree need to be
updated to WorldGenJungleTree to generate the correct type of tree.

Pulled from PR #1277
2013-12-16 19:44:03 -07:00
GJ
cee6a7bab5 [Bleeding] Correct naming of sounds for 1.7. Fixes BUKKIT-5065
Several sounds were renamed in Minecraft 1.7, and have been updated
accordingly. Additionally, two sounds, HURT and BREATH, were removed from
Minecraft.
2013-12-16 19:32:29 -07:00
Travis Watkins
24ff27b408 Don't try to teleport to a null world. Fixes BUKKIT-5145 2013-12-14 17:23:34 -06:00
t00thpick1
a565486ee1 [Bleeding] Return correct drops for Cocoa blocks. Fixes BUKKIT-5159
For Cocoa Blocks, Block.getDropType() returns the item form of the Cocoa
block, rather than the Cocoa Bean item. Because of this, Cocoa blocks need
to have explicit handling in order to return the proper drop contents.
2013-12-13 22:42:39 -07:00
GJ
1ff8132bdd [Bleeding] Fix witches dropping empty ItemStacks on death. Fixes BUKKIT-3554 2013-12-13 22:21:12 -07:00
GJ
a0e50c36b9 [Bleeding] Fix Blazes not firing death events. Fixes BUKKIT-4898
Previously, due to the way that death events were called, Blazes only
fired death events when they dropped loot. This change fixes that,
enabling death events for Blazes whenever they die, regardless of loot
drops.
2013-12-13 22:21:11 -07:00
t00thpick1
ae9cd0729e [Bleeding] Call EntityTargetEvent for EnderDragons. Fixes BUKKIT-5160
EnderDragons did not call an EntityTargetEvent when they
were targeting random players in the End.  This commit
adds that event call into the targeting code.
2013-12-13 22:20:39 -07:00
t00thpick1
1154484815 Do not fire EntityDamageEvent for explosions twice. Fixes BUKKIT-5156
Explosions directly caused by LivingEntities, such as creepers and tnt lit
by players, have their EntityDamageEvent explicitely handled within
the Explosion class.  In order to prevent double events when damage
is handled for other DamageSources, we need return null for explosion
based damage sources.
2013-12-13 20:05:36 -07:00
t00thpick1
c2a0396af2 Throw event when EnderCrystals harm EnderDragon. Fixes BUKKIT-4052
The EntityLiving dealDamage method will not call an event for the
entity damage caused by an explosion without an associated
entity cause, therefore, the explosion caused by EnderCrystals
needs to be explicitely handled within the EnderDragon class.
2013-12-13 20:05:35 -07:00
t00thpick1
e6bccf6bfd Re-add WorldLoadEvent lost in 314051580a0a8e4745d3a539f232b552916eb302 Fixes BUKKIT-5125
In the 1.4.2 update for CraftBukkit, a missed diff resulted in the
WorldLoadEvent no longer being fired for the worlds loaded on
startup.
2013-12-13 20:05:35 -07:00
t00thpick1
1460f250cf Alter fall particles to respect visibility API. Fixes BUKKIT-5158
Bukkits Visibility API should prevent players from seeing fall particles
of players that they cannot see.  This commit alters the handling to
provide an EntityPlayer argument that is later used to determine if they
are visible.
2013-12-13 20:05:19 -07:00
t00thpick1
bdbd1808f7 Show fall particles while in creative mode. Fixes BUKKIT-5009
Relocate CraftBukkit patch to fall damage when changing
gamemode from creative mode.
2013-12-13 18:51:13 -07:00
Travis Watkins
fbe062caf5 Only filter data from block items, not all of them. Fixes BUKKIT-5047 2013-12-13 18:52:33 -06:00
Travis Watkins
f5fad449bd Call interact event if block cannot be punched. Fixes BUKKIT-5126
We do ray tracing on arm swings to filter out swings that hit blocks since
punching blocks has its own event handling. However, some blocks cannot
be punched so the air interact type is still valid for them. Luckily
these blocks all have a means to query them so add an additional check
for this and don't fail the check for them.
2013-12-12 02:01:22 -06:00
Wesley Wolfe
ca4c118994 Rework furnace result log. Fixes BUKKIT-5115
This changes the logic for furnace smelt event to consider a result of
null (read: air / invalid), which will still consume an item. It also
properly considers item meta in the result, instead of only checking the
item data value.
2013-12-10 16:21:09 -06:00
Travis Watkins
f5f71a5502 Print message on startup before loading log4j
Log4j takes a long time to load on startup. Before it loads, the server
appears to have frozen as there is no output until after. We now print
a loading message before this happens to let the user know the server
is actually working.
2013-12-09 14:12:34 -06:00
Travis Watkins
772867eb51 Call event when pistons push an item frame/painting. Fixes BUKKIT-5110
When pistons push/pull blocks they call Entity.move(float, float) to move
entities out of their path. For hanging entities this code path makes them
simply die and drop as an item. We now call an event in this scenario so
plugins can control this behavior.
2013-12-09 13:43:02 -06:00
Travis Watkins
305e5f4f08 Handle null damage events for item frames. Fixes BUKKIT-5114
Some types of damage are handled specially so do not end up returning an
event in handleEntityDamageEvent. To ensure we don't have problems with
these we need to check for them and simply ignore them, as they've been
handled already.
2013-12-09 13:40:52 -06:00
Alex Ciuba
80935e5c2b Don't consume bonemeal if there is no crop present. Fixes BUKKIT-3790
Bonemeal dispense behavior already took care of decrementing the item
stack, therefore we shouldn't manage the size manually.

Pulled from PR #1172
2013-12-08 23:21:11 -06:00
t00thpick1
0aa187f151 [Bleeding] Ignore Block Physics in Chunk population. Fixes BUKKIT-4923
Suppressing physics updates during Chunk population prevents
infinite recursion due to custom Block Populators editing border
blocks on chunks.
2013-12-08 22:39:50 -06:00
BlackHole
c7b4514ad3 Call BlockPlaceEvent for cocoa beans planted on log. Adds BUKKIT-5039
The behavior of cocoa are now aligned to be the same as other plants.

Pulled from PR #1281
2013-12-08 21:47:26 -06:00
Starbuck Johnson
36ef37b982 Call EntityDamageEvent on ItemFrame item removal. Fixes BUKKIT-5020
Calling this event allows plugins to react to the situation by simply
handling a normal damage event, possibly using existing code to
handle other entity damage.

Pulled from PR #1279
2013-12-08 20:58:27 -06:00
Starbuck Johnson
3cf569a33f Added EntityItemFrame.java for diff visibility 2013-12-08 20:31:38 -06:00
Kodekpl
431e5ea442 Set proper position of snow block. Fixes BUKKIT-5004
Missed diffs when updating to 1.7.

Pulled from PR #1278
2013-12-08 20:26:37 -06:00
AlphaBlend
ff0da6bad5 Fix BlockPhysicsEvent having incorrect changed type. Fixes BUKKIT-5063
This change updates the reference to the local variable representing the
block being checked when calling BlockPhysicsEvent.
2013-12-07 21:34:50 -07:00
t00thpick1
6f4d9bea2b [Bleeding] Correctly generate giant mushrooms. Fixes BUKKIT-5066
This change fixes the reference to the local variables representing the
block position during large mushroom generation.
2013-12-07 20:31:04 -06:00
feildmaster
97cb46f9f8 Reintroduce disconnection flag that was removed in 1.7 update. 2013-12-06 21:34:06 -06:00
Wesley Wolfe
70747ca28b Follow vanilla settings behavior. Fixes BUKKIT-5069
A vanilla server does a series of checks for the client black-listing
certain chat types (commands or chat). This change changes a CB
whitelist to the vanilla blacklist behavior.
2013-12-06 16:44:32 -06:00
Wesley Wolfe
dc86362c9a Implement Firework.detonate(). Adds BUKKIT-4538
This implements the detonate method from bukkit by setting the fuse
timer to 0. This makes a firework explode using the normal codepath,
but without waiting for the fuse.
2013-12-06 00:05:23 -06:00
feildmaster
8a29829d1a Correctly register Furnace Recipies. Fixes BUKKIT-5044
We should also use items, not blocks. :)
2013-12-05 14:37:14 -06:00
GJ
b880a2d24c Add new fishing enchants. Fixes BUKKIT-5035 2013-12-04 21:17:54 -07:00
t00thpick1
e5353b82a7 Correctly validate map colors. Fixes BUKKIT-4984
The validation check in CraftMapView.render(CraftPlayer) filters out any
values less than 0. As of Minecraft 1.7, -128 through -113 are valid colors,
so filtering them out prevents some of the new colors from being sent.

This commit fixes the issue by adjusting the validation check to include
any values less than or equal to -113.  As the minimum value for a byte is
-128, no invalid colors are included.
2013-12-03 18:56:36 -07:00
Travis Watkins
169fd46960 Finish kicking player before letting their clone in. Fixes BUKKIT-4960 2013-12-03 19:21:27 -06:00
Travis Watkins
bc0ac48074 Try to detect when to disable jline automatically. Fixes BUKKIT-5028 2013-12-03 11:21:26 -06:00
Nate Mortensen
39719fff74 Maintain old setType method in WorldGenerator. Fixes BUKKIT-4915
WorldGenerator setType and setTypeAndData have their arguments changed to
add in support for CraftBlockChangeDelegate, which changes the method
signature. This change in the method signature breaks any WorldGenerators
that aren't modified to use CraftBlockChangeDelegate.

This commit fixes the issue by readding the old method and maintaining the
CraftBlockChangeDelegate method.  This makes it so that there is a
compatible method for both  CraftBlockChangeDelegate WorldGenerators and
unmodified WorldGenerators.

Additionally, this commit reduces and corrects the diffs in
WorldGenerator, moving the fix for layering violations to
CraftBlockChangeDelegate.
2013-12-02 21:03:57 -07:00
toastedtruth
a721fe8473 Fix BlockCanBuildEvent returning null. Fixes BUKKIT-4972
A Block object is now passed in place of the previous id value, so the
obfuscated name for all subsequent arguments was shifted.  As such,
BlockCanBuildEvent was using the incorrect values for both the material
and the location of the event.

This is corrected by swapping the values into the correct order and
providing an id based upon the Block passed into the method.
2013-12-02 21:03:57 -07:00
toastedtruth
803268867e Fix written books crashing the server. Fixes BUKKIT-4945
CraftBukkit modifies the IRecipe interface, adding new methods, so all
classes that implement IRecipe need to be imported and modified to add the
new methods.

Extending ShapelessRecipes implements the added methods and allows
RecipeBookClone to work with the Recipes API in a way that is consistent
with similar recipes, even if the recipe information present in the API
isn't technically correct.
2013-12-02 21:03:56 -07:00
toastedtruth
579b203347 Added RecipeBookClone from nms for diff visibility 2013-12-02 21:03:56 -07:00
Aikar
9969a86e83 Use strict lookup for op permission refresh. Fixes BUKKIT-4698
Adding or removing operators was mistakenly using a loose player lookup
method, which would cause a permission refreshes on an online player whos
name starts with the name of the (offline) opped player.

Add/Remove op operations are exact name match only and the permission
refresh will behave the same way.
2013-12-02 20:34:01 -06:00
Travis Watkins
c5d8b4393a Use correct packet data for toggling flying. Fixes BUKKIT-4989 2013-12-02 20:13:07 -06:00
feildmaster
8c444f275a Correctly drop BlockBreakEvent experience. Fixes BUKKIT-4942
This was a missed diff from the update.
2013-12-02 17:29:12 -06:00
Travis Watkins
963cd5438a Catch all exceptions in jansi initialization. Fixes BUKKIT-4936
Both log4j and our own jline/jansi initialization attempt to catch
errors caused by jansi's use of native libraries. However both of them use
the Exception type which does not catch all errors. On Windows Server 2008
R2 Enterprise without installing extra software the required C++ libraries
are not available which causes an error that does not extend Exception. To
ensure we catch all errors I've changed both of these to catch Throwable
instead which gets us a working console minus jansi functionality.
2013-12-02 15:46:34 -06:00
Travis Watkins
f3865064f8 Add ConsoleAppender from log4j for diff visibility 2013-12-02 15:43:29 -06:00
Nate Mortensen
5b6f271037 Fix missed doors diff. Fixes BUKKIT-4908
l previously was the block id, however Minecraft's refactoring means that
the method is now passed a Block reference rather than the id.  l is now
the data value of the block, so the block retrieved with that value is not
the correct block to be testing.
2013-12-01 14:54:51 -07:00
feildmaster
f0af95505b Fix fishing ignoring event experience. 2013-12-01 14:46:41 -06:00
mbax
46c11eb83f Handle ChatColor-ending messages FIXES BUKKIT-4924
Now adds the component upon creation, eliminating issues where the
created component was discarded.
2013-12-01 15:24:15 -05:00
feildmaster
72b36b8b07 Correctly send player names for the tab list. Fixes BUKKIT-4925 2013-12-01 14:15:59 -06:00
Travis Watkins
6aafe7c5a1 Make console work on Windows again. Fixes BUKKIT-4956
Something the log4j ConsoleAppender does makes the console work correctly
on Windows. After trying to pull pieces of it out and run them manually
I decided to just put the appender back. We now once again start with the
ConsoleAppender then remove it immediately after starting.
2013-12-01 13:21:22 -06:00
Travis Watkins
d48bcbe642 Handle JUL logger formatting 2013-12-01 12:29:22 -06:00
Travis Watkins
c098854591 Forward exceptions to log4j, cleanup logger handling. Fixes BUKKIT-4948 2013-12-01 11:15:18 -06:00
mbax
2726696652 Update CraftBukkit to Minecraft 1.7.2 2013-11-30 19:26:12 -06:00
EvilSeph
ff8b70fbb7 Updated version to 1.6.4-R2.1-SNAPSHOT for development towards next release. 2013-10-30 19:44:34 -04:00
EvilSeph
bf8865b829 Updated version to 1.6.4-R2.0 in pom.xml for RB. 2013-10-30 19:22:17 -04:00
feildmaster
1c7698fab2 Ensure maps are stored only in the main world. Fixes BUKKIT-4872 2013-10-30 17:00:41 -04:00
Wesley Wolfe
7aabcb2ab3 Don't share WorldMapCollection. Fixes BUKKIT-4871
WorldMapCollection stores scoreboard, map (item), structure, and
village information. Scoreboards are explicitly handled globally,
while villages and structures are erroneously shared.

This commit separates the WorldMapCollections to not be shared among
custom worlds. Maps are special-cased to maintain the previous shared
behavior.
2013-10-30 04:22:00 -05:00
Luke GB
84237bb783 Fix our versioning system. 2013-10-24 05:58:36 -04:00
EvilSeph
641d353106 Updated version to 1.6.4-R1.1-SNAPSHOT for development towards next release. 2013-10-24 02:28:24 -04:00
EvilSeph
6cf9820c70 Updated version to 1.6.4-R1.0 in pom.xml for RB. 2013-10-24 01:50:38 -04:00
Wesley Wolfe
bd1389895b Add auto-save plugin redundancy detection.
This change will print a warning when a plugin induces a forced save. A
player or console forcing a save (via a command) is ignored for purposes
of printing a warning.
2013-10-23 20:22:30 -04:00
EvilSeph
de16ba6eec Re-enable built in auto-save. Fixes BUKKIT-4800
When Minecraft first introduced an auto-save feature, we
were taken by surprise by how much of an impact it actually had on the performance
of the server. After investigating the potential causes of the significant
slow-downs we saw at the time, we came to the conclusion that it was a
combination of the auto-save interval being incredibly frequent and
servers already having an auto-save solution that was conflicting with the
newly added built-in one.

Since we noticed that most servers already had their own auto-save
solution, we decided to completely disable the built in auto-save by
default. In hindsight, however, we were so happy that we discovered and
squashed the cause of the performance issues that we forgot to consider
the future and, as a result, some servers have unfortunately been caught
by surprise when they ran their servers without any auto-save plugins.

Without the auto-save plugin conflict, however, Minecraft's default save
interval of 45 seconds is not suitable for the types of servers that run
Bukkit, to the point where it was negatively impacting performance. As
such, we've decided to re-enable the built in auto-save at an interval of
5 minutes for newly created servers.
2013-10-23 19:29:05 -04:00
Nate Mortensen
6430c868c7 Remove redundant call to worldMaps.a(). Addresses BUKKIT-4828
The WorldMapCollection object for SecondaryWorldServers(Nether, End) is
shared with the main world, so saving it again for each SecondaryWorldServer
is redundant.

This commit removes the redundant call by checking if the WorldServer is an
instanceof SecondaryWorldServer before invoking worldMaps.a().
2013-10-19 20:01:52 -06:00
Wesley Wolfe
42e7fdee92 Update maven compiler to 2.3.2
This change removes a redundant addition of source encoding and makes our
compiler match the current maven default. This amends the commit
4775b25a5932a2a24da2c55356936e2f98bff98c

Upstream issue http://jira.codehaus.org/browse/MCOMPILER-70
2013-10-15 04:09:24 -05:00
feildmaster
f4277d7105 Force item data to use a tag name. Fixes BUKKIT-4809
The recent Minecraft update rendered the
e20e50f85083dc53cb5456254bcf5781ef750daa fix incorrect by adding a
compound name to the base tag in some code. This fix changes all uses
of tag changes to explicitly use a name.
2013-10-12 03:18:45 -05:00
Phil Watson
159403e085 Call BlockFadeEvent for fire on inflammable block. Fixes BUKKIT-4835
This adds a call to fireExtinguished for fire burning out on inflamable
blocks, similar to other causes of fire fading.
2013-10-09 16:34:10 -05:00
Wesley Wolfe
ca5e0c6db0 Add exception-resilience to reading UUID. Fixes BUKKIT-4833
When a "uid.dat" file is corrupt (empty or <16 bytes), WorldNBTStorage
will silently fail to read and return null. Non-null behavior is
expected everywhere that this value is used.

This change will force a random UUID when the previous UUID cannot be
read, and getUUID to no longer silently ignore read/write exceptions.
2013-10-06 22:37:44 -05:00
Wesley Wolfe
cfa5490a58 Clarify exception message for bad hanging location. Fixes BUKKIT-4824
This change adds the location and a more specific message to the
IllegalArgumentException that gets thrown when a hanging entity is being
spawned in a location that it cannot survive.
2013-10-05 13:21:15 -05:00
Wesley Wolfe
90e8aa008a Initialize hostname on handshake. Fixes BUKKIT-4793
This restores a lost CraftBukkit diff that initializes the hostname
field used during login events.
2013-09-20 09:13:48 -05:00
feildmaster
dcb9d6a5ef Update CraftBukkit to 1.6.4 2013-09-19 20:01:02 -05:00
EvilSeph
e20ef1f606 Updated version to 1.6.2-R1.1-SNAPSHOT for development towards next release. 2013-09-11 00:54:59 -04:00
EvilSeph
8656d6917a Updated version to 1.6.2-R1.0 in pom.xml for RB. 2013-09-10 22:59:18 -04:00
EvilSeph
79bc53fe97 Update for 1.6.2_01 renames. 2013-09-10 22:59:18 -04:00
feildmaster
7ad5d6098d Fix villager death sound 2013-09-10 21:55:42 -05:00
feildmaster
ac73522ecf Add missing villager sounds. Addresses BUKKIT-4756 2013-09-10 21:30:36 -05:00
EvilSeph
6d700c3320 Use correct spawn reason for Zombie reinforcements. Fixes BUKKIT-4744 2013-09-10 22:24:00 -04:00
EvilSeph
b8feaf059c Remove unnecessary error logging. Fixes BUKKIT-4406 2013-09-10 22:23:59 -04:00
Phillip Schichtel
ffcd0f4502 Provide a tab completion handler for JLine. Adds BUKKIT-4168 2013-09-10 20:57:31 -05:00
FrozenBrain
5f65cd9a1c Add support for custom Hopper inventories. Fixes BUKKIT-4722
Opening a hopper inventory created by Server.createInventory will
currently have no effect as proper handling code is missing in
CraftEntityHuman for hopper inventories that aren't associated with a tile
entity or minecart. Initialization logic for hoppers is also missing from
CraftContainer, which is necessary for the opening of custom hopper
inventories.

This commit fixes the two aforementioned by adding proper handling to
CraftHumanEntity for opening inventories not associated with a tile
entity, and by adding initialization logic for hoppers to CraftContainer.
2013-09-10 20:51:35 -05:00
feildmaster
600e1524a9 Update and add new sound mappings. Fixes BUKKIT-4756 2013-09-10 20:24:34 -05:00
Brokkonaut
5f43109c0e Correct location of fire from lightning strikes. Fixes BUKKIT-4707
Previously fires spawned by lightning strikes were in the wrong locations.
This introduced the possibility of having blocks replaced when they should
not be.

EntityLightning now uses the correct locations as defined to spawn the
fires when needed.
2013-09-10 20:53:48 -04:00
feildmaster
8ae8957d15 Properly set persistence flag for bred animals. Fixes BUKKIT-4751 2013-09-10 19:42:08 -05:00
Nate Mortensen
c62375f95e Check that a vehicle is a Vehicle before casting. Fixes BUKKIT-4749
When an entity is being moved as the passenger of an entity from one
entity to another, a VehicleExitEvent is fired, but it is assumed that the
current entity is a Vehicle. However, entities can be passengers of more than
just Vehicles, which causes a ClassCastException to be thrown.

This commit fixes the issue by checking that the current entity's vehicle's
bukkitEntity is an instance of Vehicle before casting it to Vehicle.
2013-09-09 22:07:27 -05:00
Wesley Wolfe
5c861fe864 Fix improperly initialized usernames 2013-09-02 16:51:14 -05:00
T00thpick1
cd593fb1ee Set current recipe to null when a recipe isn't found. Fixes BUKKIT-2311
This commit restores the diff from 84dbc21aa71b96fd1d2ea40d624b536309118cde
that has since been lost.
2013-08-28 08:14:01 -06:00
Wesley Wolfe
4667e9493c Add source encoding to the maven compiler plugin.
This change adds the source encoding to the maven compiler plugin, which
will strictly enforce build consistency on multiple platforms and address
possible compilation issues on some of the source files. The source
encoding unintuitively is system-specified by default.
2013-08-28 01:45:58 -05:00
Roger Baumgartner
2e7f66787d Return correct hasLineOfSight value for players. Fixes BUKKIT-4634
Prior to this change when a plugin called Player.hasLineOfSite() the
method would always return false because EntityHuman does not extend
EntityInsentient. This commit changes that by explicitly checking for
line of sight between two entities and returning that value.
2013-08-26 08:43:51 -06:00
T00thpick1
6482b6f0bd Fire FoodLevelChangeEvent when eating cake. Fixes BUKKIT-2242 2013-08-15 11:59:47 -06:00
T00thpick1
3fb4ccb62c Add BlockCake for diff visibility. 2013-08-15 11:59:46 -06:00
Wesley Wolfe
f481c9ee07 Make ItemFactoryTest.java platform agnostic. Fixes BUKKIT-4695
Maven paths that include spaces (and possible other characters) get
improperly translated when using a file handle from a URL. This changes
the unit test to open a stream directly from the URL, providing proper
file resolution on multiple platforms.
2013-08-14 02:37:24 -05:00
T00thpick1
ea39ca187b Return instance of CraftInventoryBeacon for Beacons. Fixes BUKKIT-4521 2013-08-07 13:42:23 -06:00
Wesley Wolfe
92f111cfed Fix missed diff for chat packets. Fixes BUKKIT-4666
This commit removes chat wrapping. It is no longer needed, as clients
properly render lines with line breaks.

This commit also changes an outgoing chat message to use the vanilla
behavior for indicating a client cannot chat with commands-only setting.
2013-08-07 04:05:56 -05:00
riking
0506b709fe Wrap plugin.getDefaultWorldGenerator in try-catch. Fixes BUKKIT-4116
If a plugin generates an exception when returning a world generator, the
server will crash. This change adds a try-catch block to keep the server
from crashing on plugin defined world generators.
2013-08-07 01:01:12 -05:00
Wesley Wolfe
71a6a56572 Fix javac workaround in ItemStackTest 2013-08-06 20:09:42 -05:00
Wesley Wolfe
9ba5c79c30 Add BukkitObjectIOStream tests on top of ItemMeta tests 2013-08-06 20:00:29 -05:00
Wesley Wolfe
066fcfe79f Validate title for custom inventories. Fixes BUKKIT-4616, BUKKIT-4663
Custom inventories currently do not validate the titles provided. Null values
cause NPEs when writing packets. Values longer than 32 characters
disconnect clients.

This change throws and IllegalArgumentException for null titles or titles
longer than 32 characters.
2013-08-06 17:11:30 -05:00
T00thpick1
5e8dd7d57d Use correct spawn reason for Villagers Breeding. Fixes BUKKIT-4113 2013-08-06 13:03:14 -06:00
T00thpick1
485e9ad93f Add PathfinderGoalMakeLove for diff visibility 2013-08-06 13:03:13 -06:00
T00thpick1
4aeb3ff63d Call unleash event for non-sitting animals. Fixes BUKKIT-4658
The unleash event is only called for animals that are sitting - ones that
receive no movement vector. This adds the missing event call for
non-sitting animals.
2013-08-06 00:38:44 -05:00
EvilSeph
e489840ca9 Updated version to 1.6.2-R0.2-SNAPSHOT for development towards next release. 2013-08-04 00:44:27 -04:00
EvilSeph
ff60299af3 Updated version to 1.6.2-R0.1 in pom.xml for Beta. 2013-08-03 19:59:29 -04:00
Jonatan Noponen
6d0d33b9d2 Fix off by 1 error for spawn protection. Fixes BUKKIT-4154 2013-08-03 18:23:38 -04:00
Kai Dederichs
e7539378fa Fix mistranslation in isPlayerCreated() for IronGolems. Fixes BUKKIT-4543 2013-08-03 18:23:37 -04:00
Wesley Wolfe
da5d494b36 Update players when coming into view of vehicle. Fixes BUKKIT-4628
When only considering trackers from player perspective, attach entity
packet could be sent before a packet for a respective vehicle is in view
and will, in turn, be ignored.

This adds another notification when the vehicle comes into view to cover
all cases.
2013-08-03 17:03:49 -05:00
T00thpick1
54672a75f6 Implement Leash API. Adds BUKKIT-4459, BUKKIT-4583 2013-08-03 15:03:41 -05:00
T00thpick1
f7ca953ff1 Add EntityLeash and ItemLeash for diff visibility 2013-08-03 14:48:40 -05:00
Wesley Wolfe
8a7c582d54 Ignore null sound by contract. Fixes BUKKIT-4641 2013-08-02 20:05:22 -05:00
Wesley Wolfe
93cfe3961f Indicate help is a command. Fixes BUKKIT-4642 2013-08-02 20:03:50 -05:00
EvilSeph
720a8d706a Revert to 1.5 despawning behaviour for Ocelots and Wolves. Fixes BUKKIT-4449 2013-08-02 19:21:35 -04:00
EvilSeph
a466e0aa6c Add timeout for Panic goal. Fixes BUKKIT-4531 2013-08-02 19:20:26 -04:00
EvilSeph
ab36dbb6a9 Add PathfinderGoalPanic for diff visibility. 2013-08-02 19:20:25 -04:00
h31ix
f959530f6b Add raw sound string playSound method. Adds BUKKIT-2443
A method has been added to Player which allows the server to send a sound string to the client. Assuming the client has the specified sound, it will be played. This is needed by the implementation of the /playsound command.
2013-08-02 00:13:20 -05:00
Wesley Wolfe
c8b09db844 Restore diff missed in 4176258a836062b22ac46919aefa5cc36fae78f2 2013-08-01 12:12:40 -05:00
Wesley Wolfe
69d3362335 Revert "Correct vehicle movement issues." Fixes BUKKIT-4565
This reverts commit 3d906d134417cfeefe7f71b916fee4d105e7650f.

Conflicts:
	src/main/java/net/minecraft/server/EntityTrackerEntry.java
2013-07-29 13:04:23 -05:00
Wesley Wolfe
b2be908fbb Fix NBT token for attribute names. Addresses BUKKIT-4483 2013-07-28 14:52:25 -05:00
Wesley Wolfe
1e7f2ebebd Store item attributes. Addresses BUKKIT-4523 2013-07-27 18:00:01 -05:00
T00thpick1
b6fec0467f Restore CraftBukkit diff in ItemDye. Fixes BUKKIT-4493
Change ItemDye to pass the EntityHuman for StructureGrowEvent again.
2013-07-25 18:27:00 -05:00
Wesley Wolfe
5bfd599e9f Store owning Horse in horse inventory. Fixes BUKKIT-4586 2013-07-25 18:04:09 -05:00
Wesley Wolfe
0a9758ae54 Fix CraftBukkit diffs 2013-07-23 22:07:42 -05:00
Wesley Wolfe
e88cea8402 Check interactable items before event. Fixes BUKKIT-4576
Items that cause entities to change state, including tags, chest, and
leashes, do not update the client properly following the firing of
PlayerInteractEntityEvent. This change makes the item checks occur
before the event fires, to concur with the client's assumptions.
2013-07-23 21:52:31 -05:00
T00thpick1
1192f2a53a Add API to control scaled health. Adds BUKKIT-4590
This commit implements the ability to set the scale of hearts that the
client renders.  When the Packet44UpdateAttributes packet is sent, the
max health attribute is replaced with a scaled version, to preserve the
scaled health illusion clientside.

In order to accurately display the scaled health for players, a true
health is stored within CraftPlayer, and the datawatcher now stores the
scaled health. The getHealth() method for players still returns their
true health.

Changed setHealth() within EntityLiving to appropriately handle health
for instances of EntityPlayer. Inlined a call to
setHealth(getMaxHealth()) within the EntityLiving constructor to work
around CraftEntity instantiation.

Additionally fixes the health values sent when eating food within
FoodMetaData and ItemFood, which previously sent the unscaled health;
this commit alters them to send the properly scaled health.

Additionally fixes BUKKIT-4535, BUKKIT-4536, and BUKKIT-4127
2013-07-23 21:52:17 -05:00
Jim Bilbrey
4ad3cdd4b5 Use ambient setting of potion effects. Fixes BUKKIT-4357 and BUKKIT-3653
This changes livingEntity.addPotionEffect(PotionEffect, boolean) to
construct the MobEffect using the constructor that includes the ambient
setting as supplied by the PotionEffect

This also changes livingEntity.getActivePotionEffects() to construct the
PotionEffects using the ambient setting supplied by the MobEffects.
2013-07-13 20:28:16 -04:00
Nate Mortensen
cebc247b78 Correctly fire VehicleExitEvent. Fixes BUKKIT-3761
This change makes it so that EntityHuman#setPassengerOf(Entity) invokes
its parent method when leaving vehicles so that VehicleExitEvent is fired
for players leaving vehicles.

This change also fixes BUKKIT-2110, making it so VehicleExitEvent
correctly handles cancellation. The implementation of VehicleExitEvent
completely ignored the cancellation state of the event, making it so that
cancelling the event had no effect.  Cancelling a VehicleExitEvent now
causes the entity to remain inside of the vehicle, with no visual stutter.
2013-07-13 13:29:32 -06:00
EvilSeph
67f15266da Return inGround when checking Arrow's OnGround state. Fixes BUKKIT-4439 2013-07-10 20:27:03 -04:00
EvilSeph
a31158bd0b Clear attributes on death; mistranslation issue. 2013-07-10 20:02:18 -04:00
EvilSeph
96fd897a2f Missed a mention of Java 5. We build for Java 6, as per the Minecraft spec. 2013-07-10 19:33:35 -04:00
h31ix
f9d58bf481 Implement Horse API. Adds BUKKIT-4424
API has been added to interface with Horses and to modify their inventories. Horse entities will now be recognized with the type EntityType.HORSE, and will no longer be UNKNOWN.

HorseJumpEvent, EntityDamageEvent, and EntityTameEvent are all correctly fired for horses.

This commit fixes BUKKIT-4393.
2013-07-10 13:45:52 -04:00
h31ix
a192775f0f Add PathfinderGoalTame for diff visibility. 2013-07-10 13:45:43 -04:00
EvilSeph
f665884955 Correctly set level name for 'world' option. Fixes BUKKIT-4474 2013-07-09 21:35:49 -04:00
EvilSeph
9109bd7652 Ocelots -> Ocelittle. Addresses BUKKIT-4449 2013-07-09 21:04:45 -04:00
mbax
f6a0b1e426 Update CraftBukkit to 1.6.2 2013-07-08 19:43:37 -04:00
EvilSeph
2d9a9d8cea Removed extra eat call. Fixes BUKKIT-4462 2013-07-04 19:19:36 -04:00
Wesley Wolfe
fdd53f9ddc Improve maps.yml. Fixes BUKKIT-4419
Additionally fixed Minecart's interface to map INVALID methods.
2013-07-03 03:55:54 -05:00
EvilSeph
c00db5f751 Properly clear attributes on remove and death. Fixes BUKKIT-4416 2013-07-03 00:25:31 -04:00
Wesley Wolfe
adcb293a03 Fix scaling for player health. Fixes BUKKIT-4431 2013-07-02 23:09:43 -05:00
EvilSeph
e1a3fb56b5 Minecraft spec has changed and we're required to follow. We now build with Java 6. 2013-07-02 23:45:59 -04:00
EvilSeph
29fa46a4b2 Fix donkey/mule dupe exploit. 2013-07-02 23:38:44 -04:00
EvilSeph
7b71fc23be Added EntityHorse for diff visibility. 2013-07-02 23:38:44 -04:00
mbax
d213f7588f Update client on cancelled entity naming. Fixes BUKKIT-4396 2013-07-02 21:38:01 -04:00
mbax
774cf2a2ca Update client on cancelled leash. Fixes BUKKIT-4395 2013-07-02 21:06:17 -04:00
mbax
a15096ae1c Send event-defined MOTD/maxplayers. Fixes BUKKIT-4409
Also, revert to previous CraftBukkit functionality
2013-07-02 16:36:57 -04:00
mbax
905f00b070 Fix world preparation status output. Fixes BUKKIT-4407 2013-07-02 16:07:50 -04:00
mbax
65ccff6340 Regrow sheep wool on grass consumption. Resolves BUKKIT-4405 2013-07-02 15:01:57 -04:00
Nate Mortensen
3a9622cbdc Fix Entity persistence. Fixes BUKKIT-4397
Missed diff.
2013-07-02 11:50:37 -06:00
Wesley Wolfe
22adf8a3ce Rework max health values. Fixes BUKKIT-4398 2013-07-02 12:34:40 -05:00
Wesley Wolfe
e79d26d7d7 Fixed NPE in BrewingStand 2013-07-01 22:29:43 -05:00
Nate Mortensen
6c09066e22 Update CraftBukkit to 1.6.1 2013-07-01 12:10:06 -05:00
EvilSeph
f887b76a25 Updated version to 1.5.2-R1.1-SNAPSHOT for development towards next release. 2013-06-14 22:25:24 -04:00
EvilSeph
c945563f9b Updated version to 1.5.2-R1.0 in pom.xml for RB. 2013-06-14 21:54:39 -04:00
Nate Mortensen
5c8498c8b7 Fix cancellation for InventoryDragEvent. Fixes BUKKIT-4332
Cancelling InventoryDragEvent causes the placed items to be lost.  This is
because the cursor is set to the result prior to the event taking place,
so the items are removed from the cursor. When the event is cancelled, the
items removed from the cursor aren't placed in the inventory, and are just
lost.

This change sets the cursor back to the original cursor when the event is
cancelled.
2013-06-13 22:01:50 -05:00
Nate Mortensen
930a9e805c Correct cancellation of InventoryClickEvent. Fixes BUKKIT-4331
Cancelling an InventoryClickEvent for a single click causes the click not
to be processed by the clicked inventory. The server then doesn't
correctly identify their second click as being a double click, causing an
inconsistency between what the Player believes the inventory to be and
what the server believes the inventory to be.

This change forces an updateInventory call whenever an InventoryClickEvent
whose action is NOTHING is cancelled.  Both clicks are considered
PICKUP_ALL, so updating the inventory after the second click fixes any
inconsistencies that could arise between the client and the server.
2013-06-13 22:01:50 -05:00
ST-DDT
93c0d7e6b5 Fix negative damage from Zombies. Fixes BUKKIT-4193
Currently, the method used for calculating the damage of zombies is scaled
to their health, but it uses the default max health rather than the real
max health value. If zombies have more health than the default max health
value, the amount of damage they deal becomes negative.

This is caused by EntityZombie.getMaxHealth() returning a hardcoded value of
20, which is the vanilla max health for zombies. Rather than using this value
when calculating zombie damage, the call is changed to instead use
((CraftLivingEntity) this.bukkitEntity).getMaxHealth(). This uses the true
maximum health of the Entity. "this.maxHealth" could be used instead of the
aforementioned method, however that creates a very unclear diff, and a
confusing change.
2013-06-13 16:53:35 -06:00
Des Herriott
045121d095 Implement PlayerBookEditEvent. Adds BUKKIT-1995 2013-06-10 12:06:37 -06:00
mbax
c55c0db86d Update blaze breathe sound. Fixes BUKKIT-4286 2013-06-05 19:45:24 -05:00
Nate Mortensen
bf4796d39e Fix creative ArrayIndexOutOfBoundsException. Fixes BUKKIT-4305
When a Player drops an ItemStack while in creative mode by placing it outside
of their inventory window, the slot number in the packet is -1. The check
that was added to avoid throwing InventoryCreativeEvent excessively didn't
take this into account, and would cause an ArrayIndexOutOfBoundsException to
be thrown when attempting to get the slot specified by the packet.

This change shorts the invocation of player.defaultContainer.getSlot(
packet107setcreativeslot.b) to only occur if the slot id is within the range
of the Inventory.  This prevents attempting to get the slot from a location
that is actually outside of the Inventory.
2013-06-04 15:58:36 -05:00
riking
991218a339 Improve events for new inventory features. Adds BUKKIT-3859
This commit brings the InventoryClickEvent up to date with the new Minecraft
changes in 1.5.

InventoryDragEvent (thanks to @YLivay for his PR) is added to represent the
new "dragging" or "painting" functionality, where if you hold an itemstack and
click-drag over several slots, the items will be split evenly (left click) or
1 each (right click).

The ClickType enum is used to represent what the client did to trigger the
event.

The InventoryAction enum is reserved for future expansion, but will be used to
indicate the approximate result of the action.

Additionally, handling of creative inventory editing is improved with the new
InventoryCreativeEvent, and handling of numberkey presses is also improved
within InventoryClickEvent and CraftItemEvent.

Also, cancelling a creative click now displays properly on the client.

Adresses BUKKIT-3692, BUKKIT-4035, BUKKIT-3859 (new 1.5 events),
BUKKIT-2659, BUKKIT-3043, BUKKIT-2659, and BUKKIT-2897 (creative click events).
2013-06-03 18:01:08 -06:00
EvilSeph
56dbde3c5b Updated version to 1.5.2-R0.2-SNAPSHOT for development towards next release. 2013-05-03 18:39:32 -04:00
EvilSeph
9b9cd2dc0c Updated version to 1.5.2-R0.1 in pom.xml for BETA. 2013-05-03 17:42:59 -04:00
Travis Watkins
5ed1418bb4 Pass correct block when dispensing empty buckets. Fixes BUKKIT-3668 2013-05-03 06:45:11 -05:00
Travis Watkins
d9eb586568 Correct event handling for dispensing filled buckets. Fixes BUKKIT-4046
We only go through event creation and calling when dispensing filled buckets
if the bucket is able to place its liquid. However, the check for this is
incorrect so the event is not called when a block liquids can destroy is
in front of the dispenser. This commit fixes the check to match the checks
vanilla does when actually using the bucket.
2013-05-03 06:38:44 -05:00
Des Herriott
28fb514a4d Send block updates even when applyPhysics is false. Fixes BUKKIT-3971
The CraftBlock class is setting bit 0x4 of the update flag when bit 0x2
should in fact be set here. Bit 0x2 means "do updates"; bit 0x4 means
"don't do updates if the world is static, even when bit 0x2 is set".
2013-05-02 16:42:47 -06:00
Travis Watkins
4e7ad05111 Fix typo/logic error in previous commit 2013-05-02 13:06:21 -05:00
Travis Watkins
25ca3f41af Fix animal spawning ignoring limits. Fixes BUKKIT-4180
Minecraft 1.5.2 changed mob spawning by ignoring persistent mobs from the
mob count. In CraftBukkit all mobs that previously used a separate hard
coded persistence system were ported to instead use this one. This causes
all animals to be persistent by default and thus never be counted. To
correct this issue we consider if the mob would be considered persistent
in the hard coded system as well when deciding if a mob should count.
2013-05-02 12:24:31 -05:00
Travis Watkins
401a6809be Improve InventoryCloseEvent handling. Fixes BUKKIT-3286
Currently there are several cases where a player will have their inventory
screen closed client side but we will not call an event. To correct this
we call the event when the server is the cause of the inventory closing
instead of just when the client is the cause. We also ensure the server is
closing the inventory reliably so we get the events. Additionally this
commit also calls the event when a player disconnects which will handle
kicks, quits, and server shutdown.
2013-05-02 06:28:51 -05:00
Score_Under
75641a607e Move world generator warning to CraftBukkit. Fixes BUKKIT-2565 2013-04-30 17:09:04 -07:00
Travis Watkins
f08081c77d Always process movement for vehicles and passengers. Fixes BUKKIT-4142
As an optimization we don't do any movement processing on entities that
have not moved. However, players in minecarts trigger this condition when
the minecart is moving on its own. This causes issues with things that rely
on player collision like tripwires. To correct this and any future related
issues we always handle movement for passengers and their vehicles even
if one of the two hasn't moved since they are linked.
2013-04-30 01:21:04 -05:00
Travis Watkins
2715e43305 Revert "Add delay to hopper even if it doesn't do anything."
This reverts commit f5388e8f94e2cbab76c2255fd872c289e83100a0.
2013-04-27 10:42:25 -05:00
Travis Watkins
3bbfb41798 Fix things using wall time running too fast. Fixes BUKKIT-4155
When converting things in Minecraft to use wall time instead of ticks I
realized we'd run into integer division rounding issues and could have
updates that end up counting as zero ticks. To compensate for this the
code ensures we always process at least one tick. However, every time we
end up with zero ticks the next time we have an extra tick due to rounding
the other way with the leftovers. This means we are going far too fast and
should not have this at least one tick logic at all.

On top of this some potions rely on the number of ticks they run and not
just the amount of time they last and so potions were put back to running
with ticks entirely.
2013-04-27 10:42:25 -05:00
Travis Watkins
799779e4b1 Update CraftBukkit to Minecraft 1.5.2 2013-04-27 10:42:19 -05:00
Wesley Wolfe
83c3aa188b Rework EntityExplodeEvent. Fixes BUKKIT-4140. Adds BUKKIT-4141 2013-04-24 03:03:38 -05:00
Travis Watkins
708b0e6ae1 Don't do physics updates in world generation. Fixes BUKKIT-3747 2013-04-16 07:09:32 -05:00
Mike Primm
40e6308718 Validate chunk data array lengths. Fixes BUKKIT-4093
If a chunk has somehow managed to save with arrays that are not 4096
entries long when reading them again we will get exceptions. Checking the
array length and resizing if needed is cheap so we should do this to help
avoid crashing servers due to this error.
2013-04-15 22:50:20 -05:00
Travis Watkins
928e4d9bbb When moving a misplaced chunk move tile entities too. Fixes BUKKIT-4092
When a chunk is being loaded the server checks to ensure the chunk's idea
of where it is located matches where it was located in the region file. If
these two values do not match the chunk's idea of its position is updated
and the chunk is reloaded. In vanilla minecraft this loading involves the
chunk's tile entities as well. With the change to loading player chunks
asynchronously we split loading tile entities to a separate step that takes
place after this check. Because of this tile entities are loaded with
invalid locations that result in trying to fetch block data from negative
or too large positions in the chunk's internal block storage arrays.

Because loading the tile entities is not thread safe we cannot return to
vanilla behavior here. Instead when we detect a misplaced chunk we just
edit the NBT data for the chunk to relocate the tile entities. This results
in them moving correctly with the chunk without having to actually load
them first.
2013-04-15 22:49:54 -05:00
GJ
0ab14dbaad Make Slimes fire EntityTarget events. Fixes BUKKIT-1408 2013-04-15 20:03:22 -07:00
EvilSeph
e62614a71e Updated version to 1.5.1-R0.3-SNAPSHOT for development towards next release. 2013-04-13 02:58:41 -04:00
EvilSeph
3dfdd0fe41 Updated version to 1.5.1-R0.2 in pom.xml for BETA. 2013-04-13 02:47:51 -04:00
Travis Watkins
c3cf8a435b Don't apply fall damage when cancelled. Fixes BUKKIT-4065 2013-04-13 01:03:08 -05:00
Travis Watkins
8590492680 Add delay to hopper even if it doesn't do anything. Fixes BUKKIT-4061
If a hopper is unable to perform any action during a tick it attempts to do
so every tick from then on. Once it is able to do so it then sets a delay
before attempting to do something again. To avoid excessive CPU usage for
hoppers sitting idle we now apply this delay regardless of the success of
the action.
2013-04-13 00:36:35 -05:00
riking
5cc4fbd712 Perform anvil calculations when using 1.5 drop feature.
When using the new feature in 1.5 to drop the item in any highlighted slot,
the anvil result slot does not apply the full anvil calculation that picking
up the item does, including the experience calculation.
2013-04-13 00:31:20 -05:00
Travis Watkins
1c18834b7d Use wall time instead of ticks for several things. Fixes BUKKIT-4059
Currently furnace smelting and the item pickup delay timer use wall time
(aka actual time passed) to emulate a constant tick rate so run at the
same speed regardless of the server's actual tick rate. There are several
other places this makes sense so this commit converts them.

The item despawn timer is converted so now always takes 5 minutes. Users
know this 5 minute number well so keeping this constant helps to avoid
confusion. This also helps alleviate lag because if a large number of item
drops is the reason your server is running slowly having them stay around
longer just means your server is slow longer.

Potion brewing and the zombie villager conversion timer are now constant.
These match the furnace criteria of being useful for hiding lag and not
having a detrimental effect on gameplay.

Potion effects are now also using wall time. The client is told about effect
times in ticks and displays this information to the user as minutes and
seconds assuming a solid 20 ticks per second. The server does have
code for updating the client with the current time remaining to help
avoid skew due to differing tick rates but making this a constant makes
sense due to this display.
2013-04-13 00:31:08 -05:00
Travis Watkins
94f43d8c36 Add MobEffect from mc-dev for diff visibility 2013-04-13 00:30:56 -05:00
Travis Watkins
a2d9f33ca3 Various minor performance improvements
Add a check to avoid doing movement work if an entity doesn't move. This
usually will not ever happen in the current server but is useful when it
does and will be more useful in the future.

Only process mob on mob (non-player) collisions every other tick. Players
tend to pack a lot of mobs into a small space (sheep farm, mob grinder, etc)
so they do a lot of work processing collisions. To help alleviate some of
this we only run these calculations every other tick. This has no visible
effect on the client but can be a huge win on the server depending on
circumstances.

Use generic entity inWater checking for squids. Squids have their own logic
currently for determining if they are in water. This check is almost
identical to the generic entity checking which is run anyway. To avoid
doing duplicate work we just remove the squid version. This does not
have any noticeable effect on gameplay since the checks are so similar.

Use HashSet for tile entities instead of ArrayList. Using an ArrayList for
storing tile entities in a world means we have very expensive inserts and
removes that aren't at the end of the array due to the array copy this
causes. This is most noticeable during chunk unload when a large number of
tile entities are removed from the world at once. Using a HashSet here uses
a little more memory but is O(1) for all operations so removes this
bottleneck.
2013-04-13 00:30:43 -05:00
Travis Watkins
159d614a3a Correct vehicle movement issues. Fixes BUKKIT-2993, BUKKIT-4056
When a player comes into range of an entity in a vehicle they will often be
sent the spawn packet for the rider before receiving one for the vehicle.
This causes the attachment packet to fail client side because it attempts
to attach the rider to a vehicle that doesn't exist on the client. To
correct this we account for both possible orderings and send the
attachment packet appropriately.

Vanilla also sends an new attach packet every 60 ticks even if the vehicle
has not changed. As this packet is a toggle this resulting in players
teleporting around randomly. Since we handle attachments properly now we
simply revert this section to use the 1.4 logic.
2013-04-13 00:30:30 -05:00
Travis Watkins
ce5b97ea83 Fetch tile entities from chunks instead of world. Fixes BUKKIT-4055
When looking up tile entities for a chunk to send to a player we currently
loop through every tile entity in the world checking if it is within the
bounds of the relevant chunk. Instead of doing this we can just use the
tile entities list stored in the chunk to avoid this costly searching.

As a further optimization, we also modify the generic range-based lookup
to use chunks as well. For most lookups this will give a smaller search
pool which will result in faster lookups.

Thanks to @mikeprimm for the idea and most of the implementation.
2013-04-13 00:30:16 -05:00
Travis Watkins
70a778f475 Boats can only die once.
In certain scenarios a boat can be killed multiple ways in a single tick.
Due to improper guards this can cause the death code to run multiple times
creating item drops. To correct this we insert the appropriate death check.
2013-04-13 00:29:49 -05:00
Wesley Wolfe
7939572c33 Check connection status before setting scoreboard. Fixes BUKKIT-4064
Two connection status checks were added to setting a scoreboard for a
player. The first checks to see if a player has logged in yet, which
implicates the ability to receive packets. The second checks to affirm
that the CraftPlayer reference is still to a logged in player; setting
it while not logged in would maintain a stale player reference in the
scoreboard manager.
2013-04-12 21:31:24 -05:00
Wesley Wolfe
3e0d8331be Change perspective of team checking. Fixes BUKKIT-4044
The method's return value was being incorrectly calculated from the
perspective of this.canHurt(that), where it's actually used from the
this.canBeHurtBy(that) perspective.
2013-04-11 23:22:41 -05:00
Wesley Wolfe
ac593849ae Use correct method for getting player's team. Fixes BUKKIT-4050
The method getTeam gets the team from name of, as opposed to getting the
team a player belongs to.

This also addresses BUKKIT-4002 and partially BUKKIT-4044
2013-04-11 23:03:37 -05:00
feildmaster
77d1524b3d Refactor EntityDamageEvents. Adds BUKKIT-1944 & BUKKIT-3684 2013-04-10 21:33:33 -05:00
Wesley Wolfe
535a85a5b0 Make auxiliary worlds use the main scoreboard. Addresses BUKKIT-3984
When a world is created using our API, it does not use secondary world
server and will maintain a reference to its own scoreboard. In vanilla,
this is not an issue as there is only ever one world.

Similarly to maps, an overwrite to the scoreboard reference has been
added for when another world has been created.

This should also address BUKKIT-3982 and BUKKIT-3985
2013-04-04 23:35:16 -05:00
Travis Watkins
2a5e90fb8b Handle large chests correctly for hopper events. Fixes BUKKIT-3979
In commit 7710efc5f9 we corrected the handling of large chests as the
destination for hoppers moving items but did not apply the same fix for
large chests being the source or for droppers. This commit updates these
to have the same fix.
2013-04-04 12:59:47 -05:00
Wesley Wolfe
055c13461d We compile for 1.5 2013-04-04 01:22:50 -05:00
mbax
d95a4705cb Implement Scoreboard API. Adds BUKKIT-3776
This implementation facilitates the correspondence of the Bukkit Scoreboard
API to the internal minecraft implementation.

When the first scoreboard is loaded, the scoreboard manager will be created.
It uses the newly added WeakCollection for handling plugin scoreboard
references to update the respective objectives. When a scoreboard contains no
more active references, it should be garbage collected.

An active reference can be held by a still registered objective, team, and
transitively a score for a still registered objective. An internal reference
will also be kept if a player's specific scoreboard has been set, and will
remain persistent until that player logs out.

A player's specific scoreboard becomes the scoreboard used when determining
team structure for the player's attacking damage and the player's vision.
2013-04-04 01:13:21 -05:00
Wesley Wolfe
5634d9f701 Add a WeakCollection utility class.
This class is designed to be an invisible layer between a normal collection,
and one that silently loses entries because they are only weakly referencable.
Some operations have additional overhead to be semantically correct, but it
maintains the equals contract for all entries, as opposed to identity.

It does not support the equals or hash code method as it cannot easily have
the transitive and commutative properties.
2013-04-04 01:05:47 -05:00
mbax
3f637d1724 Add ScoreboardServer from mc-dev for diff visibility 2013-04-04 01:05:03 -05:00
EvilSeph
0c6b9bba15 Updated version to 1.5.1-R0.2-SNAPSHOT for development towards next release. 2013-04-04 00:18:59 -04:00
EvilSeph
e5ebb143d2 Updated version to 1.5.1-R0.1 in pom.xml for BETA. 2013-04-03 22:40:36 -04:00
gjmcferrin@gmail.com
5ede9ce5f7 Add missing calls to BlockRedstoneEvent. Adds BUKKIT-3926
This adds calls to BlockRedstoneEvent for the new daylight sensor and
trapped chest blocks. Note that the redstone level for trapped chests
cannot be modified, as it is based on the number of players currently
viewing the chest's inventory.
2013-04-03 02:48:58 -05:00
gjmcferrin@gmail.com
1d6ff3461d Add BlockDaylightDetector from mc-dev for diff visibility 2013-04-03 02:48:47 -05:00
h31ix
743d0fb603 Properly return contents of Inventory. Fixes BUKKIT-3930
When an array of an inventory's contents is requested, we loop through the contents of the NMS inventory's ItemStacks in order to return Bukkit ItemStacks that can be used through the API. However, the NMS ItemStack can, in some cases, be larger than the physical size of the inventory. Using the size of the NMS array as a limit on the loop that follows can result in an ArrayIndexOutOfBoundsException because the Bukkit array's length is the actual size of the inventory, and thus will be smaller.

With this commit we use the smaller of the two arrays' length as the limit in the loop, thus eliminating the possibility that the smaller array will be asked for an index higher than its length.
2013-04-02 16:10:04 -05:00
Travis Watkins
c33908509a Set world on fixed tile entity to avoid NPE. Addresses BUKKIT-3949 2013-04-01 00:06:09 -05:00
Travis Watkins
311f0c86a4 Fix mismatched tile entities for new blocks. Fixes BUKKIT-3949 2013-03-31 19:38:25 -05:00
Travis Watkins
71a475f076 Don't update physics when block place is cancelled. Fixes BUKKIT-3939
When a block placement happens we currently update physics on the
attempted placement and update again if the placement is cancelled.
To correct the first one we simply set the block without applying
physics. To correct the second we have to add a new method to
BlockState that lets us update without applying physics and use
this method method when putting the block back.
2013-03-31 19:18:42 -05:00
Travis Watkins
d3dbb1bb50 Correct slot types for brewing stand. Fixes BUKKIT-3937 2013-03-31 18:41:36 -05:00
Wesley Wolfe
f859d45727 Throw exception for disabled plugin tasks. Fixes BUKKIT-3951
Without this check, any non-null reference to a plugin is considered
'valid' for registering a task in the scheduler. This is obviously
unintentional behavior and has been changed to throw an
IllegalPluginAccessException. It is now consistent with the
SimplePluginManager event registration contract.

This in affect also addresses BUKKIT-3950 for uninitialized plugin
references (ones without a description).
2013-03-31 15:37:17 -05:00
Travis Watkins
af964c8331 Limit hopper to valid directions. Fixes BUKKIT-3940 2013-03-31 13:29:13 -05:00
Travis Watkins
06ebe6b705 Add BlockHopper from mc-dev for diff visibility. 2013-03-31 13:20:30 -05:00
Travis Watkins
a1c38cd8f3 Include anvil result in inventory size. Fixes BUKKIT-3741 2013-03-30 02:51:26 -05:00
Travis Watkins
af7ea28bc7 Only call event when turning pressure plate on. Fixes BUKKIT-3881 2013-03-29 22:48:49 -05:00
Travis Watkins
82e05d435b Special case large chests for hopper events. Fixes BUKKIT-3916
Large chests work in a different fashion as they are a combination of
two other inventories. This causes their getOwner method to always return
null as their is no correct return. To compensate for this for the hopper
events we special case them to use their CraftBukkit counterpart that has
the information we need for the event.
2013-03-29 22:27:07 -05:00
Travis Watkins
ee572114dd Add Beacon block state for hopper events. Fixes BUKKIT-3932 2013-03-29 22:26:27 -05:00
EdGruberman
377be0a79e Call PotionSplashEvent even for no effects. Fixes BUKKIT-3618
When a splash potion has no applicable effects we currently do not call
PotionSplashEvent. This means plugins are unable to make custom
potions with reliable splash handling as they have to relicate the
functionality themselves.

With this commit we simply make the event fire regardless of the effects
on the potion.
2013-03-28 21:14:48 -05:00
gjmcferrin@gmail.com
adbee6049e Call appropriate event for zombies igniting players. Adds BUKKIT-3915 2013-03-28 21:10:42 -05:00
Wesley Wolfe
acd637d48b Properly copy collection references in ItemMeta.clone(). Fixes BUKKIT-3913
When cloning an item, all references are copied to the new item. For
collections, this makes internal changes become visible in both the old and
new items.

In CraftMetaItem, clone was not making copies of the appropriate collections
and has been fixed for non-null values.

In CraftMetaEnchantedBook and CraftMetaPotion, clone was using possible empty
collection references and has been changed to explicitly null-check instead.
2013-03-28 20:01:01 -05:00
Travis Watkins
1a7e5a75ae Correct missed diff on skeletons. Fixes BUKKIT-3912 2013-03-28 19:42:27 -05:00
Andre LeBlanc
08f3df82eb Improve calling of ProjectileHitEvent. Fixes BUKKIT-3872 2013-03-26 07:13:14 -04:00
riking
45d3e2514d Add missing semicolon
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
for i in range(100)
2013-03-25 17:12:22 -07:00
Kristofer Henriksson
3c02fb02a1 Allow plugins to enchant already enchanted items. Fixes BUKKIT-1956
This causes the server to generate PrepareItemEnchantEvent even in the
case that an item is already enchanted or otherwise would normally not
be enchantable.
2013-03-25 15:56:15 -07:00
Black-Hole
02a5d09ddf Call EntityChangeBlockEvent when boats destroy blocks. Fixes BUKKIT-3871 2013-03-25 16:55:48 -04:00
Andre LeBlanc
18d7bc7ca3 Allow fishing success rate to be adjustable. Adds BUKKIT-3837 2013-03-25 14:45:24 -04:00
GJ
96ba65d506 Add methods to check conflicting enchantments. Adds BUKKIT-3830 2013-03-25 10:51:54 -04:00
Travis Watkins
5f089137ee Cleanup comments, formatting, etc 2013-03-25 00:51:36 -05:00
Patrick Seidel
7c40a073d8 Add ability to change player item in hand. Adds BUKKIT-3318 2013-03-24 14:04:27 -04:00
Travis Watkins
b532042973 Don't assume all hoppers are blocks. Fixes BUKKIT-3883 2013-03-24 12:38:57 -05:00
riking
8d3ba07f93 Add check for Thorns damage - Fixes BUKKIT-3505 2013-03-23 19:45:46 -07:00
Carlos Cobo
62c6d223e4 Include ThrownPotion in spawn methods. Adds BUKKIT-2542 2013-03-23 19:05:14 -07:00
EdGruberman
e1b50b0110 Identify outside slot independent of inventory type. Fixes BUKKIT-2768 2013-03-23 16:23:03 -07:00
Dennis Bliefernicht
e61a6bab05 Implement InventoryMoveItemEvent. Adds BUKKIT-3765
This makes droppers, hoppers and hopper minecarts fire an
InventoryMoveItemEvent whenever an item is being moved from or to another
inventory.
2013-03-23 16:12:52 -06:00
me4502
b10474253c Fire VehicleEnterEvent for loaded chunks only. Fixes BUKKIT-3831 2013-03-23 10:58:01 -06:00
James Clarke
3ad423af07 ANSI color codes now reset text attributes. Fixes BUKKIT-3508
The client resets all formatting after a color code is received, but currently the ANSI codes do not, and so the console does not accurately reflect the appearance of the formatted text. Instead, the ANSI color codes are now set to reset all text attributes.
2013-03-23 00:26:22 -04:00
Travis Watkins
444ced306a Cleanup and rework physical interaction events. Fixes BUKKIT-3686
Currently when dealing with physical interactions with pressure plates
and tripwires we immediately block their activation as soon as a single
entity involved has their event cancelled. We also fire events whenever
an entity intersects the block a wooden button is in even if they aren't
actually pressing it. To correct this we move the button interaction to
the correct place and modify all three to only block the activation if
every entity is blocked from using them instead of just one of them.
2013-03-22 17:18:19 -05:00
Xephi
ae19f2c46f Implement Dropper interface. Adds BUKKIT-3750 2013-03-21 22:33:16 -06:00
Xephi
978de7e9da Add BlockDropper for diff visibility 2013-03-21 21:42:47 -06:00
Travis Watkins
6f9e4f8541 Stationary lava is also a LAVA ignition cause. 2013-03-21 16:59:45 -05:00
Olof Larsson
abee107830 Add ability to modify ThrownPotion properties. Adds BUKKIT-3197 2013-03-21 15:18:27 -04:00
AlphaBlend
2c5b2a8f6f Add method to get the source of a TNTPrimed. Adds BUKKIT-3815 2013-03-21 12:47:46 -06:00
James Clarke
816a7f1559 Ignore all .DS_Store files, not just the one in the project root. 2013-03-21 01:20:08 -04:00
Andre LeBlanc
83e0e0770a Add Fish (Hook) entity to PlayerFishEvent. Adds BUKKIT-1025 2013-03-20 15:58:37 -07:00
nitnelave
ddec7117ee Implement unit test for hasGravity(). Adds BUKKIT-3832 2013-03-20 18:44:22 -04:00
Travis Watkins
696543cf3f Update CraftBukkit to Minecraft 1.5.1 2013-03-20 15:09:23 -05:00
Travis Watkins
6aaa1e83df Really don't filter out -1 data in ItemStack. 2013-03-20 11:11:47 -05:00
Travis Watkins
b325ffc8f6 Handle filled buckets dispensing up and down. Fixes BUKKIT-3814 2013-03-20 10:24:22 -05:00
Travis Watkins
2fc755cc65 Don't filter out -1 data in ItemStack. Fixes BUKKIT-3824 2013-03-20 09:44:17 -05:00
Travis Watkins
26d1f9189a Readd missed diff for minecart container size. Fixes BUKKIT-3826 2013-03-20 09:44:17 -05:00
Nate Mortensen
dc19d3788f BlockState for Command Blocks. Adds BUKKIT-3805. 2013-03-19 20:54:38 -06:00
Edmond Poon
e639690e45 Validate Server method input. Addresses BUKKIT-3687
CraftServer methods that implement the Server interface will throw an
IllegalArgumentException if a method cannot operate on a null input
and given a null pointer.

This causes methods to fail early and identify that a plugin is
responsible for passing in an invalid argument. This will only
change the exception thrown, if there originally was a thrown
exception. This helps with hunting down legitimate problems
with CraftBukkit.
2013-03-18 23:40:10 -06:00
Warren
abee2151ea Remove point about squashing commits. 2013-03-18 23:49:15 -03:00
Kane York
370b912dd6 Add link to CONTRIBUTING.md in README 2013-03-18 19:26:15 -07:00
EvilSeph
aabfe5a560 Pull Contributing Guidelines and Requirements into CONTRIBUTING.md 2013-03-18 22:14:15 -04:00
Travis Watkins
51d4e647fb Only filter data on block items, not all items. 2013-03-18 18:22:13 -05:00
Travis Watkins
d26336eb40 Add /testfor command support to command block. Adds BUKKIT-3813 2013-03-18 17:12:21 -05:00
Travis Watkins
596047aa6b Only set player weather if a plugin requested it.
If the server changes the weather it will set the per-player weather
variable and future changes will not apply. We should only set this
variable when a plugin is requesting per-player weather and not when
the server it doing it.
2013-03-18 13:58:16 -05:00
T00thpick1
1bde25bb33 Implement per-player Weather API. Adds BUKKIT-812 2013-03-18 13:03:54 -05:00
Yariv Livay
a7a5f273e3 Implement new cause versions of BlockIgniteEvent. Addresses BUKKIT-3609, BUKKIT-3656, BUKKIT-3657 2013-03-18 12:47:01 -05:00
Travis Watkins
2e6cfdb3cc Implement InventoryPickupItemEvent. Adds BUKKIT-3798 2013-03-18 12:35:43 -05:00
Michael Limiero
2642fbdf7e Make CraftMinecartHopper work as InventoryHolder. Adds BUKKIT-3796 2013-03-18 12:16:37 -05:00
Chad Waters
93fd33e218 Implement Entity.isOnGround(). Adds BUKKIT-3787 2013-03-17 22:25:05 -05:00
Travis Watkins
5df704bf5a Use name given to command block instead of "@". Fixes BUKKIT-3803 2013-03-17 20:19:32 -05:00
Michael Limiero
d802168cd5 Implement Hopper block state and inventory methods. Adds BUKKIT-3749 2013-03-17 12:59:27 -05:00
Travis Watkins
6f68fc4ba4 Add missing getOwner method for container minecarts. 2013-03-16 18:32:01 -05:00
Travis Watkins
737e8c5127 Allow special crafting data value on items. Fixes BUKKIT-3780 2013-03-16 18:16:00 -05:00
Travis Watkins
5515b0ee2b Handle double trapped chest inventory. Fixes BUKKIT-3772 2013-03-16 17:14:21 -05:00
Travis Watkins
0e60f1f7b8 Fire BlockDispenseEvent for new dispenser behaviors. Fixes BUKKIT-3774 2013-03-16 16:55:27 -05:00
Travis Watkins
fbe609bdbe Add new DispenseBehavior files from mc-dev for diff visibility. 2013-03-16 16:48:08 -05:00
Travis Watkins
ff1c1daf69 Allow data on tool items. Fixes BUKKIT-3773 2013-03-16 14:51:22 -05:00
Travis Watkins
2e47a1eb80 Comment out vanilla debug message. 2013-03-16 13:45:42 -05:00
Travis Watkins
515830cda9 Filter negative values for all items. 2013-03-16 13:26:29 -05:00
Travis Watkins
6d88d545e9 Filter data for items that shouldn't have it and filter wool.
We used to fall Item.filterData() for this but that method is meant for
converting item data to block data during placement and does the wrong
thing for this case. Instead we just see if the item should have data and
if not set it to zero. We also have to filter wool data explicitly because
clients crash when given invalid wool data.
2013-03-16 13:14:09 -05:00
Travis Watkins
a76a5bd36f Ignore invalid inventory slots. Fixes BUKKIT-3737 2013-03-16 10:28:12 -05:00
Travis Watkins
9a38f2022a Use Chest block state for trapped chests. Fixes BUKKIT-3762 2013-03-16 09:46:32 -05:00
Travis Watkins
5903b9f5ca Don't set health directly, will interfere with scoreboard system. 2013-03-16 08:57:57 -05:00
Travis Watkins
7466321212 Limit mob names to 64 chars to avoid client crash. Fixes BUKKIT-3753 2013-03-16 08:32:31 -05:00
Travis Watkins
4fa8c24e42 Always consume bonemeal when used on a sapling. Fixes BUKKIT-3755
In Minecraft 1.5 saplings do not grow with a single use of bonemeal anymore.
Our code assumes they will and only takes away bonemeal from the player
when the tree grows successfully (not cancelled by a plugin). Instead we
now always remove a bonemeal even if a plugin is the reason a tree didn't
grow as this matches the vanilla logic more closely.
2013-03-16 08:05:03 -05:00
Travis Watkins
d47849df8c Remove duplicate place logic for snow. Fixes BUKKIT-3756 2013-03-16 07:38:54 -05:00
Wesley Wolfe
2cb9cbf05c Handle the newly refactored minecarts. 2013-03-16 02:15:51 -05:00
Travis Watkins
b2c72b968e Use proper naming convention for boolean methods. 2013-03-15 14:25:37 -05:00
Travis Watkins
83d29e461c Update CraftBukkit to Minecraft 1.5 2013-03-15 13:28:59 -05:00
Wesley Wolfe
ba6e4c38cf Fix compilation error with exception names 2013-03-02 16:33:35 -06:00
Nate Mortensen
032c7366ad Use the correct CB object for ContainerBrewingStand. Fixes BUKKIT-3357 2013-03-02 16:01:14 -06:00
Eimref
cf7dfeda62 Add proper logging for custom channel exceptions. 2013-03-02 15:57:00 -06:00
Travis Watkins
f6c574dd04 Implement PlayerItemConsumeEvent. Adds BUKKIT-2349 2013-03-02 00:33:46 -06:00
Andrzej Pomirski
993e19b3fb Close inventory on teleport. FIXES BUKKIT-3021. 2013-02-10 17:22:34 -06:00
EdGruberman
d06e597ca5 Check TravelAgent.findOrCreate(Location) for null; Fixes BUKKIT-3590
If a custom TravelAgent is used and returns null for findOrCreate method
a NullPointerException will occur.
Conflicts:
	src/main/java/net/minecraft/server/PlayerList.java
2013-02-10 17:21:59 -06:00
James Clarke
5bb81b75c7 Set CraftTravelAgent.DEFAULT to a non-null value. Fixes BUKKIT-3578
Currently, CraftTravelAgent will call s() on the passed-in WorldServer in order to set DEFAULT. However, s() will always return null at this point, because WorldServer.P will still be null, as it is set after the constructor is called. Instead, we set CraftTravelAgent.DEFAULT to the instance that is being constructed.
2013-02-06 16:45:22 -06:00
feildmaster
2e99e02094 Use entity UUID instead of EntityID for metadata. Fixes BUKKIT-3582
The entity id is a non-unique, non-persistent value, and will cause
entities to lose their respective meta data on chunk unloading, and
teleportation.
2013-02-06 16:32:19 -06:00
EdGruberman
efe8e9a7f5 Always return a TravelAgent; Fixes BUKKIT-3541
Recent changes caused PlayerPortalEvent to suddenly return null
unexpectedly and could end up in NPEs resulting that did not before.
This commit addresses that situation by always ensuring a TravelAgent
instance is returned.

The TravelAgent for world 0 is returned arbitrarily in an effort to
compensate for plugins that are implementation dependent and expect some
form of a TravelAgent to be accessible in the event at all times.
2013-02-04 18:53:06 -06:00
James Clarke
4d3865a036 Fix players spawning above portals. Fixes BUKKIT-3542.
Vanilla does not check for blocks in which the player could
suffocate when changing dimension, so portals will happily spawn
players in blocks when using a portal under certain
circumstances. However, we currently check for these instances
and move the player up until they will not suffocate. This means
that players can sometimes be taken to above the target portal,
making it seem as if a portal was not created. Instead, we now
disable this suffocation check when moveToWorld is called from
changeDimension, mirroring vanilla behavior more accurately.
2013-02-04 18:53:05 -06:00
James Clarke
d661c67a70 Always use the set exit location for portal events. Fixes BUKKIT-3555. 2013-02-04 18:53:04 -06:00
James Clarke
94da64ee93 Use the result of EntityPortalExitEvent. Fixes BUKKIT-3559. 2013-02-04 18:53:03 -06:00
EvilSeph
1090e0cf46 Updated version to 1.4.7-R1.1-SNAPSHOT for development towards next release. 2013-01-30 23:44:50 -05:00
EvilSeph
416f1d6ccf Updated version to 1.4.7-R1.0 in pom.xml for RB. 2013-01-30 23:32:21 -05:00
feildmaster
b4b7cacf5e Fix NPE when getting bed spawn location. 2013-01-29 17:25:39 -06:00
feildmaster
37975946a2 Fix contract with Player.getBedSpawnLocation. Fixes BUKKIT-3525
Getting the bed spawn location is supposed to check if the bed is
valid, however, it currently did not do so.
2013-01-29 10:11:57 -06:00
feildmaster
0576395ddd When leaving the end, always target the main world. Fixes BUKKIT-3517 2013-01-29 09:48:52 -06:00
feildmaster
b0e43c8097 Make command blocks only select players on its world. Fixes BUKKIT-3515 2013-01-28 17:01:08 -06:00
EdGruberman
132fdbc4ac Target default world when returning from The End; Fixes BUKKIT-3494
Due to the having to generate new logic to avoid using the customized
PlayerConnection.moveToWorld, entities returning from The End were not
properly calculating their exit target.  This commit corrects that
logic.
2013-01-28 11:26:32 -06:00
Wesley Wolfe
50e74b3b49 Remove erroneous break statement in scheduler. Fixes BUKKIT-3395 2013-01-27 23:00:14 -06:00
feildmaster
1053a1e29d Update Fireballs to account for ExplosionPower. Fixes BUKKIT-3460
Adds BUKKIT-3516
2013-01-27 16:43:30 -06:00
feildmaster
f20d6e3595 Ignore block functions for skulls on BlockPlace. Fixes BUKKIT-3495
Skulls don't normally get block data applied to them, so we shouldn't
apply it either.
2013-01-27 11:31:27 -06:00
feildmaster
899b9c17cc Direct all BlockPlaceEvents to a singular location. Fixes BUKKIT-3438
By having a single function to process BlockPlacement logic, we make
it so that there is consistent behavior throughout all BlockPlace
events. This should allow for easier troubleshooting and less diffs
in source.

This also fixes BUKKIT-3463 by including the correct coordinates that
were clicked to the event.
2013-01-27 10:44:32 -06:00
feildmaster
528bbbdcd8 Fix TileEntities and Blocks getting out of sync. Fixes BUKKIT-3501
Also fixes: BUKKIT-3477 and BUKKIT-3488

Minecraft likes to double check that tile entities get set after they
are placed, however we didn't set tile entities until after our event
was called. This caused the world to have multiple tile entities in a
single block location; to fix this we now set tile entities before
the event.
2013-01-27 10:34:59 -06:00
QuarterAnimal
6e438ccb32 Call BlockGrowEvent for Cocoa plants. Fixes BUKKIT-2525 2013-01-24 19:57:52 -06:00
QuarterAnimal
d74cf36f1c Add BlockCocoa for diff visibility. 2013-01-24 19:57:15 -06:00
QuarterAnimal
b82375a596 Preserve source block in mushroom spread event. Fixes BUKKIT-3354 2013-01-24 19:50:21 -06:00
feildmaster
f10c986136 Properly calculate level cost for books. Fixes BUKKIT-3410 2013-01-24 18:10:03 -06:00
feildmaster
f1efe717bd Call BlockPlaceEvent for skulls the same as other blocks. BUKKIT-3406
When the skull BlockPlaceEvent was added it was made so the event
would be called after all the data has been set, however this is a
behavior change that is inconsistent with other BlockPlaceEvents.
Instead, if people wish to get the block data they should schedule
a task.

Relates to: BUKKIT-3438
2013-01-23 20:41:05 -06:00
EdGruberman
9df87d3399 Compensate for allow-nether/allow-end as false; Fixes BUKKIT-3466
When either of those settings are false, the worlds are not loaded and
therefore will not be targeted for portal exits.  Existing worlds are
iterated directly to avoid defaulting to the first world if a direct
dimension match is not found.

Plugins must also specify exit from custom Bukkit worlds to comply with
original commit: https://github.com/Bukkit/CraftBukkit/commit/2dc2af0

This commit introduces a constant to clarify the dependency on the
CraftBukkit implementation of custom worlds having a dimension offset.
2013-01-23 20:11:01 -06:00
feildmaster
488e45b4ff Reload ban files when reloading the server. Adds BUKKIT-3470 2013-01-23 06:24:40 -06:00
feildmaster
641ecc4f34 Return the valid max value for piston direction. Fixes BUKKIT-2191
By returning the following value (7) we remove the need to special
case pistons in any way (other than the original purpose of this
check, which is to ensure pistons have valid data)
2013-01-23 06:15:21 -06:00
feildmaster
9ba0ddc292 Refactor processBlockPlace logic. Fixes BUKKIT-3406 and BUKKIT-3454
The previous logic was faulty since it lost the logic of "placing" the
block. It was also taking into account data that could have been
changed outside of the processing of this event, which is irrelevant
to the processing of this event.
2013-01-19 08:14:17 -06:00
feildmaster
6a499c8589 Fix broken null contract with Jukebox.setPlaying, Fixes BUKKIT-3429
The javadocs state that a null may be used to remove the currently
playing sound, however this causes a NullPointerException.

It also doesn't process registering the record correctly, along with
processing non-valid items.
2013-01-19 08:14:17 -06:00
EdGruberman
d834ca4c6c [Bleeding] Add experimental support for entity portal traveling 2013-01-19 06:20:33 -06:00
EdGruberman
9cb320654d Add BlockEnderPortal for diff visibility 2013-01-19 06:20:32 -06:00
Wesley Wolfe
01fc296fef Improve the item meta deserialization code-style
Fixed the ItemMetaFireworkTest

Add set power unit tests for FireworkMeta
2013-01-18 02:58:07 -06:00
Zloteanu Nikita
5934a65729 Always call PotionSplashEvent. Fixes BUKKIT-3363
This change allows plugins to add recipients to a PotionSplashEvent
when it would have otherwise had none.
2013-01-17 22:55:09 -06:00
feildmaster
d577b840d4 Place beds with the correct data. Fixes BUKKIT-3447 2013-01-17 12:17:37 -06:00
EvilSeph
3d133d7abd Updated version to 1.4.7-R0.2-SNAPSHOT for development towards next release. 2013-01-17 05:30:48 -05:00
EvilSeph
ed817d199b Updated version to 1.4.7-R0.1 in pom.xml for Beta. 2013-01-17 05:15:55 -05:00
feildmaster
e59af9908b Update CraftBukkit to Minecraft 1.4.7 2013-01-17 03:50:24 -06:00
feildmaster
315127782a Initialize entity data before spawning them. Fixes BUKKIT-3209
Vanilla does the initialize before spawning everywhere except in the
SpawnerCreature, our spawn event depends on this behavior to be
consistent.
2013-01-16 23:05:18 -06:00
bloodmc
b581068464 Fix entities traveling sideways. Addresses BUKKIT-3443
Original: Update mappings to correct 1.4.6 version.
2013-01-16 23:05:18 -06:00
feildmaster
ccbd3d84e8 Get the BlockState before changing the block. Fixes BUKKIT-3441 2013-01-16 20:21:38 -06:00
feildmaster
98aea835b5 Handle beds and doors the same way as other blocks. Fixes BUKKIT-3437
Relates to: BUKKIT-3438
2013-01-16 08:06:00 -06:00
feildmaster
614ef2f8c5 Throw BlockPlaceEvent when placing double slabs. Fixes BUKKIT-2469 2013-01-16 08:05:59 -06:00
Wesley Wolfe
647b82032b Add ItemStackMapTest
This test was missing from c056293b38cb9a1296937d91746b175252be044a
2013-01-15 01:22:53 -06:00
cexikitin
8bc9e712e1 Spawn monsters without prematurely exiting. Fixes BUKKIT-3425
By using return 0, we exit the loop prematurely preventing other
creature types from being spawned if one type is set to 0. By using
continue we move on to the other types and allow them to spawn
properly.
2013-01-14 19:24:08 -06:00
Wesley Wolfe
dd7ba4a258 Various ItemMeta fixes.
Fixes BUKKIT-3408, BUKKIT-3190, BUKKIT-3191, BUKKIT-3407

These changes relate mostly to semantical changes for serialization
contract, exception of changing the map scaling value from byte to boolean,
what it should have been in the first place. Appropriate unit tests were
added for CraftMapMeta, as they were missing.
2013-01-09 05:04:08 -06:00
Wesley Wolfe
43865e8e67 Update unit test to reflect firework color fix. Fixes BUKKIT-3382
The ItemDye color-int array uses dye data values, not wool.
2013-01-05 17:16:19 -06:00
Wesley Wolfe
182681e384 Update calls to DyeColor getData and getByData. Addresses BUKKIT-2786
These two methods are now deprecated and replaced by the strictly
equivalent calls using wool data.
2013-01-05 17:15:49 -06:00
feildmaster
baaf8e1d86 Implement fishing experience. Adds BUKKIT-3348 2013-01-01 23:59:47 -06:00
feildmaster
fb0be1fc0a Move the tile entity with the falling block. Adds BUKKIT-3349
Allows for interesting things to be done with world.spawn()
2013-01-01 23:58:46 -06:00
feildmaster
8f0c1aed6b Fix "setSitting" on tameable animals. Fixes BUKKIT-1534
This makes it so animals (tame or not) will sit properly and not move
around.

Wild animals that are sitting may override the sitting position if
they are attacking.
2013-01-01 22:28:44 -06:00
feildmaster
05512942db Add PathfinderGoalSit for diff visibility 2013-01-01 22:28:43 -06:00
EvilSeph
95098c9435 Updated version to 1.4.6-R0.4-SNAPSHOT for development towards next release. 2012-12-31 01:14:07 -05:00
EvilSeph
2e1033215b Updated version to 1.4.6-R0.3 in pom.xml for Beta. 2012-12-31 01:00:18 -05:00
Mike Primm
32924f9757 [Bleeding] Fix corruption due to thread safety issues. Fixes BUKKIT-3333
The 'tag' NBTTagCompound field of the ItemStack assumes that it is OK to
save a reference to an NBT supplied via load() and assumes it is OK to
supply a reference to the internal field during a save(). Neither is true,
as Chunk NBT structures are required to be read-only once created (due to
being written asynchronously off the server thread AND due to the potential
to be passed to a new Chunk if the same chunk is reloaded before the
writing of the NBT is completed by the File I/O thread). Keeping a live
reference to the NBT copy passed in, or to the NBT value passed back
during saving, creates serious thread safety issues which can result in
corrupted data being written to the world data files.

The specific issue here was uncovered by the recent change to use
setName("") on the ItemStack.tag object. When a chunk is being loaded
again before its save is completed, this results in name of the field
in the NBT being set to "". This causes it to be saved as "" instead
of "tag" resulting in it not being properly reloaded in the future which
results in the itemstack losing all of its metadata.
2012-12-30 23:31:22 -06:00
EvilSeph
6bb240cdf0 Updated version to 1.4.6-R0.3-SNAPSHOT for development towards next release. 2012-12-29 22:27:49 -05:00
EvilSeph
4047542d65 Updated version to 1.4.6-R0.2 in pom.xml for Beta. 2012-12-29 22:19:49 -05:00
Wesley Wolfe
bb83795815 Return the level, not ID. Fixes BUKKIT-3326
CraftItemStack was erroneously using the enchantment ID instead of level
for the return value of remove enchantment.
2012-12-29 20:53:27 -06:00
Wesley Wolfe
8954cb291c /dev/null does not accept EnchantmentThorns 2012-12-29 19:18:37 -06:00
feildmaster
7b5a8d0c23 Don't teleport entities that are considered dead. Addresses BUKKIT-1331
Teleportation should never be processed on dead entities. If you wish
to teleport an entity, do it on a living entity. If you wish to
teleport a player, set their respawn location in PlayerRespawnEvent.
2012-12-29 19:18:36 -06:00
Mike Primm
fb0eed177a [Bleeding] Implement periodic chunk garbage collector
This adds two settings to bukkit.yml, allowing activation and control of
two chunk garbage collection triggering conditions:
chunk-gc/period-in-ticks controls a periodic GC, run once every N ticks
(default is 600); chunk-gc/load-threshold causes the GC to run once
after every N calls to loadChunk() on a given world (this call is an API
call used by plugins, and is distinct from the path taken for routine
player movement-based loading).  In both cases, setting to zero will
disable the given GC scheduling strategy.

In either case, the act of doing the GC is simply one of scanning the
loaded chunks, seeing which are NOT being used by one or more players
(due to view-distance) and which are not already queued for unload, and
queueing them for a normal unload.  Ultimately, the unload is then
processed the same as if the chunk were unloaded due to leaving the
view-distance range of all players, so the impact on plugins should be
no different (and strategies such as handling the ChunkUnloadEvent in
order to prevent unload will still work).

The initial interval for the periodic GC is randomized on a per-world
basis, in order to avoid all world being GCed at the same time -
minimizing potential lag spikes.
2012-12-29 16:50:05 -06:00
feildmaster
538de63a03 Fix persistence on tamed pets. Fixes BUKKIT-3300
With the persistence api introduced, pets did not have their
persistence flag updated to reflect their persistence. This caused
tame ocelots to not persist under specific conditions.
2012-12-28 20:27:41 -06:00
feildmaster
509e3d2a32 Update maxhealth for entities that have variable max health. Fixes BUKKIT-3308
Slimes and wolves have health that can change based on certain
conditions. So we check if their max health should be updated, and if
it has been customized in any way.

We also scale the wolf's health for their tail
2012-12-27 21:05:40 -06:00
feildmaster
b908c192bf Fix removing enchantments causing the enchantment tag to remain. 2012-12-27 20:48:56 -06:00
feildmaster
54b2707ba7 Fix discrepancies in NBT and ItemMeta. Fixes BUKKIT-3279
An ItemStack gains the tag name "tag" when the stack is serialized
to NBT, however items don't have a tag *until* they are serialized at
least once. So to solve this, we remove the tag name when loading the
NBT data.

Another problem with NBT are TagLists, when transferring tag lists
between the server and the client the names are lost, and so we
simply don't add a name to the tag.
2012-12-27 20:45:21 -06:00
Travis Watkins
25732f0487 Fire BlockRedstoneEvent for repeaters. Fixes BUKKIT-1157 2012-12-27 15:40:18 -06:00
Travis Watkins
186a679730 Add BlockDiode from mc-dev for diff visibility. 2012-12-27 15:26:49 -06:00
Wizjany
5963da294f Don't update physics until after the place event. Fixes BUKKIT-3316
If you cancel a BlockPlaceEvent for a sign the world is updated as if
the block was placed and then destroyed. To avoid this we set the block
without updating physics then apply the update after the event.
2012-12-27 15:22:19 -06:00
cexikitin
49da990ee3 Never remove players when unloading chunks. Fixes BUKKIT-3129
When unloading chunks we have a check to ensure we do not remove players
from the world due to the issues this would cause. However, our check
to see if the player is in this chunk is reversed and is in fact entirely
wrong. Even if the player isn't currently in this chunk we do not want
to remove them as that will still cause the same issues.
2012-12-27 15:16:33 -06:00
feildmaster
3a0c5aff0c Fix fireballs being motionless (again). Fixes BUKKIT-3299
The key "direction" incorrectly mapped to variables that were already
set in the entity. In order to prevent loading incorrect data we
renamed "direction" to "power."
2012-12-25 05:58:49 -06:00
feildmaster
155b83e2c7 Perform permission removals after the quit event. Fixes BUKKIT-3303
The player would have no permissions (other than their OP status)
when checked in the Quit event. This is because we removed permissions
before the event occurred. By calling it afterwards, we can persist
the data until the server finally removes the player.
2012-12-24 22:11:04 -06:00
feildmaster
f726d07f11 Fix Skull BlockState setting illegal values on owner. 2012-12-24 14:32:08 -06:00
feildmaster
8292b73f30 Fix fireworks being short lived. Fixes BUKKIT-3291 2012-12-23 17:06:26 -06:00
feildmaster
edd90ccf16 Properly update fireworks. Fixes BUKKIT-3289 2012-12-23 08:59:15 -06:00
feildmaster
ced0646351 Implement entity max health methods. Adds BUKKIT-266 2012-12-23 07:29:06 -06:00
feildmaster
4e1793f363 Report valid health when getting Entity health. Fixes BUKKIT-3210 2012-12-23 07:29:05 -06:00
Wesley Wolfe
ed6aab8200 Remove runner leak on async tasks. Fixes BUKKIT-3288
In some situations, an async task could be cancelled with no tasks
pending. This means the finally {} block from run() never gets executed
properly on the last async task to have run, as it expected to be
executed again.

This fix takes the only spot that the task period is set to cancelled
and will check to see if the task should be purged from the runners
list.
2012-12-23 05:13:33 -06:00
Travis Watkins
717fbbeffa Update firework power when modifying meta. Fixes BUKKIT-3272 2012-12-22 13:07:18 -06:00
Travis Watkins
f72a08c22e Fire BlockDispenseEvent for fireworks. Adds BUKKIT-3246 2012-12-22 13:07:18 -06:00
Travis Watkins
da571ef428 Add DispenseBehaviorFireworks and EntityFireworks for diff visibility 2012-12-22 13:06:55 -06:00
feildmaster
dc85940526 Allow fireworks to be created. Adds BUKKIT-3262 2012-12-22 12:24:16 -06:00
Wesley Wolfe
6dc13b688a One record per JukeBox. 2012-12-22 05:48:11 -06:00
Wesley Wolfe
2fd78a6549 Add BlockJukeBox for diff visibility 2012-12-22 05:45:52 -06:00
EvilSeph
adc1c2f982 Updated version to 1.4.6-R0.2-SNAPSHOT for development towards next release. 2012-12-22 01:24:14 -05:00
EvilSeph
e6f14b4be5 Updated version to 1.4.6-R0.1 in pom.xml for Beta. 2012-12-22 01:12:16 -05:00
feildmaster
2ee62eb580 Implement API to get and set FireworkMeta on Firework entities 2012-12-21 23:56:54 -06:00
meiskam
fdb4b2d911 Implement Skull BlockState. Adds BUKKIT-3259 2012-12-21 22:47:11 -06:00
meiskam
39e2af7bd1 Added TileEntitySkull for diff visibility 2012-12-21 21:56:47 -06:00
Wesley Wolfe
78d384de93 Zero is not less than zero. Fixes BUKKIT-3259 2012-12-21 21:48:09 -06:00
feildmaster
a0cf0d03f4 Check file existence before determining readOnly. Fixes BUKKIT-3255 2012-12-21 19:31:39 -06:00
feildmaster
ec211ed952 Update enchantment handling to 1.4.6. Fixes BUKKIT-3256 2012-12-21 19:31:28 -06:00
feildmaster
f71be2506d Fix loading Items entities with an invalid item. Addresses BUKKIT-3249 2012-12-21 16:07:59 -06:00
feildmaster
118682ce5c Don't save server properties when it's read only. Fixes BUKKIT-3250 2012-12-21 15:40:39 -06:00
feildmaster
0216d09033 Fix command line arguments being ignored. Fixes BUKKIT-3247 2012-12-21 15:40:39 -06:00
feildmaster
e937307596 Add a null check for Item Entities. Fixes BUKKIT-3249 2012-12-21 15:40:27 -06:00
Wesley Wolfe
b870755edb Use max inventory size for new stack. Fixes BUKKIT-3240 2012-12-21 11:10:23 -06:00
Wesley Wolfe
708252c020 Implement 1.4.6 ItemMeta. Adds BUKKIT-3236, BUKKIT-3237
Some meta functionality is refactored into common methods.

CraftItemStack uses the ItemMetaKey identifiers for enchantments.

Refactored unit test to include extra functionality; initially only
checking the presence of the DelegateDeserialization annotation.
2012-12-21 10:36:34 -06:00
Wojciech Stryjewski
f377a7680f Add API to allow plugins to request players switch to a texture pack. Adds BUKKIT-2579
The setTexturePack method causes the player's client to
download and switch to a texture pack specified by a URL.

Note: Players can disable server textures on their client, in which
case this API would not affect them.
2012-12-20 22:09:38 -05:00
feildmaster
f4836fb428 Add the ability to make Enchanted Books. Fixes BUKKIT-3220 2012-12-20 20:51:51 -06:00
feildmaster
bd0daa6d54 Remove obsolete fix for the end
The end was getting block offsets, causing client side issues.
2012-12-20 19:15:37 -06:00
Travis Watkins
ca7f67da9d Fetch correct info for skulls in block.getDrops(). Fixes BUKKIT-3205 2012-12-20 15:06:01 -06:00
Mike Primm
ed2dd31a80 [Bleeding] Fix exception in getChunkSnapshot() - sky light can be null 2012-12-20 14:22:25 -06:00
feildmaster
686807e387 Filter invalid ItemStacks from Packets.
Invalid ItemStacks are causing Fireworks to disconnect players and
prevent them from reconnecting
2012-12-20 10:52:44 -06:00
feildmaster
23b6764374 Update CraftBukkit to Minecraft 1.4.6 2012-12-20 10:43:00 -06:00
EvilSeph
9f1bf124ee Updated version to 1.4.5-R1.1-SNAPSHOT for development towards next release. 2012-12-19 06:15:47 -05:00
EvilSeph
06ae8e4826 Updated version to 1.4.5-R1.0 in pom.xml for RB. 2012-12-19 06:08:22 -05:00
mbax
924a46469d [Bleeding] Check visibility API for sounds. Fixes BUKKIT-3114
With 1.4, entity sound tracking changed for the better.
Our previous method additions can now be removed.
All that's left is checking if the source can be seen
by the recipient of the sound packet. Thanks, Mojang!
2012-12-18 19:02:20 -06:00
feildmaster
d9708d032e Fix PotionMeta not applying the correct Id. Fixes BUKKIT-3193 2012-12-18 18:43:53 -06:00
feildmaster
d73e5ab469 Add missing name in PotionEffect for Wither 2012-12-18 18:20:11 -06:00
feildmaster
a2d551fafa Refactor get/setChestPlate to Chestplate. Addresses BUKKIT-3189 2012-12-18 03:46:58 -06:00
Wesley Wolfe
6cec8ba5cb Change enchantment comparisons to isSimilar. Fixes BUKKIT-3183
The purpose of the isSimilar method was designed to consider all NBT
data, not solely enchantments, without the need to have exact stack
size matches. The respective methods in CraftInventory were still
comparing enchantments instead of the ItemMeta.
2012-12-17 16:43:16 -06:00
Wesley Wolfe
d66d3674ea Clarify functionality in CraftInventory. Fixes BUKKIT-3097
Changes some NPEs to IllegalArgumentExceptions for exception consistency.

Contains(ItemStack, int) correctly calculates number of ItemStacks.

Adds a containsAtLeast(ItemStack, int) for finding a combined amount of a
single similar ItemStack.

Makes some utility methods private to prevent ambiguity in use.
2012-12-17 16:39:25 -06:00
Wesley Wolfe
78f48258d8 Implement ItemFactory and ItemMeta values. Adds BUKKIT-15 2012-12-17 01:31:41 -06:00
feildmaster
d20d4dc43a ItemStack.asBukkitStack(null) should return Air. Fixes BUKKIT-3170 2012-12-15 01:52:42 -06:00
Wesley Wolfe
0f4c206f9b Add isRecord and new material method tests.
Cleaned up all of the CraftBukkit tests, including moving some tests
from MaterialTest to PerMaterialTest.
2012-12-14 02:02:02 -06:00
deathmarine
53b064ec79 Fix EntityEquipment positions being reversed. Fixes BUKKIT-3157 2012-12-12 22:20:44 -06:00
Travis Watkins
24143ef6a1 Load chunks asynchronously for players.
When a player triggers a chunk load via walking around or teleporting there
is no need to stop everything and get this chunk on the main thread. The
client is used to having to wait some time for this chunk and the server
doesn't immediately do anything with it except send it to the player. At
the same time chunk loading is the last major source of file IO that still
runs on the main thread.

These two facts make it possible to offload chunks loaded for this reason
to another thread. However, not all parts of chunk loading can happen off
the main thread. For this we use the new AsynchronousExecutor system to
split chunk loading in to three pieces. The first is loading data from
disk, decompressing it, and parsing it in to an NBT structure.  The second
piece is creating entities and tile entities in the chunk and adding them
to the world, this is still done on the main thread. The third piece is
informing everyone who requested a chunk load that the load is finished.
For this we register callbacks and then run them on the main thread once
the previous two stages are finished.

There are still cases where a chunk is needed immediately and these will
still trigger chunk loading entirely on the main thread. The most obvious
case is plugins using the API to request a chunk load. We also must load
the chunk immediately when something in the world tries to access it. In
these cases we ignore any possibly pending or in progress chunk loading
that is happening asynchronously as we will have the chunk loaded by the
time they are finished.

The hope is that overall this system will result in less CPU time and
pauses due to blocking file IO on the main thread thus giving more
consistent performance. Testing so far has shown that this also speeds up
chunk loading client side although some of this is likely to be because
we are sending less chunks at once for the client to process.

Thanks for @ammaraskar for help with the implementation of this feature.
2012-12-12 19:35:53 -06:00
Travis Watkins
11593b4592 Add RegionFile from mc-dev for diff visibility 2012-12-12 04:05:47 -06:00
Wesley Wolfe
29d7cc711b Add utility class AsynchronousExecutor
This class is a general purpose task execution system, that uses stages
to separate processing blocks for asynchronous and synchronous
executions.
2012-12-12 04:05:47 -06:00
Travis Watkins
24c04dc784 Don't run mob pickup code on players. Fixes BUKKIT-3150
When a player has canPickUpLoot set to true the code for mob pickup is
triggerd which does not know how to deal with player inventory. Since
players have their own logic for picking up items we simply disable this
code for them.
2012-12-12 03:08:14 -06:00
feildmaster
4e91fbd0db Fix players not being able to pickup items due to default values.
The old flag for picking up loot was default to false, making existing players not able to pickup items. We now use this flag for Players, which gives us the problem we had in 48b46f83.

To fix this, we add an incremental flag that will be cross-examined to check if the data was saved before or after the flag level was introduced.

Addresses BUKKIT-3143
2012-12-11 06:05:54 -06:00
feildmaster
39fdb56200 Players should be able to pick up items by default. Fixes BUKKIT-3143
As an added feature, players defaulted to being able to not pick up items if the flag was false. However, since minecraft doesn't normally use the flag on players, the flag was always false.
2012-12-10 20:27:40 -06:00
feildmaster
3692209fe6 Missed a rename 2012-12-10 19:17:47 -06:00
feildmaster
430d352a5a Add EntityEquipment API. Adds BUKKIT-3103
Adds:
- Getting/Setting equipment
- getting/setting drop rates
- getting/setting ability to pick up items
-- As an added feature, players with this flag start off with a canceled PlayerPickupItemEvent
2012-12-10 19:01:50 -06:00
h31ix
684ba31c39 [Bleeding] Correct getEyeHeight value. Fixes BUKKIT-3130 2012-12-10 01:41:00 -06:00
feildmaster
22b1100001 Only display help aliases when there are aliases. Fixes BUKKIT-1621 2012-12-10 01:40:22 -06:00
feildmaster
dc93da8e34 Pass null help values values as empty strings to HelpTopics
Fixes BUKKIT-2618 and BUKKIT-2561
2012-12-10 01:40:21 -06:00
EdGruberman
f18b3cdc76 [Bleeding] Fix NPE with a null bedSpawnLocation. Fixes BUKKIT-1500 2012-12-10 01:40:20 -06:00
Wesley Wolfe
4d2a92ed47 Add isSolid() tests for each material 2012-12-09 18:15:34 -06:00
feildmaster
12c7c2f695 Implement FurnaceExtractEvent. Adds BUKKIT-2114 2012-12-08 03:58:34 -06:00
feildmaster
e760d6eb31 Add SlotFurnaceResult for diff visibility 2012-12-08 02:45:50 -06:00
EdGruberman
24abdd556d [Bleeding] Fix NPE in getBedSpawnLocation. Fixes BUKKIT-1949 2012-12-08 02:18:06 -06:00
Dark Arc
090c1a60bd Correctly shoot arrows with the spawnArrow Method. Fixes BUKKIT-3116 2012-12-08 02:15:15 -06:00
Travis Watkins
9973e7cdec Update entity state correctly when marked as persistent. Fixes BUKKIT-3123
When a mob is marked with the persistent flag (animal or anything with
setRemoveWhenFarAway(false)) the entire block of code for checking if they
should be despawned is skipped. However, one part of this code updates the
mob state if a player is close enough to them. It turns out this state is
used by the AI system to decide if the mob should move around randomly or
not. To stop mobs from being frozen in place we now update this state if
the persistent flag is set as well.
2012-12-07 21:18:51 -06:00
Travis Watkins
846a22304c Provide a faster way to get a location. Adds BUKKIT-3120
Currently when a plugin wants to get the location of something it calls
getLocation() which returns a new Location object. In some scenarios this
can cause enough object creation/destruction churn to be a significant
overhead. For this cases we add a method that updates a provided Location
object so there is no object creation done. This allows well written code
to work on several locations with only a single Location object getting
created.

Providing a more efficient way to set a location was also looked at but
the current solution is the fastest we can provide. You are not required
to create a new Location object every time you want to set something's
location so, with proper design, you can set locations with only a single
Location object being created.
2012-12-07 21:15:05 -06:00
feildmaster
c74fd4196f Use shooter constructor for Fireballs. Fixes BUKKIT-3121
Fixes fireballs exploding in the shooter's face and not having a shooter for the projectile. (Two birds with one stone!)
2012-12-07 05:25:20 -06:00
feildmaster
78bc0ad1d5 Add the ability to launch WitherSkulls. Fixes BUKKIT-3106 2012-12-07 05:25:11 -06:00
feildmaster
72ee1f3182 Fix "Commands Only" chat flag. Fixes BUKKIT-2238
Thanks for the commit @mrapple
2012-12-07 05:22:00 -06:00
feildmaster
6a04fd98ad Implement API for wolves collar color. Adds BUKKIT-3109 2012-12-05 18:08:31 -06:00
feildmaster
bb60e85fff Not enough testing went into this, you can't have packages start with numbers. 2012-12-05 16:24:00 -06:00
Wesley Wolfe
453f49abd9 Refactor all OBC, libs, and NMS into versioned packages.
org.bukkit.craftbukkit and net.minecraft.server will now include the
minecraft version in the package name. As the internal implementations
are known to change dramatically, this refactor reduces the strain on
support requests due to version mismatching.

org.bukkit.craftbukkit.libs will also have version numbers for each
imported set of packages. These are not dictated by the minecraft
version number. This is done to prevent future incompatibilities.
2012-12-05 14:43:45 -06:00
Travis Watkins
1af83da760 Don't run command blocks in empty worlds. Fixes BUKKIT-3094 2012-12-05 13:37:13 -06:00
feildmaster
09684ba9d7 Persistence isn't just animals. Fix BUKKIT-3105
Also set to this value if the persistence hasn't been updated
2012-12-05 12:28:09 -06:00
feildmaster
fb6d9e1808 Add a custom shutdown message set in bukkit.yml. Addresses BUKKIT-3031 2012-12-05 06:07:10 -06:00
Travis Watkins
320712aba7 Allow placing blocks in spawn if ops.txt is empty. Fixes BUKKIT-3004 2012-12-05 05:01:15 -06:00
Travis Watkins
5409d05d3a Ensure animals don't despawn due to old default setting.
The old default for the persistent flag on mobs was false which was then
written out to their NBT data when they were saved. We now use this data
for all mobs, not just non-animal mobs. However, this means animals that
spawned before that change will now start despawning like monsters do.

To avoid this we add a new flag to the mob's saved data to mark if the
data was saved before or after we started using it and ignore it if it
was before.
2012-12-04 23:15:53 -06:00
Wesley Wolfe
b854320fc8 Fire EntityFormBlockEvent for FallingBlocks. Adds BUKKIT-3078 2012-12-04 22:38:51 -06:00
Travis Watkins
4dadf0e2b5 Implement API for mob despawn when away from players. Adds BUKKIT-2986
As of 1.4 mobs have a flag to determine if they despawn when away from a
player or not. Unfortunately animals still use their own system to prevent
despawning instead of making use of this flag. This change modifies them
to use the new system (defaults to true) and to add API for plugins to adjust
this.
2012-12-04 20:10:23 -06:00
feildmaster
11894784b0 Fix leaky pipes (water flow). Fixes BUKKIT-3085
(Also, fix mistranslation for VehicleBlockCollisionEvent)
2012-12-01 13:33:44 -06:00
feildmaster
c596093c31 [BREAKING] Update BlockFace directions. Fixes BUKKIT-1567, BUKKIT-3069
The answer is 42
2012-12-01 01:14:25 -06:00
Wesley Wolfe
3404318bc5 Fix missed refactoring in EntityWither 2012-11-30 17:50:09 -06:00
Wesley Wolfe
1a6a828156 Add data values to EntityChangeBlockEvent. Adds BUKKIT-3077, BUKKIT-3076
This change affects Endermen and Silverfish, adding a data value for the block change event.
2012-11-30 11:59:29 -06:00
Wesley Wolfe
9bd02495df Use carried item for endermen's changed-block's id. Fixes BUKKIT-3075 2012-11-30 11:49:01 -06:00
feildmaster
0c16afd6e0 Take into account if the shooter is a player before considering pvp mode for projectiles. Fixes BUKKIT-3058 2012-11-27 12:14:53 -06:00
feildmaster
1040a81334 Fix multi-world sounds not being sent correctly. Fixes BUKKIT-3051 2012-11-25 18:05:17 -06:00
feildmaster
aa99d67963 Call EntityInteractEvent for Wood Buttons. Fixes BUKKIT-3022
Prior to this, there was no way to tell when arrows trigger buttons
2012-11-24 01:41:19 -06:00
feildmaster
cd66edd40f Fix the previous fix for "infinite 'breeding' with MonsterEggs" 2012-11-22 21:42:34 -06:00
feildmaster
22e26a5029 Call MapInitializeEvent on newly created maps. Fixes BUKKIT-2907 2012-11-21 16:48:25 -06:00
feildmaster
f0325da814 Add ItemMapEmpty for diff visibility 2012-11-21 16:19:56 -06:00
EvilSeph
45e8919598 Updated version to 1.4.5-R0.3-SNAPSHOT for development towards next release. 2012-11-20 20:34:41 -05:00
EvilSeph
cf677490e4 Updated version to 1.4.5-R0.2 in pom.xml for Beta. 2012-11-20 20:06:14 -05:00
feildmaster
71b0510f88 Fix teleporting entities with vehicles/passengers teleporting you illegally. Fixes BUKKIT-2821
Also some formatting...
2012-11-20 19:41:56 -05:00
EvilSeph
fed863049d Update invalidItems array. Fixes BUKKIT-2554. 2012-11-20 19:37:01 -05:00
EvilSeph
a17ca07fe8 Add SPAWNER_EGG spawn reason to allow for filtering. Adds BUKKIT-3000 2012-11-20 19:37:01 -05:00
EvilSeph
c36b3da573 Fix infinite 'breeding' with MonsterEggs. Fixes BUKKIT-2997
If the player is not in Creative (i.e. does not have the ability to
instantly build) we need to decrement the MonsterEgg item stack when used
on a breedable parent mob.
2012-11-20 19:37:00 -05:00
feildmaster
5f5dd727b6 Add a DamageEvent for falling blocks which can damage entities. Fixes BUKKIT-2781 2012-11-20 17:16:30 -06:00
Wesley Wolfe
d039986be7 No teleporting people back into the server. Fixes BUKKIT-2298
Stale player references will add a player back into the world when
teleporting them, causing a cascade of issues relating to ghost entities
and servers failing to stop.
2012-11-19 21:38:31 -06:00
EvilSeph
d23c97429f Updated version to 1.4.5-R0.2-SNAPSHOT for development towards next release. 2012-11-18 22:50:41 -05:00
EvilSeph
0f2913e30a Updated version to 1.4.5-R0.1 in pom.xml for Beta. 2012-11-18 22:40:13 -05:00
Travis Watkins
8f4cde24bd Don't add player to world if join event did it already.
On join we unconditionally add the player to the world they logged out in.
If a plugin teleports a player during PlayerJoinEvent in a way that adds
them to a world (cross-world teleport) we end up with one player in two
places. To avoid this we check to see if the player has changed worlds or
is already added to the world we have we skip adding them again.
2012-11-18 21:27:48 -05:00
EvilSeph
cc78e17312 Fix players losing experience when keepInventory is true. Fixes BUKKIT-2915 2012-11-18 17:45:29 -05:00
Travis Watkins
7ef9adc04e Fix missed rename making withers too cheaty. Fixes BUKKIT-2972 2012-11-18 16:14:08 -06:00
Travis Watkins
58636c2dd8 Don't do case lookups when we have the right case already.
This is a missed part of the original "[Bleeding] Use case from player data
for OfflinePlayer. Fixes BUKKIT-519" commit. It avoids doing (somewhat
expensive) lookups of player data to find the correct capitalization inside
getOfflinePlayers() as we're already loading their name from the player data
and thus have the correct capitalization.
2012-11-18 10:51:52 -06:00
Travis Watkins
1044c32a54 Lower compression level to avoid overloading the thread. Fixes BUKKIT-2963
When sending chunks to a player we use their writer thread to do chunk
compression to avoid blocking the main thread with this work. However,
after a teleport or respawn there are a large number of chunk packets to
process. This causes the thread to spend a long period handling compression
while we continue dumping more chunk packets on it to handle. The result of
this is a noticable delay in getting responses to commands and chat
immediately after teleporting.

Switching to a lower compression level reduces this load and makes our
behavior more like vanilla. We do, however, still give this thread more
work to do so there will likely still be some delay when comparing to
vanilla. The only way to avoid this would be to put chunk compression back
on the main thread and give everyone on the server a poorer experience
instead.
2012-11-18 09:16:50 -06:00
Karl Fritsche
028860399b Implement sound changes for Minecraft 1.4.2 changes. Fixes BUKKIT-2849 2012-11-17 15:06:18 -06:00
James Clarke
a575e6b075 Use correct itemstack for dispenser behavior chaining. Fixes BUKKIT-2886
When an event changes the item to be dispensed we check to see if the new
item has special behavior for dispensing and if so pass it on to that
behavior handler. However, we are actually checking the old itemstack and
passing the new itemstack so this check fails.
2012-11-17 15:06:18 -06:00
EdGruberman
293474d99b [Bleeding] Use case from player data for OfflinePlayer. Fixes BUKKIT-519
If a plugin looks up a player that is offline they may not know the correct
capitalization for the name. In this case they're likely to get it wrong
and since we cache the result even after the player joins the server all
future request for an OfflinePlayer will return one with incorrect case.

When looking up a player who has played on the server before we can
get the correct case from the player data file saved by the server. If
the player has never played before this point we cannot do anything and
will still have the same issue but this is not a solvable problem.
2012-11-17 15:06:18 -06:00
Travis Watkins
20c074ec6c Don't show a player on map if they're vanished. Fixes BUKKIT-1882 2012-11-17 15:06:06 -06:00
Travis Watkins
2d832bf148 Don't kick player when they travel too far. Fixes BUKKIT-2968
If a player travels past 32,000,000 blocks on the X or Z coordinates they
will be kicked for having an illegal position. On kick their player data
is saved which includes their (illegal) position. This means on join they
are immediately kicked again for the same reason and are stuck. Instead of
kicking at all in this case just teleport the player back to their previous
position just like the moved wrongly check does.
2012-11-17 15:00:14 -06:00
James Clarke
bd0868ae1e Implement API for Skeleton and Zombie types. Fixes BUKKIT-2818 2012-11-17 15:00:14 -06:00
Travis Watkins
dca54ff187 Fire BlockSpreadEvent for vine growth. Fixes BUKKIT-1097 2012-11-17 15:00:14 -06:00
Travis Watkins
0c78ce40e5 Add BlockVine.java from mc-dev for diff visibility. 2012-11-17 15:00:14 -06:00
Travis Watkins
9ab40b1ab3 Fire BlockFadeEvent when soil turns back to dirt. Fixes BUKKIT-1854 2012-11-17 14:59:41 -06:00
Travis Watkins
558411692a Don't wait for main thread when processing commands.
In order to correctly handle disconnects for invalid chat we setup a
Waitable and pass it to the main thread then wait for it to be processed.
However, commands are also chat packets and they are already on the main
thread. In this case, waiting will deadlock the server so we should just
do a normal disconnect.
2012-11-17 11:48:22 -06:00
Travis Watkins
9add7d3000 Don't create tile entity when block placement fails. Fixes BUKKIT-2924
End portals can only be placed in the end during the dragon's death.
Attempts to place them outside of this window causes the block to remove
itself. However, we still create the tile entity for the portal which
leads to exceptions spamming the console about a tile entity existing
without the appropriate block. In these cases we should not place the tile
entity at all.
2012-11-16 16:56:49 -06:00
Travis Watkins
d21c5f3871 Ignore empty custom payload packets. Fixes BUKKIT-2957 2012-11-16 16:15:41 -06:00
Wesley Wolfe
6466aa1d25 Use synchronous calls and wait for chat disconnect. Fixes BUKKIT-2946
When invalid chat is detected we currently drop the connection with no
hint as to why as anything else is not allowed while we're off the main
thread. To give valid disconnect reasons and fire proper events instead
pass these off to the main thread and wait for it to process them.
2012-11-16 15:56:13 -06:00
Travis Watkins
82c8cf4234 Update tile entity when interact event is cancelled.
If a plugin cancels a PlayerInteractEvent when left clicking a block the
client may have removed this block if they are in creative mode or if the
block breaks in a single hit. In this case, we need to update the client's
tile entity as well as telling it the block still exists.
2012-11-16 13:46:52 -06:00
Travis Watkins
6952ad1e59 Update CraftBukkit to Minecraft 1.4.5. 2012-11-16 10:13:34 -06:00
feildmaster
8e806550d7 Remove fire ticks if damage has been canceled. Fixes BUKKIT-2933 2012-11-15 19:26:39 -06:00
Travis Watkins
6149fc3e78 Don't thread single chunk compression. Fixes BUKKIT-2927
Packet 51 is used to send updates about large changes to single chunks
and to remove chunks from the client when they get out of range. In the
first case a single packet object is created and queued for all relevant
players. With our current chunk compression scheme this means the first
player to have the packet processed will start the compression and get the
packet correctly but the rest will get garbage.

Since this packet never contains much data it is better to simply handle
compression of it on the main thread like vanilla does instead of putting in
locks and dealing with their overhead and complexity.
2012-11-15 16:09:21 -06:00
Travis Watkins
e1afee008f Update tile entity on client on cancelled block break. Fixes BUKKIT-2935
When a client tries to break a block it assumes it has done so unless told
otherwise by the server. This means the client also wipes out any tile
entity data it has for the block as well. We do not send this data when
updating the client so clients lose things like text on signs, skull type,
etc when they aren't allowed to break the block.
2012-11-14 20:14:47 -06:00
Travis Watkins
df69ea8814 Rework skull dropping. Fixes BUKKIT-2930 and BUKKIT-2820
Skulls need their tile entity in order to create an item correctly when
broken unlike every other block. Instead of sprinkling special cases all
over the code just override dropNaturally for skulls to read from their
tile entity and make sure everything that wants to drop them calls this
method before removing the block. There is only one case where this wasn't
already true so we end up with much less special casing.
2012-11-14 20:14:47 -06:00
Wesley Wolfe
092800af26 Fixed some async tasks running synchronously. Fixes BUKKIT-2934
Additionally refactored cancel method to be more object-oriented.
2012-11-14 16:47:21 -06:00
Travis Watkins
c2bae0bebb Add crafting result slot for sheep breeding. Fixes BUKKIT-2926
Sheep now use the crafting system when breeding to determine what color
their baby should be. This triggers an event but the event wants the
crafting inventory to have a result slot which sheep do not have. This
event could be useful for plugins to control the output of sheep breeding
so instead of disabling it we add a result slot so the event fires without
issue.
2012-11-14 13:27:45 -06:00
Travis Watkins
188a71ad5b Clear out empty extended block ID array. Fixes BUKKIT-2923
If a chunk gets a block added to it that requires the extended block id
nibble array (block id greater than 255) the array is created and saved
with the chunk. When the blocks are verified to make sure they exist these
entries are erased but the extended block id array is not. This causes the
server and client to disagree about how much data a chunk has which makes
the client crash while trying to load the chunk for rendering.

To resolve these issues we now clear the extended block id array on chunk
load if there is no valid data in it.
2012-11-14 11:36:06 -06:00
Travis Watkins
2b22ae2d45 Potentially fix glitch with falling entities.
When a block creates a falling entity the block is not immediately removed
from the world. Instead, the falling entity is responsible for removing it
but only if the block still exists. Due to certain piston mechanics it is
possible to move the block before this check happens and thus the block is
not removed. This should be fine as the entity will kill itself in this
situation. However, the code does not stop here and continues running the
rest of the entity logic which includes either placing a block in the world
or placing a block item in the world depending on the circumstances.
2012-11-13 23:34:43 -06:00
Travis Watkins
db43197ecf Add EntityFallingBlock from mc-dev 2012-11-13 23:23:04 -06:00
Travis Watkins
5a999a2660 Correct digging behavior. Fixes BUKKIT-2780
If a block is air we return immediately so miss the cleanup work that would
normally happen in this case in vanilla. This causes us to get in to a
situation where, due to odd packet sending from the client, we never
properly stop an attempt by the client to break a block and thus it
eventually breaks.

We also use our own variable for block damage and never sync it up with the
vanilla one so damage reporting to other clients is not always correct.
2012-11-13 21:42:36 -06:00
Travis Watkins
7f7192f8fd Update CraftBukkit to Minecraft 1.4.4. 2012-11-13 16:09:52 -06:00
EvilSeph
a0c3b4f9d1 Updated version to 1.4.2-R0.3-SNAPSHOT for development towards next release. 2012-11-03 01:08:15 -04:00
EvilSeph
cc668b2f8b Updated version to 1.4.2-R0.2 in pom.xml for Beta. 2012-11-03 00:51:40 -04:00
EvilSeph
f683d5568f Migrate world data with world when switching from vanilla Minecraft to
Bukkit. Fixes BUKKIT-2816 and BUKKIT-2760
2012-11-02 21:12:02 -04:00
md_5
53d24e2b22 [Bleeding] Fix mistranslation affecting time of the server vs time of day.
Fixes BUKKIT-2797
2012-11-02 16:36:43 -04:00
Wesley Wolfe
3dd0580d50 Improved the potion test to detect missing PotionType values. 2012-11-02 00:24:11 -05:00
Travis Watkins
87d25c4cc6 Fix compile issue with chunk generation. 2012-11-02 00:12:49 -05:00
feildmaster
a4892dfa72 Delegate recreateStructures to nms provider. Fixes BUKKIT-2760
This was a miss when updating to 1.4.2
2012-11-01 21:32:28 -05:00
Wesley Wolfe
1c14586c49 Add CraftArt mappings for Wither. Fixes BUKKIT-2667.
The static assertions are not normally evaluated in the JVM, and failed
to fail when the enums went from size 25 to size 26. This meant missing
values would not be detected at runtime and instead return null,
compounding problems later. The switches should never evaluate to null
so will instead throw runtime assertion errors.

Additional unit tests were added to detect new paintings and assure they
have proper, unique mappings. The test checks both that a mapping
exists, is not null, and does not duplicate another mapping.
2012-11-01 03:06:47 -05:00
Wesley Wolfe
9a88e615d4 Change ItemFrame to actually provide a defensive copy. Fixes BUKKIT-2784
If a defensive copy is not used in the API, changes to the item are
reflected in memory, but never updated to the client. It also goes
against the general contract provided in Bukkit, where setItem should be
the only way to change the underlying item frame.
2012-11-01 01:34:54 -05:00
EvilSeph
1fb3164a96 Updated version to 1.4.2-R0.2-SNAPSHOT for development towards next release. 2012-10-31 20:51:53 -04:00
EvilSeph
b9486da5c4 Updated version to 1.4.2-R0.1 in pom.xml for Beta. 2012-10-31 15:59:34 -04:00
EvilSeph
1623bf0f9b Fire HangingBreakEvent when explosions remove hanging entities. Fixes BUKKIT-2764 2012-10-31 14:24:03 -04:00
Travis Watkins
87a1cd3d43 Add inventory and slot types for new containers. Fixes BUKKIT-2741 2012-10-31 13:25:53 -04:00
Travis Watkins
347fd3cb6e Fix NPE when blowing up an item frame. Fixes BUKKIT-2763 2012-10-31 13:09:57 -04:00
Travis Watkins
f479aa84a4 Implement API for ambient mob spawn limit. Add spawn-limit.ambient to
bukkit.yml. Adds BUKKIT-2765
2012-10-31 13:01:48 -04:00
Travis Watkins
46d7cd1e05 Use BlockCommandSender for dispatching Command block commands
Also allow commands that don't start with a / to match vanilla behavior
2012-10-31 06:37:46 -05:00
feildmaster
9e4e2c62af Expose API for managing and using GameRules. Adds BUKKIT-2757 2012-10-31 03:40:43 -04:00
Travis Watkins
59dc403a61 Hook command block up to ConsoleCommandSender. Fixes BUKKIT-2684
This will need to have its own CommandSender but this makes command blocks
work for now with any command console can run.
2012-10-31 02:39:56 -05:00
h31ix
63eaf74d44 Implement the API for ItemFrames. Adds BUKKIT-2668 2012-10-31 01:18:59 -05:00
h31ix
02ca9be079 [Bleeding] Fire damage is no longer a valid reason for hanging entity removal 2012-10-31 00:45:47 -04:00
h31ix
54cce5bf92 [Bleeding] Implement new Hanging events. Adds BUKKIT-2754 2012-10-31 00:21:31 -04:00
EvilSeph
4efd06a6b5 Remove Anvil debug. Fixes BUKKIT-2732 2012-10-30 19:11:34 -04:00
md_5
42391009f7 [Bleeding] Prevent players from appearing to be sneaking after they change dimensions whilst doing so. 2012-10-30 19:11:34 -04:00
EvilSeph
b7886d1421 Disable portal support for entities for now. Restore allowNether check.
Relates to:
BUKKIT-2695 BUKKIT-2675
2012-10-30 19:11:33 -04:00
EvilSeph
6bf705dd08 Expose API for clearing a player's inventory with a successful count
return. Adds BUKKIT-2745
2012-10-30 04:55:02 -04:00
feildmaster
856fdc2ab6 Update map cursors to reflect 1.4 changes. Fixes BUKKIT-2740 2012-10-29 23:29:40 -04:00
EvilSeph
3047a424bb Expose API for giving and taking experience levels for use with ExpCommand's new behaviour with Minecraft 1.4. Adds BUKKIT-2739 2012-10-29 23:18:37 -04:00
feildmaster
aba7e2faf1 Revert changing EntityType.FIREBALL to LARGE_FIREBALL 2012-10-29 20:17:52 -05:00
Travis Watkins
216cddb2ab Get skull data before destroying block. Fixes BUKKIT-2723
Skull blocks store their type in a tile entity and use their block data
as rotation. When breaking a block the block data is used for determining
what item to drop. Simply changing this to use the skull method for getting
their drop data is not enough because their tile entity is already gone.
Therefore we have to special case skulls to get the correct data _and_ get
that data before breaking the block.
2012-10-29 12:54:16 -05:00
EvilSeph
14f4bd9024 Fix bug preventing non bed-reliant spawns from being successfully set. Fixes BUKKIT-2708 2012-10-29 04:56:30 -04:00
Travis Watkins
d16f8c5e65 Drop skulls like every other block. Fixes BUKKIT-2678
Instead of having a special case for skulls just use the normal logic for
breaking a block. This avoids issues when interacting with API.
2012-10-29 02:28:27 -05:00
EvilSeph
f4cdf8fe98 Add isHardcore API to check if the server is in hardcore mode or not. Adds BUKKIT-2707 2012-10-29 01:46:14 -04:00
EvilSeph
442b7a69f1 Prevent health from wrapping around. 2012-10-28 23:55:40 -04:00
h31ix
db49a57694 Update PotionEffects on player death. Fixes BUKKIT-2673
On player death player PotionEffects need to be updated so that a player's
invisibility and other effects are removed, otherwise they will persist
after a respawn. This is a carry-over from our use of persistent player
entities.
2012-10-28 23:27:02 -04:00
Travis Watkins
0fb806c566 Clamp difficulty levels to prevent invalid values
Some features added in 1.4.2 use the difficulty value as an index to an
array so while before having it set to an invalid value would do nothing
or maybe cause an odd side effect somewhere it now crashes the server. This
patch ensures difficulty values are clamped between 0 and 3, inclusive.
2012-10-28 10:07:11 -05:00
Travis Watkins
37a0d6757d Don't filter item data for anvils. Fixes BUKKIT-2640
Filtering item data is usually a good idea to make sure we don't have
invalid data or data on items that shouldn't have it. However, anvils
use item data in slightly different way and so running its code for
filtering here causes the data to be corrupted.
2012-10-28 09:37:47 -05:00
Travis Watkins
9841b77009 Use correct variable for squid Y motion. Fixes BUKKIT-2648 2012-10-28 03:23:48 -05:00
Travis Watkins
c675cc0b3b Fix missed rename for ore exp dropping. Fixes BUKKIT-2662 2012-10-28 02:43:23 -05:00
Travis Watkins
d97d193b91 Add new entities to World.spawn method. Fixes BUKKIT-2658 2012-10-28 02:21:34 -05:00
h31ix
788e9e84cf Fix incorrect method names missed during update. Fixes BUKKIT-2653
A couple method names were changed between 1.3.2 and 1.4.2 but were missed
in the update. One of these affects being able to enchant bows and the
other is used for updating player animations while firing.
2012-10-28 03:06:59 -04:00
EvilSeph
11d65171cd These books are too powerful! 2012-10-28 03:05:28 -04:00
EvilSeph
784f9e31a8 Remove spawn-radius setting in bukkit.yml in favour of spawn-protection in
server.properties. Fixes BUKKIT-2657
2012-10-28 01:55:27 -04:00
EvilSeph
5fe8523023 Fixed generator-settings not being set. Fixes BUKKIT-2652 2012-10-28 01:00:28 -04:00
Travis Watkins
5469311a36 Don't pass vanilla plugin channels to plugins. Fixes BUKKIT-2638
Vanilla has its own handlers for plugin channel messages for things like
texture packs, books, and anvils. When vanilla handles one of these messages
we should not also pass it to plugins because they will be duplicating work
and potentially running in to situations our plugin system isn't setup to
handle. This is how 1.3.2 worked but was lost in the 1.4.2 update.
2012-10-27 23:25:10 -05:00
Travis Watkins
60819c6693 Update CraftBukkit to Minecraft 1.4(.2). 2012-10-27 22:19:03 -04:00
EvilSeph
b9a72531b6 Updated version to 1.3.2-R3.0 in pom.xml for RB. 2012-10-27 21:10:46 -04:00
EvilSeph
df7f86d028 Made books less powerful, though you should still read them! 2012-10-27 20:44:16 -04:00
EvilSeph
bd6c824c11 Updated version to 1.3.2-R2.1-SNAPSHOT for development towards next release. 2012-10-17 07:36:44 -04:00
EvilSeph
46f773a685 Updated version to 1.3.2-R2.0 in pom.xml for RB. 2012-10-17 07:30:23 -04:00
Wesley Wolfe
4166af1d3a Implement chat tab completion API. Fixes BUKKIT-2608. Adds BUKKIT-2607.
The chat tab completion implementation also includes a sanity check to
assure type-safety in the list.
2012-10-17 04:31:36 -05:00
Score_Under
3ce954bb86 Delegate tab-completion. Fixes BUKKIT-2181. Adds BUKKIT-2602
CommandMap now contains the functionality for tab completion. This
commit replaces the vanilla implementation and simply delegates it to
the Bukkit API.
2012-10-15 03:18:59 -05:00
Wesley Wolfe
05e889f346 Queue tasks from secondary threads. Fixes BUKKIT-2546 and BUKKIT-2600
This change affects the old chat compatibility layer from an
implementation only standpoint. It does not queue the 'event' to fire,
but rather queues a runnable that allows the calling thread to wait for
execution to finish.

The other effect of this change is that rcon connects now have their
commands queued to be run on next server tick using the same
implementation.

The internal implementation is in org.bukkit.craftbukkit.util.Waitable.
It is very similar to a Future<T> task, but only contains minimal
implementation with object.wait() and object.notify() calls
under the hood of waitable.get() and waitable.run().

PlayerPreLoginEvent now properly implements thread-safe event execution
by queuing the events similar to chat and rcon. This is still a poor way
albeit proper way to implement thread-safety; PlayerPreLoginEvent will
stay deprecated.
2012-10-14 17:26:53 -05:00
Wesley Wolfe
93a79cd0e6 Implement new scheduler API. Adds BUKKIT-836
The implementation for the new methods mimics the old methods. The final
call for the old methods now maps to the new methods with an additional
call to get id.
2012-10-14 01:21:58 -05:00
Travis Watkins
506a1a0765 Ensure entity isn't destroyed when trying to show it. Fixes BUKKIT-2038
If two players (or a player and any other entity) are teleported to the
same location in the same tick they will both get added to the other's
destroy queue then have a new entity spawn packet sent. Next tick the
destroy queue will be processed and they will then be invisible to each
other. To prevent this situation we remove the entity from the destroy
queue when sending out a spawn packet for them.
2012-10-13 15:27:45 -05:00
EvilSeph
cb2f8244e9 Updated version to 1.3.2-R1.1-SNAPSHOT for development towards next release. 2012-09-28 16:34:17 -04:00
EvilSeph
9796049536 Updated version to 1.3.2-R1.0 in pom.xml for RB. 2012-09-28 16:31:23 -04:00
EdGruberman
59d6b60c0a Update entity target data to reflect current AI status. Fixes BUKKIT-2280
The new AI system introduced by Minecraft 1.2 no longer relies on the
target field in the entity so it is frequently out of sync with what the
entity is actually doing. This modifies the AI goal to update the target
so our API can return the correct information.
2012-09-28 15:04:32 -05:00
Travis Watkins
62a9b8815b Allow data values on mushroom and mob spawner blocks. Fixes BUKKIT-2346
In 1.2.5 and older versions of CraftBukkit we allowed the use of data
values on bug mushroom and mob spawner blocks for use with plugins.
For the 1.3 update the mechanism for doing this was changed and I
accidentally used the wrong value when adding these, indicating that
they should not have data instead of our actual intent. This change
corrects this regression.
2012-09-28 15:00:02 -05:00
Travis Watkins
b5580b6d95 Remove player from destroy queue when they go visible. Fixes BUKKIT-2071
If a plugin calls player.hidePlayer(other); then player.showPlayer(other);
in the same tick the other player will be added to the entity destroy queue
then a spawn packet will be sent. On the next tick the queue will be
processed and a destroy packet will be sent that renders the other player
invisible. To correct this we ensure the destroy queue is in sync with use
of the vanish API.
2012-09-28 14:53:28 -05:00
Travis Watkins
244a39d209 Use this world instead of the one in the entity. Fixes BUKKIT-2315
In some situations an entity or tile entity can be added to the world but
have its own 'world' field be null or otherwise incorrect. As the entity
was added to this world to be ticked assume it actually is in this world.
2012-09-28 14:46:30 -05:00
Wesley Wolfe
fc0e35a67c Fix typo causing a task to be repeated in debug. Addresses BUKKIT-2549
An internal method for making the debug output for CraftScheduler's
async tasks was erroneously using the 'this' reference when the loop
should be referencing the current task.
2012-09-28 02:39:22 -05:00
EvilSeph
1d75bd35ce Updated version to 1.3.2-R0.3-SNAPSHOT for development towards next release. 2012-09-26 19:20:20 -04:00
EvilSeph
7ec2e2a168 Updated version to 1.3.2-R0.2 in pom.xml for Beta. 2012-09-26 19:16:20 -04:00
Wesley Wolfe
03f12497b2 Map org.bukkit.Sound to String values for sending to client.
This change was done to remove the internal sound names from the API.
Along with moving the internal names into CraftBukkit, a unit test was
added for any new sounds added in the API to assure they have a non-null
mapping.
2012-09-26 19:02:05 -04:00
Travis Watkins
74b3be57b7 Replace LongObjectHashMap with a more efficient implementation
After further testing it appears that while the original LongHashtable
has issues with object creation churn and is severly slower than even
java.util.HashMap in general case benchmarks it is in fact very efficient
for our use case.

With this in mind I wrote a replacement LongObjectHashMap modeled after
LongHashtable. Unlike the original implementation this one does not use
Entry objects for storage so does not have the same object creation churn.
It also uses a 2D array instead of a 3D one and does not use a cache as
benchmarking shows this is more efficient. The "bucket size" was chosen
based on benchmarking performance of the HashMap with contents that would
be plausible for a 200+ player server. This means it uses a little extra
memory for smaller servers but almost always uses less than the normal
java.util.HashMap.

To make up for the original LongHashtable being a poor choice for generic
datasets I added a mixer to the new implementation based on code from
MurmurHash. While this has no noticable effect positive or negative with
our normal use of chunk coordinates it makes the HashMap perform just as
well with nearly any kind of dataset.

After these changes ChunkProviderServer.isChunkLoaded() goes from using
20% CPU time while sampling to not even showing up after 45 minutes of
sampling due to the CPU usage being too low to be noticed.
2012-09-21 11:20:10 -05:00
Wesley Wolfe
9f70c1f386 Set last accessed variables after grabbing chunk. Fixes BUKKIT-1033
This fix changes the 'state' of the last accessed variables to be more
accurate. Changing the coordinates of the last accessed chunk should
never precede actually setting the last accessed chunk, as loading a
chunk may at some point call back to getChunkAt with a new set of
coordinates before the chunk has actually been loaded. The coordinates
would have been set, but the actual chunk would not. With no check for
accuracy, this causes fringe case issues such as null block states.

Big thanks to @V10lator for finding where the root of the problem was
occurring.
2012-09-20 23:00:34 -05:00
Wesley Wolfe
cebc8cffec CraftBukkit comment fixes 2012-09-14 01:53:42 -04:00
mbax
4b1f6aff3f [Bleeding] Check visibility API for sounds. Fixes BUKKIT-2210
This implementation of a visibility API check for sounds
was created by adding extra methods carrying the source entity
in WorldManager and ServerConfigurationManagerAbstract and
adding a test for canSee in the SCMA sendPacketNearby method.
This approach involves no logic copying, just method addition.
I opted to cast to WorldManager as:
1) IWorldAccess is not in CraftBukkit at the moment
2) There is no other IWorldAccess implemented in CraftBukkit,
  nor is there likely to be one soon. If that day comes, easy fix.
2012-09-14 01:53:42 -04:00
EvilSeph
349cb0bba6 What is dead may never die. 2012-09-14 01:53:34 -04:00
EvilSeph
412b4624c3 Update the client after a FoodLevelChange event is fired. Fixes BUKKIT-2510 2012-09-12 22:06:36 -04:00
Mike Primm
9a4b85c931 [Bleeding] Avoid spawn checks on empty worlds. Fixes BUKKIT-2508
Change a server wide check for players to be world specific. Worlds
without players will not spawn entities.
2012-09-12 22:06:36 -04:00
EvilSeph
4c0dd6964e Reverted changes to chunk saving behaviour. 2012-09-12 22:06:35 -04:00
Mike Primm
beee3ce2da [Bleeding] Add autosave interval setting in bukkit.yml. Adds BUKKIT-2507
The new setting is located at "ticks-per.autosave". By changing this
value, it affects how often a full save is automatically executed,
measured in ticks.

This value is defaulting to 0 (off) because we believe that the vast
majority of servers already have a third-party solution to automatically
saving the server at set intervals. Having the built in auto-save disabled
by default ensures that we are not saving things twice; doing so leads to
absolutely no benefits, but results in detrimental and noticeable
unnecessary performance decrease.

For servers that do not use an automated external script to perform saves,
this setting can be turned on by setting the value higher than 0, with 900
being the value used in vanilla.
2012-09-12 22:05:52 -04:00
Wesley Wolfe
e2b1514daf Bulk pending cleanup. 2012-09-09 23:19:28 -05:00
Luke Granger-Brown
b1f6d16bfa Change local jline checks to not use String literals. Fixes BUKKIT-2455.
Refactoring dependencies 'changes' the string literal in the code. This
commit changes the literal to instead use a char[] to initialize a new
String. On a bytecode level, there will not exist a String literal for these
two values; the shade plugin will no longer refactor them.

Refactoring jline also changes the other String literals we use for
notifying jline of the current state. To insure that our local code reflects
the inner logic in jline, the key value was changed to the static final
variable located in TerminalFactory. Likewise, UnsupportedTerminal uses the
explicit class name (as reflection is used later with the value that has
been set).
2012-09-09 17:02:48 -05:00
Wesley Wolfe
27d58a299c Add information about async tasks to CrashReports. Addresses BUKKIT-2491
Async tasks are notorious for causing CMEs and corrupted data when
accessing the API. This change makes a linked list to track recent tasks
that may no longer be running. It is accessed via the toString method on
the scheduler. This behavior is not guaranteed, but it is accessible as
such currently.

Although toString is located in the scheduler, its contract does not
guarantee an accurate or up to date call when accessed from a second
thread.
2012-09-09 00:34:41 -05:00
Wesley Wolfe
4d5894e4cb Fix crash from console-commands throwing exception. Fixes BUKKIT-2479
When 1.3.1 was released, a try-catch block was removed from the tick
loop that called the method in NMS to handle commands. This restores a
try-catch to prevent the console from crashing the server.
2012-09-06 22:11:17 -05:00
feildmaster
c710ca827f Fix BUKKIT-2419: PlayerAbilities not being updated on teleport/respawn
Minecraft resets abilities based on what it knows client side, when someone dies and is in "survival," by default they should be in "survival." However, we allow modification of the PlayerAbilities, so we send this update out to the client.

Oh and, the format of the commit is like this to see if it looks any good. :)
2012-08-27 12:02:25 -05:00
Wesley Wolfe
3307d489da Fix Future task waiting logic. Fixes BUKKIT-2408
Previously, the timeout would erroneously get converted to milliseconds
twice. The second conversion was removed.

Spurious wakeups were not handled properly, and would instead throw a
TimeoutException even if the waited time was not reached..
2012-08-26 10:25:11 -05:00
feildmaster
cb84d6b994 Fix empty chunks not sending biome properly and causing client side issues. Fixes BUKKIT-2396 2012-08-25 08:59:33 -05:00
EvilSeph
bedc2f0357 Updated version to 1.3.2-R0.2-SNAPSHOT for development towards next release. 2012-08-25 04:02:20 -04:00
EvilSeph
4b840c9686 Updated version to 1.3.2-R0.1 in pom.xml for Beta. 2012-08-25 00:55:38 -04:00
Travis Watkins
b8cc862083 Update to 1.3.2 2012-08-25 00:54:21 -04:00
feildmaster
35cff16da5 Fix EmptyChunk's not sending to the Client correctly. Fixes BUKKIT-2206 2012-08-23 14:58:23 -05:00
feildmaster
c88531eca6 Don't refactor packages with natives 2012-08-22 18:32:48 -05:00
Wesley Wolfe
9580c3e39a Refactor CraftBukkit dependencies. Fixes BUKKIT-2329
The maven shade plugin has the ability to change the namespace for
included dependencies and packages. This change is being implemented to
remove all conflicts with any possible libraries in an execution
environment.

The only dependencies to be refactored are specific to CraftBukkit. To
refactor dependencies included with Bukkit breaks any plugin compiled
against those specific dependencies, especially ebeans--an API
specifically encouraged for database management.
2012-08-22 16:42:26 -05:00
Wesley Wolfe
dcd01bf0c0 Rewrite scheduler. Fixes BUKKIT-1831, and BUKKIT-845
The new scheduler uses a non-blocking methodology. Combining volatile
references to make a linked reference chain, with the atomic reference
handling the tail, tasks are queued without waiting for locks. The main
thread will no longer limit the length of time spend for scheduled tasks,
but no task will run twice in the same tick. Scheduling a new task inside of
a synchronous task will always run the new task during the same tick,
assuming there is no supplied delay > 0.

Asynchronous tasks are now run using a thread pool. Any thread-local
implemenation should now account for threads being reused between
executions.

Race conditions were carefully examined and the order of logic is now very
important. Each task is placed in a secondary collection before removal from
primary collections. Thus, by reading tasks from the collections in the same
order they travel, it retains state-safety. This does make modifications
less responsive in some situations, as the task may be transitioning before
the modifier accesses it. This cost outweighs the requirement to synchronize
on the scheduler; previously any conflict would be first-come-first-serve,
with the main thread backing out arbitrarily.
2012-08-22 16:41:46 -05:00
feildmaster
8fdb006143 Use constant Player for EnderPearls
Also make sure players are online before proceeding to each event
2012-08-22 14:32:10 -05:00
feildmaster
98c98d0f7a Fix entities not having valid "isValid" states. Addresses BUKKIT-2366 2012-08-22 14:16:51 -05:00
V10lator
e3ae188ed2 Fix instances where Signs have null lines. Addresses BUKKIT-684 2012-08-21 20:17:29 -05:00
EdGruberman
450edc3004 Use standard format function to format logs. Addresses BUKKIT-2246
Also fix "excess" Log Levels.
2012-08-21 19:17:29 -05:00
feildmaster
161ab5edc6 Implement API for Sound, and playing the sounds for Worlds and Players. Adds BUKKIT-1430, BUKKIT-1226 and BUKKIT-2019 2012-08-21 19:13:19 -05:00
Travis Watkins
ccc760d629 Use a dynamic pool size for the iterator cache
Many codepaths only end up with one iterator being used at a time and
most of the rest only get up to two being used so using a static pool of
three is wasteful. This also allows us to efficiently handle cases that
exceed 3 iterators in use. Overall this dramatically increases the hit rate
and results in less iterators being created.
2012-08-20 18:44:07 -05:00
feildmaster
e7e643d83a Implement API to retrieve and open EnderChests. Adds BUKKIT-2016 2012-08-20 16:00:53 -05:00
Travis Watkins
feb0327d22 Check unload queue so we don't accidentally leave a chunk loaded 2012-08-19 16:06:14 -05:00
Mike Primm
7dde6cc566 [Bleeding] Stub out MethodProfiler class
Instead of trying to track down every place this class is used we can
simply stub out the entire class so it has no extra overhead.
2012-08-19 09:51:09 -05:00
Mike Primm
e079d9457e [Bleeding] Strip out unused HashSet in IntHashMap 2012-08-19 09:51:07 -05:00
Mike Primm
eaa3154b0e [Bleeding] Cache packet ID instead of doing lookups each time it is needed 2012-08-19 09:51:04 -05:00
Mike Primm
627cf2ef8b [Bleeding] Remove redundant chunkList from ChunkProviderServer
This ArrayList duplicates part of the functionality of the much more
efficient chunk map so can be removed as the map can be used in the few
places this was needed.
2012-08-19 09:51:00 -05:00
Travis Watkins
97ac0a3f14 Add LongObjectHashMap and LongHashSet
Replace uses of LongHashtable and LongHashset with new implementations.
Remove EntryBase, LongBaseHashtable, LongHashset, and LongHashtable as they
are no longer used.

LongObjectHashMap does not use Entry or EntryBase classes internally for
storage so has much lower object churn and greater performance. LongHashSet
is not as much of performance win for our use case but for general use is
up to seventeen times faster than the old implementation and is in fact
faster than alternatives from "high performance" java libraries. This is
being added so that if someone tries to use it in the future in a place
unrelated to its current use they don't accidentally end up with something
slower than the Java collections HashSet implementation.
2012-08-19 09:51:00 -05:00
Travis Watkins
7b20caf8fe Use TrigMath in hotspots
Use our implementation of atan2 in AI routines as profiling shows these are
hotspots and (for these cases) our implementation is much faster.
2012-08-19 09:51:00 -05:00
Mike Primm
8219081385 [Bleeding] Change Vec3DPool to a stack based pool
Avoid overhead of using an ArrayList and resizing it. Also allows for reuse
of objects in the pool during the same tick by explicitly releasing them
back to the pool. This allows for much better cache performance as well
as reduced cache footprint.
2012-08-19 09:50:57 -05:00
Travis Watkins
d628c886d2 Optimize entity AI goal selector
Remove redundant ArrayList to avoid excessive object creation and CPU
overhead, the entries are added to the list then immediately iterated through
to run so just run them directly.

Swap order of some conditionals to perform the more efficient check first
as if it fails the list lookup will not be executed.

Remove profiling hooks including some rather expensive calls to getSimpleName.
2012-08-19 09:50:57 -05:00
Travis Watkins
858d36efc9 Add iterator cache to UnsafeList and use it in hotspots
Adds a specialized iterator for the list and a pool of iterators to avoid
object churn. Also optimizes the clear() method to reduce object creation.
2012-08-19 09:50:57 -05:00
Mike Primm
6d777ade16 [Bleeding] Optimize chunk loading
ChunkSection.e() is called once per chunk section loaded and is quite
expensive (about 20% of CPU time for loading the chunk). This changes the
logic to add a fast path when extended block data is not being used and
reorganizes the loops for more optimal array traversal. Overall this saves
about 20-30% CPU time in this method.
2012-08-19 09:50:45 -05:00
Mike Primm
852602e430 Add files from mc-dev for diff visibility 2012-08-19 09:19:28 -05:00
EvilSeph
b44fc8ed28 Updated version to 1.3.1-R2.1-SNAPSHOT for development towards next release. 2012-08-19 09:01:23 -04:00
EvilSeph
29ca5d1f50 Updated version to 1.3.1-R2.0 in pom.xml for RB. 2012-08-19 08:47:47 -04:00
Mike Primm
5254993510 Fix issues with chunk saving. Fixes BUKKIT-2158, BUKKIT-2018 and BUKKIT-2229 2012-08-19 08:36:47 -04:00
Wesley Wolfe
cacfc71b46 Add more detailed CrashReport for CraftBukkit. Addresses BUKKIT-2319 2012-08-17 23:18:22 -05:00
Wesley Wolfe
acedd049c5 Add CrashReport for diff visiblity 2012-08-17 22:22:20 -05:00
John Driscoll
0bde47a173 Don't extend pistons until data is set. Fixes BUKKIT-2153 2012-08-17 17:06:46 -05:00
Wesley Wolfe
050a9276bc Removed unneeded mc-dev imports. Fixes BUKKIT-682 2012-08-17 16:37:53 -05:00
Travis Watkins
add387dee3 Call PlayerQuitEvent in correct location. Fixes BUKKIT-2193 2012-08-15 12:22:52 -05:00
feildmaster
fc35d000e4 Use correct SlotType's for merchants. Fixes BUKKIT-2257 2012-08-15 06:00:55 -05:00
feildmaster
b059962a5c Implement methods for spawning FallingBlocks and add various FallingBlock methods. Adds BUKKIT-2282 2012-08-14 07:38:23 -05:00
feildmaster
8748c8c757 Enable hardcore support. Fixes BUKKIT-2259
- Hardcore requires a newly generated world
- You will be banned if you die in a hardcore world
- You will NOT be banned if you die in a non-vanilla world
- Your "heart container" will not change without logging back in. (Vanilla bug)
2012-08-12 16:50:00 -05:00
feildmaster
aa92f0e313 Update CreatureSpawner.setSpawnedType(EntityType) to 1.3
They can spawn any valid entities now. What is a "valid" entity? A "valid" entity is an EntityType with a non-null getName(). (for example: PRIMED_TNT, FALLING_BLOCK)
2012-08-12 14:11:36 -05:00
feildmaster
bfc5189818 Fix "block update packet" not being sent to the correct world. Fixes BUKKIT-2023 2012-08-12 14:11:34 -05:00
Wesley Wolfe
342f9c3bd3 Implement player speed API. Addresses BUKKIT-2205 2012-08-10 00:00:04 -05:00
Wesley Wolfe
77cda7e715 Add PlayerAbilities for diff visibility 2012-08-09 23:16:19 -05:00
feildmaster
27c1c85adb Implement BlockBreakEvent block experience. Adds BUKKIT-2033 2012-08-08 19:49:10 -05:00
feildmaster
8d946b88b3 Add BlockMobSpawner and BlockOre for diff visibility 2012-08-08 19:49:08 -05:00
Wesley Wolfe
a16e0b6323 Change socket traffic class try-catch. Fixes BUKKIT-2093 2012-08-08 07:00:41 -05:00
Wesley Wolfe
25fe93479f Restore port to the hostname. Fixes BUKKIT-2124 2012-08-08 07:00:29 -05:00
EvilSeph
24809ef986 Re-add support for full chunk saving so the server save-alls on stop. Fixes BUKKIT-2158 2012-08-08 03:08:46 -04:00
EvilSeph
a133bc7182 Make periodic chunk saving less aggressive and fixed double player data saving. Fixes BUKKIT-1994 and fixes BUKKIT-2144 2012-08-07 18:52:53 -04:00
EvilSeph
05b5a068cb Updated version to 1.3.1-R1.1-SNAPSHOT for development towards next release. 2012-08-07 17:10:11 -04:00
EvilSeph
fad4f39ac8 Updated version to 1.3.1-R1.0 in pom.xml for RB 2012-08-07 02:34:24 -04:00
Wesley Wolfe
2bb7a5f94d Implement new deprecated warning state configuration option 2012-08-06 23:52:49 -05:00
Travis Watkins
bfbdbbd05c Tripwire isn't redstone, only fire interact events. 2012-08-06 19:47:22 -05:00
Travis Watkins
7a3dfecba0 Don't force chunks to load again, causes chunk leaks with multiworld. 2012-08-06 17:31:03 -05:00
Wesley Wolfe
0792b15887 Pistons no longer extend before they are pistons. Fixes BUKKIT-1999 2012-08-06 09:55:38 -05:00
feildmaster
59aaa6a80a Fix dispenser removing data from items. Fixes BUKKIT-2045 2012-08-06 09:09:05 -05:00
THDigi
7dc47892a4 Don't rotate ShapedRecipes. Fixes BUKKIT-1334
ShapedRecipe's getShape() always returns a 90deg rotated shape of the original shape, this commit fixes it.
2012-08-06 07:11:35 -05:00
Travis Watkins
164c066453 Fix "moved too quickly" detection. 2012-08-05 23:57:22 -05:00
Travis Watkins
e1a4273957 Fire events for tripwire and hooks. 2012-08-05 23:57:22 -05:00
Travis Watkins
982efb8c24 Add BlockTripwire and BlockTripwireHook from mc-dev for diff visibility. 2012-08-05 23:57:22 -05:00
Travis Watkins
304cb019e4 Fire EntityDeathEvent for pigs. Fixes BUKKIT-2100 2012-08-05 23:57:22 -05:00
Wesley Wolfe
9cccb1c89e Fix Vec3DPool; don't pool objects indefinitely or O(n^2) clear() 2012-08-05 21:36:25 -05:00
Wesley Wolfe
f5777cc0b7 Add Vec3DPool for diff visibility 2012-08-05 21:36:09 -05:00
Wesley Wolfe
44234c47ce Cease execution if block is AIR. Fixes BUKKIT-2104 2012-08-05 21:32:01 -05:00
Travis Watkins
a574ec54cc Put forceChunkLoad back to its original value. 2012-08-05 20:03:12 -05:00
Travis Watkins
beb71069b7 Don't use Packet56 and clear client cache on world changes. 2012-08-05 18:42:03 -05:00
Wesley Wolfe
0e013fa4b0 Fixed PlayerManager ConcurrentModificationExceptions. Fixes BUKKIT-1972 2012-08-04 22:12:16 -05:00
Wesley Wolfe
9804665fec Fix bounding box pool to use a dynamic cache size
Also changed insane array copy routine. This should reduce server lag
spikes that occur periodically.
2012-08-04 21:11:28 -05:00
Wesley Wolfe
14a470985d Add AABBPool for diff visibility 2012-08-04 21:06:17 -05:00
Travis Watkins
e5acb6cf3a Don't tick chunks or entities on chunks that are queued for unload.
Treat chunks in the unload queue as if they are already unloaded to prevent
processing on them removing them from the unload queue and leaking.
2012-08-04 18:08:26 -05:00
Travis Watkins
fdd01feb8c Avoid CME when lightning strikes by making a copy. Fixes BUKKIT-2055 2012-08-04 18:02:30 -05:00
Wesley Wolfe
a5da834258 Fix chat not being cancellable when not using deprecated API. 2012-08-04 05:44:23 -05:00
feildmaster
9bed5272d3 Re-implement code missing from leaving the end. Fixes BUKKIT-2003 2012-08-04 04:11:21 -05:00
feildmaster
823e3fb0c6 Correctly detect invalid PistonExtension's to allow removal of StickyPistons. Fixes BUKKIT-2059 2012-08-04 04:10:55 -05:00
feildmaster
ab8b7c7e33 Potentially fix chunk leaking, needs further examination 2012-08-04 01:43:17 -05:00
Steve Anton
f90bd7e7cc Fix PlayerBucketEmptyEvent handling. Fixes BUKKIT-2002 and fixes BUKKIT-1997
The method this.a(world, d0, d1, d2, i, j, k) is responsible for
actually placing the lava or water source block in the world. The event
is currently called after this method, thus canceling the event will
cause the player to keep their water/lava bucket but the water/lava will
still appear where they attempted to place it.

In addition, the check for whether a player has creative inventory is
short circuiting before the event fires, so the event will not be called
for these players.

This moves the event call and cancelled check above these two calls to
ensure it always fires and the results of it are honored.

Closes GH-835.
2012-08-03 23:44:45 -05:00
Wesley Wolfe
02d6703da7 Implement new AsyncPlayerChatEvent. Addresses BUKKIT-2064
Added two utility collections for use with PlayerChatEvents allowing lazier
initialization of events and less need to synchronize against the player
list.

Provided a hidden queue system for similar logic to pre-1.3 chat. When a
plugin is listening for the deprecated PlayerChatEvent, all chat will be
delayed to be mirror executed from the main thread. All developers are
encouraged to immediately update to the developmental Bukkit chat API as a
minimum transition for server stability.

Additionally, changes were required to bring thread-safety to the flow
logic. CopyOnWriteArrayList is the only viable means to produce thread
safety with minimal diff; using a sane pre-implemented collection would
require reworking of sections of NMS logic.

As a minor change, implemented expected functionality for
PlayerCommandPreProcessEvent. Setting the player should now change the
player executing the command.
2012-08-03 23:44:45 -05:00
Travis Watkins
4942f5184a Don't merge items with enchantments. Fixes BUKKIT-2050 2012-08-03 19:30:04 -05:00
feildmaster
8834d1423e Fix 1.3 changes that prevent nether and the_end to save level data. 2012-08-03 18:58:47 -05:00
md_5
07794300d0 [Bleeding] Fire inventory close event. Fixes BUKKIT-2036 2012-08-03 02:41:48 -05:00
Mike Primm
fe8fc6b90e Process entity ticks on worlds without players. Fixes BUKKIT-2031
Both the CB 1.3.1 code, and vanilla 1.3.1 code, have modified the
behavior of entity tick processing in a way that can lead to disabling
of entity cleanup. Specifically, the tickEntities() call in n.m.s.World,
which processes both the entity cleanup (removing from the world entity
list) and tile entity tick processing (furnaces and such) does not get
called by n.m.s.MinecraftServer's q() method (which drives tick
processing calls in general) when no players are on the given world.
This causes a serious memory leak when automation processes, like dynmap
mapping, load and unload chunks - as entities on unloaded chunks are
only cleaned up during entity tick processing. It also will cause issues
with any mods that use persistent chunk loading (that is, keeping chunks
loaded so that tile entities will continue being processed), since such
processing will no longer function without at least one player on the
given world.

In any case, the tickEntities() call should be called in the same
fashion as under 1.2.x (each tick, independent of player population, as
opposed to being suspended indefinitely when no players are on the given
world). The specific memory leak observed, with removing the unloaded
entites from the world, requires this call be made regularly (or, at
least, whenever the entity unload queue (world.g) is not empty.

Closes GH-832
2012-08-03 01:19:10 -05:00
Travis Watkins
f5794937a9 Print short message on exception to avoid spamming console. Fixes BUKKIT-2018 2012-08-03 01:04:16 -05:00
Travis Watkins
dcf83bc1b5 Restore configurable connection throttle. 2012-08-03 01:04:10 -05:00
Travis Watkins
e156354a60 Add DedicatedServerConnectionThread from mc-dev for diff visibility. 2012-08-03 00:48:07 -05:00
EvilSeph
d5fea5fd0d Fixed translation issue breaking custom world generation. Fixes BUKKIT-1975 2012-08-02 23:47:41 -04:00
Mike Primm
c711827e94 Fix mapping of ChunkSection nibble data to snapshot. Fixes BUKKIT-1977 2012-08-02 21:45:54 -05:00
Luke Granger-Brown
35a3d701a9 Add trailing / to BukkitDL URLs. Fixes BUKKIT-2015.
Also adds CraftBukkit version number to user agent when communicating with
BukkitDL.
2012-08-02 21:38:32 -05:00
Travis Watkins
8dc52123bf Fix dispenser event handling 2012-08-02 17:55:13 -05:00
feildmaster
d18972eca2 Fix Nether and The End having the same world names. 2012-08-02 11:02:14 -05:00
feildmaster
402b177be4 Add missing callWorldInitEvent on startup. 2012-08-02 10:14:01 -05:00
feildmaster
764c3f24ee Add test for WorldType's 2012-08-02 09:10:15 -05:00
feildmaster
a43d621c01 Update CraftBukkit to Minecraft 1.3.1 2012-08-02 04:58:50 -05:00
EvilSeph
08e2923bd4 Updated version to 1.2.5-R5.1-SNAPSHOT for development towards next release. 2012-07-28 02:13:53 -04:00
EvilSeph
32378a7190 Updated version to 1.2.5-R5.0 in pom.xml for RB. 2012-07-28 01:49:49 -04:00
Wesley Wolfe
a4d7691299 Detect and disconnect 1.3 clients properly. Fixes BUKKIT-1952 2012-07-26 01:17:09 -05:00
Wesley Wolfe
b00de5f176 Cleaned up CraftBukkit comments in NMS.
Added newlines at the end of files
Fixed improper line endings on some files
Matched start - end comments
Added some missing comments for diffs
Fixed syntax on some spots
Minimized some diff
Removed some no longer used files
Added comment on some required files with no changes
Fixed imports of items used once
Added imports for items used more than once
2012-07-23 23:55:31 -05:00
Steve Anton
8b9aad8c2b Add remaining missing setLastDamageCause's 2012-07-14 17:57:31 -05:00
feildmaster
79189c1c13 Add missing setLastDamageCause. Thanks MonsieurApple 2012-07-13 22:57:42 -05:00
feildmaster
46125dc6cf Implement getExpToLevel method. Fixes BUKKIT-1906 2012-07-11 17:14:07 -05:00
feildmaster
cf9544c1d9 Reuse ItemInWorldManager, and stop applying ability changes. Fixes BUKKIT-1811 2012-07-09 18:07:53 -05:00
Mike Primm
08740d7f91 [Bleeding] Include chunk biome data for refresh chunk. Fixes BUKKIT-1166 2012-07-08 19:11:51 -05:00
feildmaster
dba9349ed4 Factor invulnerableTicks into getNoDamageTicks. Fixes BUKKIT-1324 2012-07-04 15:12:29 -05:00
feildmaster
d7272f42ef Implement getMotd, and reload the motd. Adds BUKKIT-1799 2012-07-03 18:00:37 -05:00
feildmaster
00efc8c464 Apply setLastDamageCause after processing events and the event has not been canceled. Fixes BUKKIT-1881
This allows previous causes to be available during the event, as well as making the damage cause a valid one. If EntityDamageEvent is canceled, then it's not the last DamageCause.

Also prevents setting DamageCause involuntarily through construction.
2012-07-02 22:22:03 -05:00
feildmaster
e4e994f710 Treat ComplexParts as proxies for setLastDamageCause. Fixes BUKKIT-1821 2012-07-02 22:22:03 -05:00
feildmaster
0a0d5ebf20 Clean entity.damage functions. Fixes BUKKIT-1822 2012-07-02 22:22:03 -05:00
Wesley Wolfe
ff09ff07f9 Fix deprecated spawnCreature. Fixes BUKKIT-1880 2012-07-02 15:36:49 -05:00
H31IX
6093bcc445 Fix client crash on InventoryClick cancel. Fixes BUKKIT-1841 2012-06-28 19:34:51 -05:00
Travis Watkins
a21f038fc3 Mark entities as invalid when they get despawned. Addresses BUKKIT-810 2012-06-28 19:34:31 -05:00
Wesley Wolfe
f5b6abfae1 Fix double overflow/underflow calculations with explosions. Fixes BUKKIT-1865 2012-06-27 21:17:20 -05:00
TomyLobo
412b7eaa12 Implement LivingEntity.hasLineOfSight. Addresses BUKKIT-1255 2012-06-23 10:48:08 -05:00
Travis Watkins
78acee359e Use LinkedHashSet to make redstone update order consistent. Fixes BUKKIT-1850 2012-06-23 10:47:38 -05:00
V10lator
ea4d3662be Deprecate spawnCreature and add spawnEntity. Addresses BUKKIT-1168 2012-06-23 10:18:50 -05:00
feildmaster
568fae2e86 Trigger EntityBlockChangeEvent for Silverfish. Adds BUKKIT-1560 and BUKKIT-1593 2012-06-23 06:42:08 -05:00
feildmaster
23d5922bbf Added EntitySilverfish for diff visibility 2012-06-23 06:42:06 -05:00
Wesley Wolfe
57763845d0 Implement plugin channel events. Addresses BUKKIT-1844 2012-06-21 02:39:59 -05:00
Travis Ralston
9f37f70527 Fire PlayerItemBreakEvent. Addresses BUKKIT-1600 2012-06-21 01:10:30 -05:00
Ammar Askar
8bc42ba8c9 Clear animal owner when untamed. Fixes BUKKIT-1482 2012-06-20 12:45:17 -05:00
H31IX
0095add08c Add query-plugins setting. Addresses BUKKIT-1781 2012-06-20 12:40:12 -05:00
Wesley Wolfe
6bbae461d5 Fix Heisenplayers 2012-06-17 01:25:01 -05:00
Jeff Wardian
ae98a6f051 Changes '/whitelist list' to ignore comments. Addresses BUKKIT-1804 2012-06-14 23:33:21 -05:00
Jeff Wardian
ae94a3308d Preserve whitelist ordering. Addresses BUKKIT-1805 2012-06-14 23:33:13 -05:00
obnoxint
e35f6f2526 Fire NotePlayEvent. Fixes BUKKIT-1779 2012-06-14 20:58:57 -05:00
obnoxint
72d64b516c Add TileEntityNote from mc-dev for diff visibility. 2012-06-14 20:58:57 -05:00
Wesley Wolfe
9002690651 Implement asynchronous pre-login event; Addresses BUKKIT-1213 2012-06-13 23:00:46 -05:00
Wesley Wolfe
ed6d4c7759 Support asynchronous events; Addresses BUKKIT-1212 2012-06-13 23:00:46 -05:00
Jake King
f58e514192 Don't send kick message if the message is empty. Fixes BUKKIT-1789 2012-06-13 22:21:40 -05:00
H31IX
01fe76733f Fire PlayerToggleFlightEvent. Fixes BUKKIT-1696 2012-06-13 22:21:35 -05:00
Wesley Wolfe
478654351a Check world before checking distance. Fixes BUKKIT-1792 2012-06-12 16:37:47 -04:00
EvilSeph
b7827c4d22 Fixed EnderDragon not dealing damage after it has been hit. Fixes BUKKIT-1751 2012-06-12 16:37:47 -04:00
Wesley Wolfe
0f23a4fe23 Synchronize handler lists 2012-06-11 01:00:35 -05:00
Travis Watkins
0942b1861b Handle rcon timeouts properly 2012-06-10 22:26:07 -05:00
EvilSeph
87600345cb Updated version to 1.2.5-R4.1-SNAPSHOT for development towards next release. 2012-06-09 21:40:34 -04:00
EvilSeph
6d8b038f31 Updated version to 1.2.5-R4.0 in pom.xml for RB. 2012-06-09 21:04:38 -04:00
feildmaster
d836e57871 Kill fireball if velocity isn't present. Fixes BUKKIT-1228 2012-06-09 04:35:55 -05:00
feildmaster
d5ba6c6644 Fix fireballs freezing when the chunk unloads. Addresses BUKKIT-1228 2012-06-09 04:35:32 -05:00
EvilSeph
3df6608a72 Fixed potential infinite loop in RCON handling. Fixes BUKKIT-1570 2012-06-09 02:52:14 -04:00
Wesley Wolfe
873ce288c2 Fixed decompile for loop handling 2012-06-09 02:47:25 -04:00
EvilSeph
282fcb44ed Added RemoteControlSession for diff visibility. 2012-06-08 20:23:44 -04:00
Travis Watkins
77cc225b83 Don't try to parse directories if we don't have any. 2012-06-06 12:12:42 -05:00
Travis Watkins
6a37511144 Try to make parent directories for --log-pattern path. Fixes BUKKIT-680 2012-06-04 18:05:23 -05:00
Travis Watkins
e385ffaefc Call ignite event for fireball shot from dispenser. 2012-06-04 17:25:39 -05:00
feildmaster
d8199aaa39 Fix a NullPointerException. 2012-06-04 04:22:22 -05:00
feildmaster
f15785669a Launch fireballs at eye location. Fixes BUKKIT-1155 2012-06-03 05:34:58 -05:00
feildmaster
e520032205 Further improving ItemStack handling 2012-06-03 05:30:22 -05:00
Travis Watkins
13fcb9e371 Make log-strip-color a simple flag instead of a boolean. 2012-06-02 14:43:38 -05:00
Travis Watkins
70c91c161e Resize UnsafeList to initial capacity when cleared and implement clone. 2012-06-01 13:03:59 -05:00
Travis Watkins
894ea06567 Reduce default size of path array. Addresses BUKKIT-1469.
The Path object creates an array of 1024 PathPoint objects as the backing
for a sorted queue but testing shows we tend to get only 80 or so entries
in the array at most. To save memory this changes the default size of the
array to 128. Changing it to 64 was considered but that triggered too many
resizes which is detremental to performance.
2012-05-31 19:55:28 -05:00
Travis Watkins
9e5d6699f5 Add Path.java from mc-dev for diff visibility 2012-05-31 19:54:31 -05:00
Wesley Wolfe
266212f9f8 Fix bold states while printing; Fixes BUKKIT-1716 2012-05-26 15:32:38 -05:00
Wesley Wolfe
25cfdfa05e Change mapping of Gold from yellow bold to yellow; Addresses BUKKIT-1717 2012-05-26 15:27:55 -05:00
EvilSeph
17cea3e57f Updated version to 1.2.5-R3.1-SNAPSHOT for development towards next release. 2012-05-26 02:24:17 -04:00
EvilSeph
a18c608830 Updated version to 1.2.5-R3.0 in pom.xml for RB. 2012-05-26 00:28:07 -04:00
Wesley Wolfe
5d3c8bfaa4 Removed AnimalTamer cache, fixes BUKKIT-1628 2012-05-24 23:02:02 -05:00
Wesley Wolfe
c43012ef1c Fixed broken hashCode() 2012-05-24 23:01:33 -05:00
Wesley Wolfe
92dce25d3c Update Bukkit API dependency to 1.2.5-R2.1-SNAPSHOT 2012-05-24 22:46:45 -05:00
Travis Watkins
c1bc0df718 Add in checks for potential NPEs. Fixes BUKKIT-1706 and BUKKIT-1590. 2012-05-24 19:12:56 -05:00
Charles Daffern
2f16b8ffa3 Don't spam console with errors on unexpected disconnect. Addresses BUKKIT-693 2012-05-23 21:53:02 -05:00
Charles Daffern
c07d4fffb0 Adding NetworkWriterThread for diff visibility 2012-05-23 21:53:01 -05:00
Charles Daffern
8be14b5bb3 Fix inaccurate head yaw. Fixes BUKKIT-1702 2012-05-23 21:52:59 -05:00
Travis Watkins
fdddc681d2 Use jansi's Windows support for terminal colors. 2012-05-23 15:32:42 -05:00
Travis Watkins
478fa4a969 Remove "failed to querty stty columns" spam. Fixes BUKKIT-1669.
When trying to execute stty to get terminal properties an
InterruptedException can be triggered even though we've read all of the
output from stty that we need. Instead of printing a warning and returning
-1 in this case try to parse what data we do have and reset the cache timer.
May also address BUKKIT-1627 and BUKKIT-1686.
2012-05-23 15:32:42 -05:00
Travis Watkins
2e744dbf64 Add files from jline for diff visibility 2012-05-23 15:32:42 -05:00
Travis Watkins
94e9543a14 Add fallback for when jline fails to initialize. Fixes BUKKIT-1675. 2012-05-23 15:32:33 -05:00
md_5
21327265f0 [Bleeding] Improve handling of ItemStacks. Addresses BUKKIT-1697 2012-05-23 04:10:49 -05:00
Score_Under
0f984dd9a5 Re-implement World.getTemperature and World.getHumidity 2012-05-23 04:02:15 -05:00
feildmaster
d484956c10 Updated version to 1.2.5-R2.1-SNAPSHOT for development towards next release 2012-05-19 17:55:53 -05:00
558 changed files with 60791 additions and 25992 deletions

2
.gitignore vendored
View File

@@ -24,7 +24,7 @@
/world
# Mac filesystem dust
/.DS_Store
.DS_Store
# intellij
*.iml

497
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,497 @@
# How to Contribute
The Bukkit project prides itself on being community built and driven. We love it when members of our community want to jump right in and get involved, so here's what you need to know.
## Quick Guide
1. Create or find an issue to address on our [JIRA issue tracker](http://leaky.bukkit.org).
- Does your proposed change [fit Bukkit's goals](#does-the-change-fit-bukkits-goals)?
- Fork the repository if you haven't done so already.
- Make your changes in a new branch (if your change affects both Bukkit and CraftBukkit, we highly suggest you use the same name for your branches in both repos).
- Test your changes.
- Push to your fork and submit a pull request.
- **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
![Life Cycle of a Bukkit Improvement](http://i.imgur.com/Ed6T7AE.png)
## Getting Started
- You'll need a free [JIRA account](http://leaky.bukkit.org) (on our issue tracker affectionately called Leaky).
- You'll need a free [GitHub account](https://github.com/signup/free).
- Make sure you have a JIRA ticket for your issue at hand.
* Either search the list of current issues and find an appropriate issue.
* Or create one yourself if one does not already exist.
* When creating an issue, make sure to clearly describe the issue (including steps to reproduce it if it is a bug).
- Fork the repository on GitHub.
- **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
## Does the Change Fit Bukkit's Goals?
As a rough guideline, ask yourself the following questions to determine if your proposed change fits the Bukkit project's goals. Please remember that this is only a rough guideline and may or may not reflect the definitive answer to this question.
* Does it expose an implementation detail of the server software, the protocol or file formats?
If your change revolves around an implementation detail then it is not proper API design. Examples of bad API design would be along the lines of a packet API, an NBT storage API, or basing an enum on implementation values.
* Does it result in unexpected behaviour as defined by the Vanilla specification?
One of the goals of the Bukkit project is to be an extended Minecraft vanilla server - meaning: if you choose to run the Bukkit server without any plugins, it should function exactly as the Minecraft server would with some rare exceptions. If your change alters the behaviour of the server in such a way that you would not have the same experience as you would in Vanilla, your change does not fit the Bukkit project's goals.
* Does it expose an issue or vulnerability when operating within the Vanilla environment?
One of the goals of the Bukkit project is to be able to operate within the limitations of the Vanilla environment. If your change results in or exposes the ability to, for example, crash the client when invalid data is set, it does not fit the Bukkit project's needs.
If you answered yes to any of these questions, chances are high your change does not fit the Bukkit project's goals and will most likely not be accepted. Regardless, there are a few other important questions you need to ask yourself before you start working on a change:
* Is this change reasonably supportable and maintainable?
* Is this change future proof?
## Making the Changes
* Create a branch on your fork where you'll be making your changes.
* Name your branch something relevant to the change you are looking to make.
* Note: if your changes affect both Bukkit and CraftBukkit, it is highly suggested you use the same branch name on both repos.
* To create a branch in Git;
* `git branch relevantBranchName`
* Then checkout the new branch with `git checkout relevantBranchName`
* Check for unnecessary whitespace with `git diff --check` before committing.
* Make sure your code meets [our requirements](#code-requirements).
* If the work you want to do involves editing Minecraft classes, be sure to read over the [Using Minecraft Internals](#using-minecraft-internals) section.
* Make sure your commit messages are in the [proper format](#commit-message-example).
* Test your changes to make sure it actually addresses the issue it should.
* Make sure your code compiles under Java 6, as that is what the project has to be built with.
### Code Requirements
* We generally follow the [Sun/Oracle coding standards](http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).
* No tabs; use 4 spaces instead.
* No trailing whitespaces.
* No CRLF line endings, LF only, set your Gits 'core.autocrlf' to 'true'.
These whitespace requirements are easily and often overlooked. They are critical formatting requirements designed to help simplify a shared heterogeneous development environment. Learn how your IDE functions in order to show you these characters and verify them. Analyse the git diff closely to verify every character and if the PR should include the character change. It is tedious and it is critical.
Eclipse: http://stackoverflow.com/a/11596227/532590
NetBeans: http://stackoverflow.com/a/1866385/532590
* No 80 column limit or 'weird' midstatement newlines.
* Any major additions should have documentation ready and provided if applicable (this is usually the case).
* Try to follow test driven development where applicable.
Bukkit employs JUnit (http://www.vogella.com/articles/JUnit/article.html) for testing and PRs should attempt to integrate with that framework as appropriate. Bukkit is a large project and what seems simple to a PR author at the time of writing a PR may easily be overlooked later by other authors and updates. Including unit tests with your PR will help to ensure the PR can be easily maintained over time and encourage the Bukkit Team to pull the PR.
* There needs to be a new line at the end of every file.
* Imports should be organised by alphabetical order, separated and grouped by package.
**For example:**
```java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.Callable;
// CraftBukkit start
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.HashSet;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.LazyPlayerSet;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
```
### Using Minecraft Internals
#### Importing a New Minecraft Class
When contributing to the Bukkit project, you will likely find that you need to edit a Minecraft class that isn't already found within the project. In this case, you need to look at [our mc-dev repository](https://github.com/Bukkit/mc-dev), find the class you need, add it to the CraftBukkit repo and include it in its own special commit separate from your other changes. The commit message of this special commit should simply be "Add x for diff visibility", where x is the name of the file you are adding from mc-dev.
If, however, you need to import multiple files from mc-dev into the Bukkit project, they should all be contained in the same special commit with the commit message "Add files for diff visibility". Note how the commit message no longer specifically mentions any class names.
#### Making Changes to Minecraft Classes
The Bukkit project employs a Minimal Diff policy to help guide when changes should be made to Minecraft classes and what those changes should be. This is to ensure that any changes made have the smallest impact possible on the update process we go through whenever a Minecraft update is released. As well as keeping the Minimal Diff policy in mind, every change made to a Minecraft class needs to be marked as such with the appropriate CraftBukkit comment.
##### Minimal Diff Policy
The Minimal Diff policy is a really important part of the project as it reminds us that every change to the Minecraft Internals has an impact on our update process. When people think of the phrase "minimal diffs", they often take it to the extreme - they go completely out of their way to abstract the changes they are trying to make away from editing Minecraft's classes as much as possible. However, this isn't what we mean by "minimal diffs". Instead, when trying to understand the minimal diffs policy, it helps to keep in mind its end goal: to reduce the impact changes we make to Minecraft's internals have on our update process.
Put simply, the Minimal Diffs Policy simply means to make the smallest change in a Minecraft class possible without duplicating logic.
Here are a few tips you should keep in mind or common areas you should focus on:
* Try to avoid duplicating logic or code when making changes.
* Try to keep your changes easily discernible - don't nest or group several unrelated changes together.
* If you only use an import once within a class, don't import it and use fully qualified names instead.
* Try to employ "short circuiting" of logic if at all possible. This means that you should force a conditional to be the value needed to side-step the code block if you would like to ignore that block of code.
**For example, to short circuit this:**
```java
if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) {
this.die();
this.h();
}
```
**You would do this:**
```java
if (false && !this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed
this.die();
this.h();
}
```
* When adding a validation check, see if the Validate package we already use has a better, more concise method you can use instead.
**For example, you should use:**
```java
Validate.notNull(sender, "Sender cannot be null");
```
**Instead of:**
```java
if (sender == null) {
throw new IllegalArgumentException("Sender cannot be null");
}
```
* When the change you are attempting to make involves removing code, instead of removing it outright, you should comment it out.
**For example:**
```java
// CraftBukkit start - special case dropping so we can get info from the tile entity
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (world.random.nextFloat() < f) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
}
// CraftBukkit end
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (entityhuman.abilities.canInstantlyBuild) {
l |= 8;
world.setData(i, j, k, l, 4);
}
super.a(world, i, j, k, l, entityhuman);
}
public void remove(World world, int i, int j, int k, int l, int i1) {
if (!world.isStatic) {
/* CraftBukkit start - drop item in code above, not here
if ((i1 & 8) == 0) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
// CraftBukkit end */
super.remove(world, i, j, k, l, i1);
}
}
```
##### General Guidelines
When editing Minecraft's classes, we have a set of rules and guidelines that need to be followed to keep us sane when it comes time for us to update Bukkit.
**CraftBukkit comments**
Changes to a Minecraft class should be clearly marked using CraftBukkit comments. Here are a few tips to help explain what kind of CraftBukkit comment to use and where to use them:
* Regardless of what kind of CraftBukkit comment you use, please take care to be explicit and exact with your usage. If the "C" in "CraftBukkit" is capitalised in the example, you should capitalise it when you use it. If the "start" begins with a lowercase "s", you should make sure yours does too.
* If the change only affects one line of code, you should use an end of line CraftBukkit comment.
**Examples:**
If the change is obvious when looking at the diff, then you just need a simple end of line CraftBukkit comment.
```java
if (true || minecraftserver.getAllowNether()) { // CraftBukkit
```
If, however, the change is something important to note or difficult to discern, you should include a reason at the end of the end of line CraftBukkit comment.
```java
public int fireTicks; // CraftBukkit - private -> public
```
If adding the CraftBukkit comment to the end of the line negatively affects the readability of the code, then you should place the CraftBukkit comment on a new line above the change you made.
```java
// CraftBukkit
if (!isEffect && !world.isStatic && world.difficulty >= 2 && world.areChunksLoaded(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2), 10)) {
```
* If the change affects more than one line, you should use a multi-line CraftBukkit comment.
**Examples:**
The majority of the time multi-line changes should be accompanied by a reason since they're usually much more complicated than a single line change. We'd like to suggest you follow the same rule as above: if the change is something important to note or difficult to discern, you should include a reason at the end of the end of line CraftBukkit comment, however it is not always clear if this is the case. Looking through the code in the project, you'll see that we sometimes include a reason when we should have left it off and vice versa.
```java
// CraftBukkit start - special case dropping so we can get info from the tile entity
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (world.random.nextFloat() < f) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
}
// CraftBukkit end
````
Otherwise, just use a multi-line CraftBukkit comment without a reason.
```java
// CraftBukkit start
BlockIgniteEvent event = new BlockIgniteEvent(this.cworld.getBlockAt(i, j, k), BlockIgniteEvent.IgniteCause.LIGHTNING, null);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
world.setTypeIdUpdate(i, j, k, Block.FIRE.id);
}
// CraftBukkit end
```
* CraftBukkit comments should be on the same indentation level of the code block it is in.
**For example:**
```java
if (j == 1) {
// CraftBukkit start - store a reference
ItemStack itemstack4 = playerinventory.getCarried();
if (itemstack4.count > 0) {
entityhuman.drop(itemstack4.a(1));
}
if (itemstack4.count == 0) {
// CraftBukkit end
playerinventory.setCarried((ItemStack) null);
}
}
```
**Other guidelines**
* When adding imports to a Minecraft class, they should be organised by alphabetical order, separated and grouped by package.
**For example:**
```java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.Callable;
// CraftBukkit start
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.HashSet;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.LazyPlayerSet;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
```
* Do not remove unused imports if they are not marked by CraftBukkit comments.
### Commit Message Example
> Provide an example commit for CONTRIBUTING.md. Fixes BUKKIT-1
>
> The CONTRIBUTING.md is missing an example commit message. Without this
> commit, we are unable to provide potential contributors with a helpful example,
> forcing developers to guess at what an acceptable commit message would look
> like. This commit fixes this issue by providing a clear and informative example
> for contributors to base their work off of.
### Commit Message Expectations
The first line in a commit message is an imperative statement briefly explaining what the commit is achieving with an associated ticket number from our JIRA, in the form of BUKKIT-#. See the list of acceptable keywords to reference tickets with for more information on this.
The body of the commit message needs to describe how the code behaves without this change, why this is a problem and how this commit addresses it. The body of the commit message should be restricted by a 78 character, plus newline, limit per line (meaning: once you hit about 78 characters, you should explicitly start a new line in the commit message).
Acceptable keywords to reference tickets with:
* **Fixes** BUKKIT-1 - this commit fixes the bug detailed in BUKKIT-1
* **Adds** BUKKIT-2 - this commit adds the new feature requested by BUKKIT-2
You can reference multiple tickets in a single commit message, for example: "Fixes BUKKIT-1, BUKKIT-2" or "Adds BUKKIT-1, BUKKIT-2" without closing punctuation.
## Submitting the Changes
* Push your changes to a topic branch in your fork of the repository.
* Submit a pull request to the relevant repository in the Bukkit organization.
* Make sure your pull request meets [our expectations](#pull-request-formatting-expectations) before submitting.
* No merges should be included in any pull requests.
* Update your JIRA ticket to reflect that you have submitted a pull request and are ready for it to be reviewed.
* Include a link to the pull request in the ticket.
* Follow our [Tips to Get Your Pull Request Accepted](#tips-to-get-your-pull-request-accepted).
* **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
### Pull Request Formatting Expectations
#### Title
> [PR Type] Brief summary. Fixes BUKKIT-####
> PR Type can be B for Bukkit, C for CraftBukkit, B+C for a PR in both sides
>
> Title Example:
> [B+C] Provide an example commit for CONTRIBUTING.md. Fixes BUKKIT-1
#### Description:
> ##### The Issue:
> Paragraphs explaining what the issue the PR is meant to be addressing.
>
> ##### Justification for this PR:
> Paragraphs providing justification for the PR
>
> ##### PR Breakdown:
> Paragraphs breaking down what the PR is doing, in detail.
>
> ##### Testing Results and Materials:
> Paragraphs describing what you did to test the code in this PR and links to pre-compiled test binaries and source.
>
> ##### Relevant PR(s):
> This should be links to accompanying PRs, or alternate PRs that attempted to perform the task. Each reference should have a reason attached as to why it is being referenced (for example: "Similar to PR ### but won't empty your Bukkits"). Accompanying PRs need no explanation, but still need to be linked.
>
> B-#### - https://github.com/Bukkit/Bukkit/pull/#### - Reason
> CB-#### - https://github.com/Bukkit/CraftBukkit/pull/#### - Reason
>
> ##### JIRA Ticket:
> BUKKIT-#### - https://bukkit.atlassian.net/browse/BUKKIT-####
>
> ##### Pull Request Check List (For Your Use):
>
>**General:**
>
>- [ ] Fits Bukkit's Goals
>- [ ] Leaky Ticket Ready
>- [ ] Code Meets Requirements
>- [ ] Code is Documented
>- [ ] Code Addresses Leaky Ticket
>- [ ] Followed Pull Request Format
>- [ ] Tested Code
>- [ ] Included Test Material and Source
>
>**If Applicable:**
>
>- [ ] Importing New Minecraft Classes In Special Commit
>- [ ] Follows Minimal Diff Policy
>- [ ] Uses Proper CraftBukkit Comments
>- [ ] Imports Are Ordered, Separated and Organised Properly
### Tips to Get Your Pull Request Accepted
Making sure you follow the above conventions is important, but just the beginning. Follow these tips to better the chances of your pull request being accepted and pulled.
* Your change should [fit with Bukkit's goals](#does-the-change-fit-bukkits-goals).
* Make sure you follow all of our conventions to the letter.
* Make sure your code compiles under Java 6.
* Check for misplaced whitespaces. It may be invisible, but [we notice](https://github.com/Bukkit/CraftBukkit/pull/1070).
* Provide proper JavaDocs where appropriate.
* JavaDocs should detail every limitation, caveat and gotcha the code has.
* Provide proper accompanying documentation where appropriate.
* Test your code and provide testing material.
* For example: adding an event? Test it with a test plugin and provide us with that plugin and its source.
* Make sure to follow coding best practises.
* Your pull request should adhere to our [Pull Request Formatting Expectations](#pull-request-formatting-expectations).
* **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
## Useful Resources
* [An example pull request demonstrating the things we look out for](https://github.com/Bukkit/CraftBukkit/pull/1070)
* [Handy gist version of our Pull Request Format Template](https://gist.github.com/EvilSeph/35bb477eaa1dffc5f1d7)
* [More information on contributing](http://wiki.bukkit.org/Getting_Involved)
* [Leaky, Our Issue Tracker (JIRA)](http://leaky.bukkit.org)
* [General GitHub documentation](http://help.github.com/)
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
* [Join us on IRC - #bukkitdev @ irc.esper.net](http://wiki.bukkit.org/IRC)

View File

@@ -4,7 +4,8 @@ CraftBukkit
A Bukkit (Minecraft Server API) implementation
Website: [http://bukkit.org](http://bukkit.org)
Bugs/Suggestions: [http://leaky.bukkit.org](http://leaky.bukkit.org)
Bugs/Suggestions: [http://leaky.bukkit.org](http://leaky.bukkit.org)
Contributing Guidelines: [CONTRIBUTING.md](https://github.com/Bukkit/CraftBukkit/blob/master/CONTRIBUTING.md)
Compilation
-----------
@@ -15,44 +16,3 @@ We use maven to handle our dependencies.
* Check out and install [Bukkit](http://github.com/Bukkit/Bukkit)
* *Note*: this is not needed as the repository we use has Bukkit too, but you might have a newer one (with your own changes :D)
* Check out this repo and: `mvn clean package`
Coding and Pull Request Conventions
-----------
* We generally follow the Sun/Oracle coding standards.
* No tabs; use 4 spaces instead.
* No trailing whitespaces.
* No CRLF line endings, LF only, put your gits 'core.autocrlf' on 'true'.
* No 80 column limit or 'weird' midstatement newlines.
* The number of commits in a pull request should be kept to a minimum (squish them into one most of the time - use common sense!).
* No merges should be included in pull requests unless the pull request's purpose is a merge.
* Pull requests should be tested (does it compile? AND does it work?) before submission.
* Any major additions should have documentation ready and provided if applicable (this is usually the case).
* Most pull requests should be accompanied by a corresponding Leaky ticket so we can associate commits with Leaky issues (this is primarily for changelog generation on dl.bukkit.org).
* Try to follow test driven development where applicable.
If you make changes or add net.minecraft.server classes it is mandatory to:
* Get the files from the [mc-dev repo](https://github.com/Bukkit/mc-dev) - make sure you have the last version!
* Make a separate commit adding the new net.minecraft.server classes (commit message: "Added x for diff visibility" or so).
* Then make further commits with your changes.
* Mark your changes with:
* 1 line; add a trailing: `// CraftBukkit [- Optional reason]`
* 2+ lines; add
* Before: `// CraftBukkit start [- Optional comment]`
* After: `// CraftBukkit end`
* Keep the diffs to a minimum (*really* important)
Tips to get your pull request accepted
-----------
Making sure you follow the above conventions is important, but just the beginning. Follow these tips to better the chances of your pull request being accepted and pulled.
* Make sure you follow all of our conventions to the letter.
* Make sure your code compiles under Java 5.
* Provide proper JavaDocs where appropriate.
* Provide proper accompanying documentation where appropriate.
* Test your code.
* Make sure to follow coding best practises.
* Provide a test plugin binary and source for us to test your code with.
* Your pull request should link to accompanying pull requests.
* The description of your pull request should provide detailed information on the pull along with justification of the changes where applicable.

46
maps.yml Normal file
View File

@@ -0,0 +1,46 @@
members:
"org/bukkit/entity/Damageable _INVALID_damage (I)V": damage
"org/bukkit/entity/Damageable _INVALID_damage (ILorg/bukkit/entity/Entity;)V": damage
"org/bukkit/entity/Damageable _INVALID_getHealth ()I": getHealth
"org/bukkit/entity/Damageable _INVALID_setHealth (I)V": setHealth
"org/bukkit/entity/Damageable _INVALID_getMaxHealth ()I": getMaxHealth
"org/bukkit/entity/Damageable _INVALID_setMaxHealth (I)V": setMaxHealth
"org/bukkit/entity/LivingEntity _INVALID_getLastDamage ()I": getLastDamage
"org/bukkit/entity/LivingEntity _INVALID_setLastDamage (I)V": setLastDamage
"org/bukkit/event/entity/EntityDamageEvent _INVALID_getDamage ()I": getDamage
"org/bukkit/event/entity/EntityDamageEvent _INVALID_setDamage (I)V": setDamage
"org/bukkit/event/vehicle/VehicleDamageEvent _INVALID_getDamage ()I": getDamage
"org/bukkit/event/vehicle/VehicleDamageEvent _INVALID_setDamage (I)V": setDamage
"org/bukkit/event/entity/EntityRegainHealthEvent _INVALID_getAmount ()I": getAmount
"org/bukkit/event/entity/EntityRegainHealthEvent _INVALID_setAmount (I)V": setAmount
"org/bukkit/entity/Minecart _INVALID_getDamage ()I": getDamage
"org/bukkit/entity/Minecart _INVALID_setDamage (I)V": setDamage
"org/bukkit/entity/Projectile _INVALID_getShooter ()Lorg/bukkit/entity/LivingEntity;": getShooter
"org/bukkit/entity/Projectile _INVALID_setShooter (Lorg/bukkit/entity/LivingEntity;)V": setShooter
"org/bukkit/Bukkit _INVALID_getOnlinePlayers ()[Lorg/bukkit/entity/Player;": getOnlinePlayers
"org/bukkit/Server _INVALID_getOnlinePlayers ()[Lorg/bukkit/entity/Player;": getOnlinePlayers
flags:
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity getHealth ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart getHealth ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity getMaxHealth ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart getMaxHealth ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity setHealth (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart setHealth (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity setMaxHealth (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart setMaxHealth (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity damage (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart damage (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity damage (ILorg/bukkit/entity/Entity;)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftEnderDragonPart damage (ILorg/bukkit/entity/Entity;)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity getLastDamage ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftLivingEntity setLastDamage (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftMinecart setDamage (I)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftMinecart getDamage ()I": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftProjectile getShooter ()Lorg/bukkit/entity/LivingEntity;": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftProjectile setShooter (Lorg/bukkit/entity/LivingEntity;)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftArrow getShooter ()Lorg/bukkit/entity/LivingEntity;": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftArrow setShooter (Lorg/bukkit/entity/LivingEntity;)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftFireball getShooter ()Lorg/bukkit/entity/LivingEntity;": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftFireball setShooter (Lorg/bukkit/entity/LivingEntity;)V": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftFish getShooter ()Lorg/bukkit/entity/LivingEntity;": 0x1001
"org/bukkit/craftbukkit/v${minecraft_version}/entity/CraftFish setShooter (Lorg/bukkit/entity/LivingEntity;)V": 0x1001

155
pom.xml
View File

@@ -4,14 +4,18 @@
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<packaging>jar</packaging>
<version>1.2.5-R2.0</version>
<version>1.7.10-R0.1-SNAPSHOT</version>
<name>CraftBukkit</name>
<url>http://www.bukkit.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<api.version>unknown</api.version>
<junit.version>4.10</junit.version>
<junit.version>4.11</junit.version>
<minecraft.version>1.7.10</minecraft.version>
<minecraft_version>1_7_R4</minecraft_version>
<buildtag.prefix>git-Bukkit-</buildtag.prefix>
<buildtag.suffix></buildtag.suffix>
</properties>
<scm>
@@ -51,14 +55,14 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.2.5-R2.0</version>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>minecraft-server</artifactId>
<version>1.2.5</version>
<version>${minecraft.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
@@ -69,6 +73,7 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- jline and jansi versions must be kept in sync -->
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
@@ -76,6 +81,13 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.8</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
@@ -90,6 +102,11 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>ebean</artifactId>
@@ -120,27 +137,16 @@
<!-- testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.2.1</version>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
@@ -152,8 +158,8 @@
<artifactId>gitdescribe-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<outputPrefix>git-Bukkit-</outputPrefix>
<outputPostfix></outputPostfix>
<outputPrefix>${buildtag.prefix}</outputPrefix>
<outputPostfix>${buildtag.suffix}</outputPostfix>
</configuration>
<executions>
<execution>
@@ -202,7 +208,7 @@
</manifestSections>
</archive>
</configuration>
</plugin>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
@@ -214,11 +220,57 @@
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>junit:junit</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.bouncycastle</pattern>
<shadedPattern>net.minecraft.v${minecraft_version}.org.bouncycastle</shadedPattern>
</relocation>
<relocation>
<pattern>joptsimple</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.joptsimple</shadedPattern>
</relocation>
<relocation>
<pattern>jline</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.jline</shadedPattern>
</relocation>
<relocation>
<pattern>org.ibex</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.org.ibex</shadedPattern>
</relocation>
<relocation>
<pattern>org.gjt</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.org.gjt</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.com.google.gson</shadedPattern>
</relocation>
<!-- These contain native libraries, and cannot be properly relocated
<relocation>
<pattern>org.fusesource</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.${project.dependencies[4].version}.org.fusesource</shadedPattern>
</relocation>
<relocation>
<pattern>org.sqlite</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.${project.dependencies[5].version}.org.sqlite</shadedPattern>
</relocation>
<relocation>
<pattern>com.mysql</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.${project.dependencies[6].version}.com.mysql</shadedPattern>
</relocation>
!-->
<relocation>
<pattern>org.bukkit.craftbukkit</pattern>
<shadedPattern>org.bukkit.craftbukkit.v${minecraft_version}</shadedPattern>
<excludes>
<exclude>org.bukkit.craftbukkit.Main*</exclude>
</excludes>
</relocation>
<relocation>
<pattern>net.minecraft.server</pattern>
<shadedPattern>net.minecraft.server.v${minecraft_version}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
@@ -226,10 +278,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
@@ -238,8 +290,55 @@
<version>2.11</version>
<configuration>
<workingDirectory>${basedir}/target/test-server</workingDirectory>
<excludes>
<exclude>org/bukkit/craftbukkit/updater/BukkitDLUpdaterServiceTest.java</exclude>
<exclude>org/bukkit/craftbukkit/inventory/ItemStack*Test.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>maps-file</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<filtering>true</filtering>
<includes>
<include>maps.yml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.wolvereness</groupId>
<artifactId>overmapped</artifactId>
<version>0.0.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>map</goal>
</goals>
<configuration>
<maps>${basedir}/target/maps.yml</maps>
<input>${basedir}/target/${project.artifactId}-${project.version}.jar</input>
<original>${basedir}/target/unmapped-${project.artifactId}-${project.version}.jar</original>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2009 the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* MODIFICATIONS: methods to deal with wrapping the output stream.
*/
package jline;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiOutputStream;
import org.fusesource.jansi.WindowsAnsiOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
/**
* ANSI-supported {@link WindowsTerminal}.
*
* @since 2.0
*/
public class AnsiWindowsTerminal
extends WindowsTerminal
{
private final boolean ansiSupported = detectAnsiSupport();
@Override
public OutputStream wrapOutIfNeeded(OutputStream out) {
return wrapOutputStream(out);
}
/**
* Returns an ansi output stream handler. We return whatever was
* passed if we determine we cannot handle ansi based on Kernel32 calls.
*
* @return an @{link AltWindowAnsiOutputStream} instance or the passed
* stream.
*/
private static OutputStream wrapOutputStream(final OutputStream stream) {
String os = System.getProperty("os.name");
if( os.startsWith("Windows") ) {
// On windows we know the console does not interpret ANSI codes..
try {
return new WindowsAnsiOutputStream(stream);
} catch (Throwable ignore) {
// this happens when JNA is not in the path.. or
// this happens when the stdout is being redirected to a file.
}
// Use the ANSIOutputStream to strip out the ANSI escape sequences.
return new AnsiOutputStream(stream);
}
return stream;
}
private static boolean detectAnsiSupport() {
AnsiConsole.systemInstall(); // CraftBukkit - install Windows JNI library
OutputStream out = AnsiConsole.wrapOutputStream(new ByteArrayOutputStream());
try {
out.close();
}
catch (Exception e) {
// ignore;
}
return out instanceof WindowsAnsiOutputStream;
}
public AnsiWindowsTerminal() throws Exception {
super();
}
@Override
public boolean isAnsiSupported() {
return ansiSupported;
}
@Override
public boolean hasWeirdWrap() {
return false;
}
}

View File

@@ -0,0 +1,227 @@
/*
* Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*/
package jline.internal;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Provides access to terminal line settings via <tt>stty</tt>.
*
* @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
* @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
* @since 2.0
*/
public final class TerminalLineSettings
{
public static final String JLINE_STTY = "jline.stty";
public static final String DEFAULT_STTY = "stty";
public static final String JLINE_SH = "jline.sh";
public static final String DEFAULT_SH = "sh";
private String sttyCommand;
private String shCommand;
private String config;
private long configLastFetched;
public TerminalLineSettings() throws IOException, InterruptedException {
sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY);
shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH);
config = get("-a");
configLastFetched = System.currentTimeMillis();
Log.debug("Config: ", config);
// sanity check
if (config.length() == 0) {
throw new IOException(MessageFormat.format("Unrecognized stty code: {0}", config));
}
}
public String getConfig() {
return config;
}
public void restore() throws IOException, InterruptedException {
set("sane");
}
public String get(final String args) throws IOException, InterruptedException {
return stty(args);
}
public void set(final String args) throws IOException, InterruptedException {
stty(args);
}
/**
* <p>
* Get the value of a stty property, including the management of a cache.
* </p>
*
* @param name the stty property.
* @return the stty property value.
*/
public int getProperty(String name) {
assert name != null;
// CraftBukkit start
long currentTime = System.currentTimeMillis();
try {
// tty properties are cached so we don't have to worry too much about getting term widht/height
if (config == null || currentTime - configLastFetched > 1000) {
config = get("-a");
}
} catch (Exception e) {
Log.debug("Failed to query stty ", name, "\n", e);
}
// always update the last fetched time and try to parse the output
if (currentTime - configLastFetched > 1000) {
configLastFetched = currentTime;
}
return this.getProperty(name, config);
// CraftBukkit end
}
/**
* <p>
* Parses a stty output (provided by stty -a) and return the value of a given property.
* </p>
*
* @param name property name.
* @param stty string resulting of stty -a execution.
* @return value of the given property.
*/
protected static int getProperty(String name, String stty) {
// try the first kind of regex
Pattern pattern = Pattern.compile(name + "\\s+=\\s+([^;]*)[;\\n\\r]");
Matcher matcher = pattern.matcher(stty);
if (!matcher.find()) {
// try a second kind of regex
pattern = Pattern.compile(name + "\\s+([^;]*)[;\\n\\r]");
matcher = pattern.matcher(stty);
if (!matcher.find()) {
// try a second try of regex
pattern = Pattern.compile("(\\S*)\\s+" + name);
matcher = pattern.matcher(stty);
if (!matcher.find()) {
return -1;
}
}
}
return parseControlChar(matcher.group(1));
}
private static int parseControlChar(String str) {
// under
if ("<undef>".equals(str)) {
return -1;
}
// octal
if (str.charAt(0) == '0') {
return Integer.parseInt(str, 8);
}
// decimal
if (str.charAt(0) >= '1' && str.charAt(0) <= '9') {
return Integer.parseInt(str, 10);
}
// control char
if (str.charAt(0) == '^') {
if (str.charAt(1) == '?') {
return 127;
} else {
return str.charAt(1) - 64;
}
} else if (str.charAt(0) == 'M' && str.charAt(1) == '-') {
if (str.charAt(2) == '^') {
if (str.charAt(3) == '?') {
return 127 + 128;
} else {
return str.charAt(3) - 64 + 128;
}
} else {
return str.charAt(2) + 128;
}
} else {
return str.charAt(0);
}
}
private String stty(final String args) throws IOException, InterruptedException {
assert args != null;
return exec(String.format("%s %s < /dev/tty", sttyCommand, args));
}
private String exec(final String cmd) throws IOException, InterruptedException {
assert cmd != null;
return exec(shCommand, "-c", cmd);
}
private String exec(final String... cmd) throws IOException, InterruptedException {
assert cmd != null;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Log.trace("Running: ", cmd);
Process p = Runtime.getRuntime().exec(cmd);
InputStream in = null;
InputStream err = null;
OutputStream out = null;
try {
int c;
in = p.getInputStream();
while ((c = in.read()) != -1) {
bout.write(c);
}
err = p.getErrorStream();
while ((c = err.read()) != -1) {
bout.write(c);
}
out = p.getOutputStream();
p.waitFor();
}
finally {
close(in, out, err);
}
String result = bout.toString();
Log.trace("Result: ", result);
return result;
}
private static void close(final Closeable... closeables) {
for (Closeable c : closeables) {
try {
c.close();
}
catch (Exception e) {
// Ignore
}
}
}
}

View File

@@ -0,0 +1,28 @@
package net.minecraft.server;
public class BiomeTheEndDecorator extends BiomeDecorator {
protected WorldGenerator J;
public BiomeTheEndDecorator() {
this.J = new WorldGenEnder(Blocks.WHITESTONE);
}
protected void a(BiomeBase biomebase) {
this.a();
if (this.b.nextInt(5) == 0) {
int i = this.c + this.b.nextInt(16) + 8;
int j = this.d + this.b.nextInt(16) + 8;
int k = this.a.i(i, j);
this.J.generate(this.a, this.b, i, k, j);
}
if (this.c == 0 && this.d == 0) {
EntityEnderDragon entityenderdragon = new EntityEnderDragon(this.a);
entityenderdragon.setPositionRotation(0.0D, 128.0D, 0.0D, this.b.nextFloat() * 360.0F, 0.0F);
this.a.addEntity(entityenderdragon, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
package net.minecraft.server;
import java.util.ArrayList;
// CraftBukkit - imported class because the constructor is package private
class BlockActionDataList extends ArrayList {
private BlockActionDataList() {}
BlockActionDataList(BananaAPI bananaapi) {
this();
}
}

View File

@@ -4,13 +4,18 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockBloodStone extends Block {
public BlockBloodStone(int i, int j) {
super(i, j, Material.STONE);
public BlockBloodStone() {
super(Material.STONE);
this.a(CreativeModeTab.b);
}
public MaterialMapColor f(int i) {
return MaterialMapColor.K;
}
// CraftBukkit start
public void doPhysics(World world, int i, int j, int k, int l) {
if (net.minecraft.server.Block.byId[l] != null && net.minecraft.server.Block.byId[l].isPowerSource()) {
if (net.minecraft.server.Block.getById(l) != null && net.minecraft.server.Block.getById(l).isPowerSource()) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int power = block.getBlockPower();

View File

@@ -1,256 +0,0 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockButton extends Block {
protected BlockButton(int i, int j) {
super(i, j, Material.ORIENTABLE);
this.a(true);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
return null;
}
public int d() {
return 20;
}
public boolean a() {
return false;
}
public boolean b() {
return false;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
return l == 2 && world.e(i, j, k + 1) ? true : (l == 3 && world.e(i, j, k - 1) ? true : (l == 4 && world.e(i + 1, j, k) ? true : l == 5 && world.e(i - 1, j, k)));
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i - 1, j, k) ? true : (world.e(i + 1, j, k) ? true : (world.e(i, j, k - 1) ? true : world.e(i, j, k + 1)));
}
public void postPlace(World world, int i, int j, int k, int l) {
int i1 = world.getData(i, j, k);
int j1 = i1 & 8;
i1 &= 7;
if (l == 2 && world.e(i, j, k + 1)) {
i1 = 4;
} else if (l == 3 && world.e(i, j, k - 1)) {
i1 = 3;
} else if (l == 4 && world.e(i + 1, j, k)) {
i1 = 2;
} else if (l == 5 && world.e(i - 1, j, k)) {
i1 = 1;
} else {
i1 = this.g(world, i, j, k);
}
world.setData(i, j, k, i1 + j1);
}
private int g(World world, int i, int j, int k) {
return world.e(i - 1, j, k) ? 1 : (world.e(i + 1, j, k) ? 2 : (world.e(i, j, k - 1) ? 3 : (world.e(i, j, k + 1) ? 4 : 1)));
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (this.h(world, i, j, k)) {
int i1 = world.getData(i, j, k) & 7;
boolean flag = false;
if (!world.e(i - 1, j, k) && i1 == 1) {
flag = true;
}
if (!world.e(i + 1, j, k) && i1 == 2) {
flag = true;
}
if (!world.e(i, j, k - 1) && i1 == 3) {
flag = true;
}
if (!world.e(i, j, k + 1) && i1 == 4) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
}
}
}
private boolean h(World world, int i, int j, int k) {
if (!this.canPlace(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
return false;
} else {
return true;
}
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
int i1 = l & 7;
boolean flag = (l & 8) > 0;
float f = 0.375F;
float f1 = 0.625F;
float f2 = 0.1875F;
float f3 = 0.125F;
if (flag) {
f3 = 0.0625F;
}
if (i1 == 1) {
this.a(0.0F, f, 0.5F - f2, f3, f1, 0.5F + f2);
} else if (i1 == 2) {
this.a(1.0F - f3, f, 0.5F - f2, 1.0F, f1, 0.5F + f2);
} else if (i1 == 3) {
this.a(0.5F - f2, f, 0.0F, 0.5F + f2, f1, f3);
} else if (i1 == 4) {
this.a(0.5F - f2, f, 1.0F - f3, 0.5F + f2, f1, 1.0F);
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.interact(world, i, j, k, entityhuman);
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
int l = world.getData(i, j, k);
int i1 = l & 7;
int j1 = 8 - (l & 8);
if (j1 == 0) {
return true;
} else {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int old = (j1 != 8) ? 1 : 0;
int current = (j1 == 8) ? 1 : 0;
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current);
world.getServer().getPluginManager().callEvent(eventRedstone);
if ((eventRedstone.getNewCurrent() > 0) != (j1 == 8)) {
return true;
}
// CraftBukkit end
world.setData(i, j, k, i1 + j1);
world.b(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.6F);
world.applyPhysics(i, j, k, this.id);
if (i1 == 1) {
world.applyPhysics(i - 1, j, k, this.id);
} else if (i1 == 2) {
world.applyPhysics(i + 1, j, k, this.id);
} else if (i1 == 3) {
world.applyPhysics(i, j, k - 1, this.id);
} else if (i1 == 4) {
world.applyPhysics(i, j, k + 1, this.id);
} else {
world.applyPhysics(i, j - 1, k, this.id);
}
world.c(i, j, k, this.id, this.d());
return true;
}
}
public void remove(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
if ((l & 8) > 0) {
world.applyPhysics(i, j, k, this.id);
int i1 = l & 7;
if (i1 == 1) {
world.applyPhysics(i - 1, j, k, this.id);
} else if (i1 == 2) {
world.applyPhysics(i + 1, j, k, this.id);
} else if (i1 == 3) {
world.applyPhysics(i, j, k - 1, this.id);
} else if (i1 == 4) {
world.applyPhysics(i, j, k + 1, this.id);
} else {
world.applyPhysics(i, j - 1, k, this.id);
}
}
super.remove(world, i, j, k);
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) > 0;
}
public boolean d(World world, int i, int j, int k, int l) {
int i1 = world.getData(i, j, k);
if ((i1 & 8) == 0) {
return false;
} else {
int j1 = i1 & 7;
return j1 == 5 && l == 1 ? true : (j1 == 4 && l == 2 ? true : (j1 == 3 && l == 3 ? true : (j1 == 2 && l == 4 ? true : j1 == 1 && l == 5)));
}
}
public boolean isPowerSource() {
return true;
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
int l = world.getData(i, j, k);
if ((l & 8) != 0) {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 1, 0);
world.getServer().getPluginManager().callEvent(eventRedstone);
if (eventRedstone.getNewCurrent() > 0) return;
// CraftBukkit end
world.setData(i, j, k, l & 7);
world.applyPhysics(i, j, k, this.id);
int i1 = l & 7;
if (i1 == 1) {
world.applyPhysics(i - 1, j, k, this.id);
} else if (i1 == 2) {
world.applyPhysics(i + 1, j, k, this.id);
} else if (i1 == 3) {
world.applyPhysics(i, j, k - 1, this.id);
} else if (i1 == 4) {
world.applyPhysics(i, j, k + 1, this.id);
} else {
world.applyPhysics(i, j - 1, k, this.id);
}
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.5F);
world.b(i, j, k, i, j, k);
}
}
}
public void f() {
float f = 0.1875F;
float f1 = 0.125F;
float f2 = 0.125F;
this.a(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2);
}
}

View File

@@ -0,0 +1,332 @@
package net.minecraft.server;
import java.util.List;
import java.util.Random;
// CraftBukkit start
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.entity.EntityInteractEvent;
// CraftBukkit end
public abstract class BlockButtonAbstract extends Block {
private final boolean a;
protected BlockButtonAbstract(boolean flag) {
super(Material.ORIENTABLE);
this.a(true);
this.a(CreativeModeTab.d);
this.a = flag;
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public int a(World world) {
return this.a ? 30 : 20;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
return l == 2 && world.getType(i, j, k + 1).r() ? true : (l == 3 && world.getType(i, j, k - 1).r() ? true : (l == 4 && world.getType(i + 1, j, k).r() ? true : l == 5 && world.getType(i - 1, j, k).r()));
}
public boolean canPlace(World world, int i, int j, int k) {
return world.getType(i - 1, j, k).r() ? true : (world.getType(i + 1, j, k).r() ? true : (world.getType(i, j, k - 1).r() ? true : world.getType(i, j, k + 1).r()));
}
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
int j1 = world.getData(i, j, k);
int k1 = j1 & 8;
j1 &= 7;
if (l == 2 && world.getType(i, j, k + 1).r()) {
j1 = 4;
} else if (l == 3 && world.getType(i, j, k - 1).r()) {
j1 = 3;
} else if (l == 4 && world.getType(i + 1, j, k).r()) {
j1 = 2;
} else if (l == 5 && world.getType(i - 1, j, k).r()) {
j1 = 1;
} else {
j1 = this.e(world, i, j, k);
}
return j1 + k1;
}
private int e(World world, int i, int j, int k) {
return world.getType(i - 1, j, k).r() ? 1 : (world.getType(i + 1, j, k).r() ? 2 : (world.getType(i, j, k - 1).r() ? 3 : (world.getType(i, j, k + 1).r() ? 4 : 1)));
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (this.m(world, i, j, k)) {
int l = world.getData(i, j, k) & 7;
boolean flag = false;
if (!world.getType(i - 1, j, k).r() && l == 1) {
flag = true;
}
if (!world.getType(i + 1, j, k).r() && l == 2) {
flag = true;
}
if (!world.getType(i, j, k - 1).r() && l == 3) {
flag = true;
}
if (!world.getType(i, j, k + 1).r() && l == 4) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
}
}
}
private boolean m(World world, int i, int j, int k) {
if (!this.canPlace(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
return false;
} else {
return true;
}
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
this.b(l);
}
private void b(int i) {
int j = i & 7;
boolean flag = (i & 8) > 0;
float f = 0.375F;
float f1 = 0.625F;
float f2 = 0.1875F;
float f3 = 0.125F;
if (flag) {
f3 = 0.0625F;
}
if (j == 1) {
this.a(0.0F, f, 0.5F - f2, f3, f1, 0.5F + f2);
} else if (j == 2) {
this.a(1.0F - f3, f, 0.5F - f2, 1.0F, f1, 0.5F + f2);
} else if (j == 3) {
this.a(0.5F - f2, f, 0.0F, 0.5F + f2, f1, f3);
} else if (j == 4) {
this.a(0.5F - f2, f, 1.0F - f3, 0.5F + f2, f1, 1.0F);
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
int i1 = world.getData(i, j, k);
int j1 = i1 & 7;
int k1 = 8 - (i1 & 8);
if (k1 == 0) {
return true;
} else {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int old = (k1 != 8) ? 15 : 0;
int current = (k1 == 8) ? 15 : 0;
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current);
world.getServer().getPluginManager().callEvent(eventRedstone);
if ((eventRedstone.getNewCurrent() > 0) != (k1 == 8)) {
return true;
}
// CraftBukkit end
world.setData(i, j, k, j1 + k1, 3);
world.c(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.6F);
this.a(world, i, j, k, j1);
world.a(i, j, k, this, this.a(world));
return true;
}
}
public void remove(World world, int i, int j, int k, Block block, int l) {
if ((l & 8) > 0) {
int i1 = l & 7;
this.a(world, i, j, k, i1);
}
super.remove(world, i, j, k, block, l);
}
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) > 0 ? 15 : 0;
}
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = iblockaccess.getData(i, j, k);
if ((i1 & 8) == 0) {
return 0;
} else {
int j1 = i1 & 7;
return j1 == 5 && l == 1 ? 15 : (j1 == 4 && l == 2 ? 15 : (j1 == 3 && l == 3 ? 15 : (j1 == 2 && l == 4 ? 15 : (j1 == 1 && l == 5 ? 15 : 0))));
}
}
public boolean isPowerSource() {
return true;
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
int l = world.getData(i, j, k);
if ((l & 8) != 0) {
if (this.a) {
this.n(world, i, j, k);
} else {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0);
world.getServer().getPluginManager().callEvent(eventRedstone);
if (eventRedstone.getNewCurrent() > 0) {
return;
}
// CraftBukkit end
world.setData(i, j, k, l & 7, 3);
int i1 = l & 7;
this.a(world, i, j, k, i1);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.5F);
world.c(i, j, k, i, j, k);
}
}
}
}
public void g() {
float f = 0.1875F;
float f1 = 0.125F;
float f2 = 0.125F;
this.a(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2);
}
public void a(World world, int i, int j, int k, Entity entity) {
if (!world.isStatic) {
if (this.a) {
if ((world.getData(i, j, k) & 8) == 0) {
this.n(world, i, j, k);
}
}
}
}
private void n(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
int i1 = l & 7;
boolean flag = (l & 8) != 0;
this.b(l);
List list = world.a(EntityArrow.class, AxisAlignedBB.a((double) i + this.minX, (double) j + this.minY, (double) k + this.minZ, (double) i + this.maxX, (double) j + this.maxY, (double) k + this.maxZ));
boolean flag1 = !list.isEmpty();
// CraftBukkit start - Call interact event when arrows turn on wooden buttons
if (flag != flag1 && flag1) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
boolean allowed = false;
// If all of the events are cancelled block the button press, else allow
for (Object object : list) {
if (object != null) {
EntityInteractEvent event = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
allowed = true;
break;
}
}
}
if (!allowed) {
return;
}
}
// CraftBukkit end
if (flag1 && !flag) {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 0, 15);
world.getServer().getPluginManager().callEvent(eventRedstone);
if (eventRedstone.getNewCurrent() <= 0) {
return;
}
// CraftBukkit end
world.setData(i, j, k, i1 | 8, 3);
this.a(world, i, j, k, i1);
world.c(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.6F);
}
if (!flag1 && flag) {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0);
world.getServer().getPluginManager().callEvent(eventRedstone);
if (eventRedstone.getNewCurrent() > 0) {
return;
}
// CraftBukkit end
world.setData(i, j, k, i1, 3);
this.a(world, i, j, k, i1);
world.c(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, 0.5F);
}
if (flag1) {
world.a(i, j, k, this, this.a(world));
}
}
private void a(World world, int i, int j, int k, int l) {
world.applyPhysics(i, j, k, this);
if (l == 1) {
world.applyPhysics(i - 1, j, k, this);
} else if (l == 2) {
world.applyPhysics(i + 1, j, k, this);
} else if (l == 3) {
world.applyPhysics(i, j, k - 1, this);
} else if (l == 4) {
world.applyPhysics(i, j, k + 1, this);
} else {
world.applyPhysics(i, j - 1, k, this);
}
}
}

View File

@@ -1,24 +1,22 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent;
// CraftBukkit end
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockCactus extends Block {
protected BlockCactus(int i, int j) {
super(i, j, Material.CACTUS);
protected BlockCactus() {
super(Material.CACTUS);
this.a(true);
this.a(CreativeModeTab.c);
}
public void a(World world, int i, int j, int k, Random random) {
if (world.isEmpty(i, j + 1, k)) {
int l;
for (l = 1; world.getTypeId(i, j - l, k) == this.id; ++l) {
for (l = 1; world.getType(i, j - l, k) == this; ++l) {
;
}
@@ -26,80 +24,63 @@ public class BlockCactus extends Block {
int i1 = world.getData(i, j, k);
if (i1 == 15) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this.id, 0); // CraftBukkit
world.setData(i, j, k, 0);
CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
world.setData(i, j, k, 0, 4);
this.doPhysics(world, i, j + 1, k, this);
} else {
world.setData(i, j, k, i1 + 1);
world.setData(i, j, k, i1 + 1, 4);
}
}
}
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
float f = 0.0625F;
return AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f));
return AxisAlignedBB.a((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f));
}
public int a(int i) {
return i == 1 ? this.textureId - 1 : (i == 0 ? this.textureId + 1 : this.textureId);
}
public boolean b() {
public boolean d() {
return false;
}
public boolean a() {
public boolean c() {
return false;
}
public int c() {
public int b() {
return 13;
}
public boolean canPlace(World world, int i, int j, int k) {
return !super.canPlace(world, i, j, k) ? false : this.f(world, i, j, k);
return !super.canPlace(world, i, j, k) ? false : this.j(world, i, j, k);
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (!this.f(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!this.j(world, i, j, k)) {
world.setAir(i, j, k, true);
}
}
public boolean f(World world, int i, int j, int k) {
if (world.getMaterial(i - 1, j, k).isBuildable()) {
public boolean j(World world, int i, int j, int k) {
if (world.getType(i - 1, j, k).getMaterial().isBuildable()) {
return false;
} else if (world.getMaterial(i + 1, j, k).isBuildable()) {
} else if (world.getType(i + 1, j, k).getMaterial().isBuildable()) {
return false;
} else if (world.getMaterial(i, j, k - 1).isBuildable()) {
} else if (world.getType(i, j, k - 1).getMaterial().isBuildable()) {
return false;
} else if (world.getMaterial(i, j, k + 1).isBuildable()) {
} else if (world.getType(i, j, k + 1).getMaterial().isBuildable()) {
return false;
} else {
int l = world.getTypeId(i, j - 1, k);
Block block = world.getType(i, j - 1, k);
return l == Block.CACTUS.id || l == Block.SAND.id;
return block == Blocks.CACTUS || block == Blocks.SAND;
}
}
public void a(World world, int i, int j, int k, Entity entity) {
// CraftBukkit start - ENTITY_DAMAGEBY_BLOCK event
if (entity instanceof EntityLiving) {
org.bukkit.block.Block damager = world.getWorld().getBlockAt(i, j, k);
org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee, EntityDamageEvent.DamageCause.CONTACT, 1);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
entity.damageEntity(DamageSource.CACTUS, event.getDamage());
}
return;
}
// CraftBukkit end
entity.damageEntity(DamageSource.CACTUS, 1);
CraftEventFactory.blockDamage = world.getWorld().getBlockAt(i, j, k); // CraftBukkit
entity.damageEntity(DamageSource.CACTUS, 1.0F);
CraftEventFactory.blockDamage = null; // CraftBukkit
}
}

View File

@@ -0,0 +1,98 @@
package net.minecraft.server;
import java.util.Random;
public class BlockCake extends Block {
protected BlockCake() {
super(Material.CAKE);
this.a(true);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
float f = 0.0625F;
float f1 = (float) (1 + l * 2) / 16.0F;
float f2 = 0.5F;
this.a(f1, 0.0F, f, 1.0F - f, f2, 1.0F - f);
}
public void g() {
float f = 0.0625F;
float f1 = 0.5F;
this.a(f, 0.0F, f, 1.0F - f, f1, 1.0F - f);
}
public AxisAlignedBB a(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
float f = 0.0625F;
float f1 = (float) (1 + l * 2) / 16.0F;
float f2 = 0.5F;
return AxisAlignedBB.a((double) ((float) i + f1), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) j + f2 - f), (double) ((float) (k + 1) - f));
}
public boolean d() {
return false;
}
public boolean c() {
return false;
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
this.b(world, i, j, k, entityhuman);
return true;
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.b(world, i, j, k, entityhuman);
}
private void b(World world, int i, int j, int k, EntityHuman entityhuman) {
if (entityhuman.g(false)) {
// CraftBukkit start
int oldFoodLevel = entityhuman.getFoodData().foodLevel;
org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, 2 + oldFoodLevel);
if (!event.isCancelled()) {
entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 0.1F);
}
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel));
// CraftBukkit end
int l = world.getData(i, j, k) + 1;
if (l >= 6) {
world.setAir(i, j, k);
} else {
world.setData(i, j, k, l, 2);
}
}
}
public boolean canPlace(World world, int i, int j, int k) {
return !super.canPlace(world, i, j, k) ? false : this.j(world, i, j, k);
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!this.j(world, i, j, k)) {
world.setAir(i, j, k);
}
}
public boolean j(World world, int i, int j, int k) {
return world.getType(i, j - 1, k).getMaterial().isBuildable();
}
public int a(Random random) {
return 0;
}
public Item getDropType(int i, Random random, int j) {
return null;
}
}

View File

@@ -1,97 +0,0 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.Random;
public class BlockCauldron extends Block {
public BlockCauldron(int i) {
super(i, Material.ORE);
this.textureId = 154;
}
public int a(int i, int j) {
return i == 1 ? 138 : (i == 0 ? 155 : 154);
}
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, ArrayList arraylist) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.3125F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
float f = 0.125F;
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
super.a(world, i, j, k, axisalignedbb, arraylist);
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
this.f();
}
public void f() {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public boolean a() {
return false;
}
public int c() {
return 24;
}
public boolean b() {
return false;
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
if (world.isStatic) {
return true;
} else {
ItemStack itemstack = entityhuman.inventory.getItemInHand();
if (itemstack == null) {
return true;
} else {
int l = world.getData(i, j, k);
if (itemstack.id == Item.WATER_BUCKET.id) {
if (l < 3) {
if (!entityhuman.abilities.canInstantlyBuild) {
entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, new ItemStack(Item.BUCKET));
}
world.setData(i, j, k, 3);
}
return true;
} else {
if (itemstack.id == Item.GLASS_BOTTLE.id && l > 0) {
ItemStack itemstack1 = new ItemStack(Item.POTION, 1, 0);
if (!entityhuman.inventory.pickup(itemstack1)) {
world.addEntity(new EntityItem(world, (double) i + 0.5D, (double) j + 1.5D, (double) k + 0.5D, itemstack1));
} else if (entityhuman instanceof EntityPlayer) { // CraftBukkit
((EntityPlayer) entityhuman).updateInventory(entityhuman.defaultContainer); // CraftBukkit
}
--itemstack.count;
if (itemstack.count <= 0) {
entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
}
world.setData(i, j, k, l - 1);
}
return true;
}
}
}
}
public int getDropType(int i, Random random, int j) {
return Item.CAULDRON.id;
}
}

View File

@@ -0,0 +1,144 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockCocoa extends BlockDirectional implements IBlockFragilePlantElement {
public BlockCocoa() {
super(Material.PLANT);
this.a(true);
}
public void a(World world, int i, int j, int k, Random random) {
if (!this.j(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeAndData(i, j, k, getById(0), 0, 2);
} else if (world.random.nextInt(5) == 0) {
int l = world.getData(i, j, k);
int i1 = c(l);
if (i1 < 2) {
++i1;
// CraftBukkit
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, i1 << 2 | l(l));
}
}
}
public boolean j(World world, int i, int j, int k) {
int l = l(world.getData(i, j, k));
i += Direction.a[l];
k += Direction.b[l];
Block block = world.getType(i, j, k);
return block == Blocks.LOG && BlockLogAbstract.c(world.getData(i, j, k)) == 3;
}
public int b() {
return 28;
}
public boolean d() {
return false;
}
public boolean c() {
return false;
}
public AxisAlignedBB a(World world, int i, int j, int k) {
this.updateShape(world, i, j, k);
return super.a(world, i, j, k);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
int i1 = l(l);
int j1 = c(l);
int k1 = 4 + j1 * 2;
int l1 = 5 + j1 * 2;
float f = (float) k1 / 2.0F;
switch (i1) {
case 0:
this.a((8.0F - f) / 16.0F, (12.0F - (float) l1) / 16.0F, (15.0F - (float) k1) / 16.0F, (8.0F + f) / 16.0F, 0.75F, 0.9375F);
break;
case 1:
this.a(0.0625F, (12.0F - (float) l1) / 16.0F, (8.0F - f) / 16.0F, (1.0F + (float) k1) / 16.0F, 0.75F, (8.0F + f) / 16.0F);
break;
case 2:
this.a((8.0F - f) / 16.0F, (12.0F - (float) l1) / 16.0F, 0.0625F, (8.0F + f) / 16.0F, 0.75F, (1.0F + (float) k1) / 16.0F);
break;
case 3:
this.a((15.0F - (float) k1) / 16.0F, (12.0F - (float) l1) / 16.0F, (8.0F - f) / 16.0F, 0.9375F, 0.75F, (8.0F + f) / 16.0F);
}
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = ((MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3) + 0) % 4;
world.setData(i, j, k, l, 2);
}
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
if (l == 1 || l == 0) {
l = 2;
}
return Direction.f[Direction.e[l]];
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!this.j(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeAndData(i, j, k, getById(0), 0, 2);
}
}
public static int c(int i) {
return (i & 12) >> 2;
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
int j1 = c(l);
byte b0 = 1;
if (j1 >= 2) {
b0 = 3;
}
for (int k1 = 0; k1 < b0; ++k1) {
this.a(world, i, j, k, new ItemStack(Items.INK_SACK, 1, 3));
}
}
public int getDropData(World world, int i, int j, int k) {
return 3;
}
public boolean a(World world, int i, int j, int k, boolean flag) {
int l = world.getData(i, j, k);
int i1 = c(l);
return i1 < 2;
}
public boolean a(World world, Random random, int i, int j, int k) {
return true;
}
public void b(World world, Random random, int i, int j, int k) {
int l = world.getData(i, j, k);
int i1 = BlockDirectional.l(l);
int j1 = c(l);
++j1;
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, j1 << 2 | i1); // CraftBukkit
}
}

View File

@@ -0,0 +1,87 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockCommand extends BlockContainer {
public BlockCommand() {
super(Material.ORE);
}
public TileEntity a(World world, int i) {
return new TileEntityCommand();
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic) {
boolean flag = world.isBlockIndirectlyPowered(i, j, k);
int l = world.getData(i, j, k);
boolean flag1 = (l & 1) != 0;
// CraftBukkit start
org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i, j, k);
int old = flag1 ? 15 : 0;
int current = flag ? 15 : 0;
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current);
world.getServer().getPluginManager().callEvent(eventRedstone);
// CraftBukkit end
if (eventRedstone.getNewCurrent() > 0 && !(eventRedstone.getOldCurrent() > 0)) { // CraftBukkit
world.setData(i, j, k, l | 1, 4);
world.a(i, j, k, this, this.a(world));
} else if (!(eventRedstone.getNewCurrent() > 0) && eventRedstone.getOldCurrent() > 0) { // CraftBukkit
world.setData(i, j, k, l & -2, 4);
}
}
}
public void a(World world, int i, int j, int k, Random random) {
TileEntity tileentity = world.getTileEntity(i, j, k);
if (tileentity != null && tileentity instanceof TileEntityCommand) {
CommandBlockListenerAbstract commandblocklistenerabstract = ((TileEntityCommand) tileentity).getCommandBlock();
commandblocklistenerabstract.a(world);
world.updateAdjacentComparators(i, j, k, this);
}
}
public int a(World world) {
return 1;
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
TileEntityCommand tileentitycommand = (TileEntityCommand) world.getTileEntity(i, j, k);
if (tileentitycommand != null) {
entityhuman.a((TileEntity) tileentitycommand);
}
return true;
}
public boolean isComplexRedstone() {
return true;
}
public int g(World world, int i, int j, int k, int l) {
TileEntity tileentity = world.getTileEntity(i, j, k);
return tileentity != null && tileentity instanceof TileEntityCommand ? ((TileEntityCommand) tileentity).getCommandBlock().g() : 0;
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
TileEntityCommand tileentitycommand = (TileEntityCommand) world.getTileEntity(i, j, k);
if (itemstack.hasName()) {
tileentitycommand.getCommandBlock().setName(itemstack.getName());
}
}
public int a(Random random) {
return 0;
}
}

View File

@@ -2,19 +2,23 @@ package net.minecraft.server;
import java.util.Random;
public class BlockCrops extends BlockFlower {
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
protected BlockCrops(int i, int j) {
super(i, j);
this.textureId = j;
public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement {
protected BlockCrops() {
this.a(true);
float f = 0.5F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
this.a((CreativeModeTab) null);
this.c(0.0F);
this.a(h);
this.H();
}
protected boolean d(int i) {
return i == Block.SOIL.id;
protected boolean a(Block block) {
return block == Blocks.SOIL;
}
public void a(World world, int i, int j, int k, Random random) {
@@ -23,46 +27,52 @@ public class BlockCrops extends BlockFlower {
int l = world.getData(i, j, k);
if (l < 7) {
float f = this.i(world, i, j, k);
float f = this.n(world, i, j, k);
if (random.nextInt((int) (25.0F / f) + 1) == 0) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this.id, ++l); // CraftBukkit
++l;
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
}
}
}
}
public void g(World world, int i, int j, int k) {
world.setData(i, j, k, 7);
public void m(World world, int i, int j, int k) {
int l = world.getData(i, j, k) + MathHelper.nextInt(world.random, 2, 5);
if (l > 7) {
l = 7;
}
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
}
private float i(World world, int i, int j, int k) {
private float n(World world, int i, int j, int k) {
float f = 1.0F;
int l = world.getTypeId(i, j, k - 1);
int i1 = world.getTypeId(i, j, k + 1);
int j1 = world.getTypeId(i - 1, j, k);
int k1 = world.getTypeId(i + 1, j, k);
int l1 = world.getTypeId(i - 1, j, k - 1);
int i2 = world.getTypeId(i + 1, j, k - 1);
int j2 = world.getTypeId(i + 1, j, k + 1);
int k2 = world.getTypeId(i - 1, j, k + 1);
boolean flag = j1 == this.id || k1 == this.id;
boolean flag1 = l == this.id || i1 == this.id;
boolean flag2 = l1 == this.id || i2 == this.id || j2 == this.id || k2 == this.id;
Block block = world.getType(i, j, k - 1);
Block block1 = world.getType(i, j, k + 1);
Block block2 = world.getType(i - 1, j, k);
Block block3 = world.getType(i + 1, j, k);
Block block4 = world.getType(i - 1, j, k - 1);
Block block5 = world.getType(i + 1, j, k - 1);
Block block6 = world.getType(i + 1, j, k + 1);
Block block7 = world.getType(i - 1, j, k + 1);
boolean flag = block2 == this || block3 == this;
boolean flag1 = block == this || block1 == this;
boolean flag2 = block4 == this || block5 == this || block6 == this || block7 == this;
for (int l2 = i - 1; l2 <= i + 1; ++l2) {
for (int i3 = k - 1; i3 <= k + 1; ++i3) {
int j3 = world.getTypeId(l2, j - 1, i3);
for (int l = i - 1; l <= i + 1; ++l) {
for (int i1 = k - 1; i1 <= k + 1; ++i1) {
float f1 = 0.0F;
if (j3 == Block.SOIL.id) {
if (world.getType(l, j - 1, i1) == Blocks.SOIL) {
f1 = 1.0F;
if (world.getData(l2, j - 1, i3) > 0) {
if (world.getData(l, j - 1, i1) > 0) {
f1 = 3.0F;
}
}
if (l2 != i || i3 != k) {
if (l != i || i1 != k) {
f1 /= 4.0F;
}
@@ -77,43 +87,50 @@ public class BlockCrops extends BlockFlower {
return f;
}
public int a(int i, int j) {
if (j < 0) {
j = 7;
}
return this.textureId + j;
public int b() {
return 6;
}
public int c() {
return 6;
protected Item i() {
return Items.SEEDS;
}
protected Item P() {
return Items.WHEAT;
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
super.dropNaturally(world, i, j, k, l, f, 0);
if (!world.isStatic) {
int j1 = 3 + i1;
if (l >= 7) {
int j1 = 3 + i1;
for (int k1 = 0; k1 < j1; ++k1) {
if (world.random.nextInt(15) <= l) {
float f1 = 0.7F;
float f2 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
float f3 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
float f4 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
EntityItem entityitem = new EntityItem(world, (double) ((float) i + f2), (double) ((float) j + f3), (double) ((float) k + f4), new ItemStack(Item.SEEDS));
entityitem.pickupDelay = 10;
world.addEntity(entityitem);
for (int k1 = 0; k1 < j1; ++k1) {
if (world.random.nextInt(15) <= l) {
this.a(world, i, j, k, new ItemStack(this.i(), 1, 0));
}
}
}
}
}
public int getDropType(int i, Random random, int j) {
return i == 7 ? Item.WHEAT.id : -1;
public Item getDropType(int i, Random random, int j) {
return i == 7 ? this.P() : this.i();
}
public int a(Random random) {
return 1;
}
public boolean a(World world, int i, int j, int k, boolean flag) {
return world.getData(i, j, k) != 7;
}
public boolean a(World world, Random random, int i, int j, int k) {
return true;
}
public void b(World world, Random random, int i, int j, int k) {
this.m(world, i, j, k);
}
}

View File

@@ -0,0 +1,72 @@
package net.minecraft.server;
import java.util.Random;
public class BlockDaylightDetector extends BlockContainer {
private IIcon[] a = new IIcon[2];
public BlockDaylightDetector() {
super(Material.WOOD);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F);
this.a(CreativeModeTab.d);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F);
}
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return iblockaccess.getData(i, j, k);
}
public void a(World world, int i, int j, int k, Random random) {}
public void doPhysics(World world, int i, int j, int k, Block block) {}
public void onPlace(World world, int i, int j, int k) {}
public void e(World world, int i, int j, int k) {
if (!world.worldProvider.g) {
int l = world.getData(i, j, k);
int i1 = world.b(EnumSkyBlock.SKY, i, j, k) - world.j;
float f = world.d(1.0F);
if (f < 3.1415927F) {
f += (0.0F - f) * 0.2F;
} else {
f += (6.2831855F - f) * 0.2F;
}
i1 = Math.round((float) i1 * MathHelper.cos(f));
if (i1 < 0) {
i1 = 0;
}
if (i1 > 15) {
i1 = 15;
}
if (l != i1) {
i1 = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, i, j, k, l, i1).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent
world.setData(i, j, k, i1, 3);
}
}
}
public boolean d() {
return false;
}
public boolean c() {
return false;
}
public boolean isPowerSource() {
return true;
}
public TileEntity a(World world, int i) {
return new TileEntityLightDetector();
}
}

View File

@@ -0,0 +1,259 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public abstract class BlockDiodeAbstract extends BlockDirectional {
protected final boolean a;
protected BlockDiodeAbstract(boolean flag) {
super(Material.ORIENTABLE);
this.a = flag;
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
}
public boolean d() {
return false;
}
public boolean canPlace(World world, int i, int j, int k) {
return !World.a((IBlockAccess) world, i, j - 1, k) ? false : super.canPlace(world, i, j, k);
}
public boolean j(World world, int i, int j, int k) {
return !World.a((IBlockAccess) world, i, j - 1, k) ? false : super.j(world, i, j, k);
}
public void a(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
if (!this.g((IBlockAccess) world, i, j, k, l)) { // CraftBukkit - Cast world to IBlockAccess to call the right method.
boolean flag = this.a(world, i, j, k, l);
if (this.a && !flag) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 15, 0).getNewCurrent() != 0) {
return;
}
// CraftBukkit end
world.setTypeAndData(i, j, k, this.i(), l, 2);
} else if (!this.a) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 0, 15).getNewCurrent() != 15) {
return;
}
// CraftBukkit end
world.setTypeAndData(i, j, k, this.e(), l, 2);
if (!flag) {
world.a(i, j, k, this.e(), this.k(l), -1);
}
}
}
}
public int b() {
return 36;
}
protected boolean c(int i) {
return this.a;
}
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return this.b(iblockaccess, i, j, k, l);
}
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = iblockaccess.getData(i, j, k);
if (!this.c(i1)) {
return 0;
} else {
int j1 = l(i1);
return j1 == 0 && l == 3 ? this.f(iblockaccess, i, j, k, i1) : (j1 == 1 && l == 4 ? this.f(iblockaccess, i, j, k, i1) : (j1 == 2 && l == 2 ? this.f(iblockaccess, i, j, k, i1) : (j1 == 3 && l == 5 ? this.f(iblockaccess, i, j, k, i1) : 0)));
}
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!this.j(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i, j, k + 1, this);
world.applyPhysics(i, j, k - 1, this);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i, j + 1, k, this);
} else {
this.b(world, i, j, k, block);
}
}
protected void b(World world, int i, int j, int k, Block block) {
int l = world.getData(i, j, k);
if (!this.g((IBlockAccess) world, i, j, k, l)) { // CraftBukkit - Cast world to IBlockAccess to call the right method.
boolean flag = this.a(world, i, j, k, l);
if ((this.a && !flag || !this.a && flag) && !world.a(i, j, k, (Block) this)) {
byte b0 = -1;
if (this.i(world, i, j, k, l)) {
b0 = -3;
} else if (this.a) {
b0 = -2;
}
world.a(i, j, k, this, this.b(l), b0);
}
}
}
public boolean g(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return false;
}
protected boolean a(World world, int i, int j, int k, int l) {
return this.h(world, i, j, k, l) > 0;
}
protected int h(World world, int i, int j, int k, int l) {
int i1 = l(l);
int j1 = i + Direction.a[i1];
int k1 = k + Direction.b[i1];
int l1 = world.getBlockFacePower(j1, j, k1, Direction.d[i1]);
return l1 >= 15 ? l1 : Math.max(l1, world.getType(j1, j, k1) == Blocks.REDSTONE_WIRE ? world.getData(j1, j, k1) : 0);
}
protected int h(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = l(l);
switch (i1) {
case 0:
case 2:
return Math.max(this.i(iblockaccess, i - 1, j, k, 4), this.i(iblockaccess, i + 1, j, k, 5));
case 1:
case 3:
return Math.max(this.i(iblockaccess, i, j, k + 1, 3), this.i(iblockaccess, i, j, k - 1, 2));
default:
return 0;
}
}
protected int i(IBlockAccess iblockaccess, int i, int j, int k, int l) {
Block block = iblockaccess.getType(i, j, k);
return this.a(block) ? (block == Blocks.REDSTONE_WIRE ? iblockaccess.getData(i, j, k) : iblockaccess.getBlockPower(i, j, k, l)) : 0;
}
public boolean isPowerSource() {
return true;
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = ((MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) % 4;
world.setData(i, j, k, l, 3);
boolean flag = this.a(world, i, j, k, l);
if (flag) {
world.a(i, j, k, this, 1);
}
}
public void onPlace(World world, int i, int j, int k) {
this.e(world, i, j, k);
}
protected void e(World world, int i, int j, int k) {
int l = l(world.getData(i, j, k));
if (l == 1) {
world.e(i + 1, j, k, this);
world.b(i + 1, j, k, this, 4);
}
if (l == 3) {
world.e(i - 1, j, k, this);
world.b(i - 1, j, k, this, 5);
}
if (l == 2) {
world.e(i, j, k + 1, this);
world.b(i, j, k + 1, this, 2);
}
if (l == 0) {
world.e(i, j, k - 1, this);
world.b(i, j, k - 1, this, 3);
}
}
public void postBreak(World world, int i, int j, int k, int l) {
if (this.a) {
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i, j, k + 1, this);
world.applyPhysics(i, j, k - 1, this);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i, j + 1, k, this);
}
super.postBreak(world, i, j, k, l);
}
public boolean c() {
return false;
}
protected boolean a(Block block) {
return block.isPowerSource();
}
protected int f(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return 15;
}
public static boolean d(Block block) {
return Blocks.DIODE_OFF.e(block) || Blocks.REDSTONE_COMPARATOR_OFF.e(block);
}
public boolean e(Block block) {
return block == this.e() || block == this.i();
}
public boolean i(World world, int i, int j, int k, int l) {
int i1 = l(l);
if (d(world.getType(i - Direction.a[i1], j, k - Direction.b[i1]))) {
int j1 = world.getData(i - Direction.a[i1], j, k - Direction.b[i1]);
int k1 = l(j1);
return k1 != i1;
} else {
return false;
}
}
protected int k(int i) {
return this.b(i);
}
protected abstract int b(int i);
protected abstract BlockDiodeAbstract e();
protected abstract BlockDiodeAbstract i();
public boolean c(Block block) {
return this.e(block);
}
}

View File

@@ -2,67 +2,55 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.util.Vector;
// CraftBukkit end
public class BlockDispenser extends BlockContainer {
private Random a = new Random();
public static final IRegistry a = new RegistryDefault(new DispenseBehaviorItem());
protected Random b = new Random();
public static boolean eventFired = false; // CraftBukkit
protected BlockDispenser(int i) {
super(i, Material.STONE);
this.textureId = 45;
protected BlockDispenser() {
super(Material.STONE);
this.a(CreativeModeTab.d);
}
public int d() {
public int a(World world) {
return 4;
}
public int getDropType(int i, Random random, int j) {
return Block.DISPENSER.id;
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
this.g(world, i, j, k);
this.m(world, i, j, k);
}
private void g(World world, int i, int j, int k) {
private void m(World world, int i, int j, int k) {
if (!world.isStatic) {
int l = world.getTypeId(i, j, k - 1);
int i1 = world.getTypeId(i, j, k + 1);
int j1 = world.getTypeId(i - 1, j, k);
int k1 = world.getTypeId(i + 1, j, k);
Block block = world.getType(i, j, k - 1);
Block block1 = world.getType(i, j, k + 1);
Block block2 = world.getType(i - 1, j, k);
Block block3 = world.getType(i + 1, j, k);
byte b0 = 3;
if (Block.n[l] && !Block.n[i1]) {
if (block.j() && !block1.j()) {
b0 = 3;
}
if (Block.n[i1] && !Block.n[l]) {
if (block1.j() && !block.j()) {
b0 = 2;
}
if (Block.n[j1] && !Block.n[k1]) {
if (block2.j() && !block3.j()) {
b0 = 5;
}
if (Block.n[k1] && !Block.n[j1]) {
if (block3.j() && !block2.j()) {
b0 = 4;
}
world.setData(i, j, k, b0);
world.setData(i, j, k, b0, 2);
}
}
public int a(int i) {
return i == 1 ? this.textureId + 17 : (i == 0 ? this.textureId + 17 : (i == 3 ? this.textureId + 1 : this.textureId));
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (world.isStatic) {
return true;
} else {
@@ -76,207 +64,126 @@ public class BlockDispenser extends BlockContainer {
}
}
// CraftBukkit - priv to public
public void dispense(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
byte b0 = 0;
byte b1 = 0;
if (l == 3) {
b1 = 1;
} else if (l == 2) {
b1 = -1;
} else if (l == 5) {
b0 = 1;
} else {
b0 = -1;
}
TileEntityDispenser tileentitydispenser = (TileEntityDispenser) world.getTileEntity(i, j, k);
// CraftBukkit - protected -> public
public void dispense(World world, int i, int j, int k) {
SourceBlock sourceblock = new SourceBlock(world, i, j, k);
TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity();
if (tileentitydispenser != null) {
// CraftBukkit start
int dispenseSlot = tileentitydispenser.findDispenseSlot();
ItemStack itemstack = null;
if (dispenseSlot > -1) {
itemstack = tileentitydispenser.getContents()[dispenseSlot];
int l = tileentitydispenser.i();
// Copy item stack, because we want it to have 1 item
itemstack = new ItemStack(itemstack.id, 1, itemstack.getData(), itemstack.getEnchantments());
}
// CraftBukkit end
double d0 = (double) i + (double) b0 * 0.6D + 0.5D;
double d1 = (double) j + 0.5D;
double d2 = (double) k + (double) b1 * 0.6D + 0.5D;
if (itemstack == null) {
if (l < 0) {
world.triggerEffect(1001, i, j, k, 0);
} else {
// CraftBukkit start
double d3 = random.nextDouble() * 0.1D + 0.2D;
double motX = (double) b0 * d3;
double motY = 0.20000000298023224D;
double motZ = (double) b1 * d3;
motX += random.nextGaussian() * 0.007499999832361937D * 6.0D;
motY += random.nextGaussian() * 0.007499999832361937D * 6.0D;
motZ += random.nextGaussian() * 0.007499999832361937D * 6.0D;
ItemStack itemstack = tileentitydispenser.getItem(l);
IDispenseBehavior idispensebehavior = this.a(itemstack);
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
org.bukkit.inventory.ItemStack bukkitItem = new CraftItemStack(itemstack).clone();
if (idispensebehavior != IDispenseBehavior.a) {
ItemStack itemstack1 = idispensebehavior.a(sourceblock, itemstack);
eventFired = false; // CraftBukkit - reset event status
BlockDispenseEvent event = new BlockDispenseEvent(block, bukkitItem, new Vector(motX, motY, motZ));
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
tileentitydispenser.setItem(l, itemstack1.count == 0 ? null : itemstack1);
}
if (event.getItem().equals(bukkitItem)) {
// Actually remove the item
tileentitydispenser.splitStack(dispenseSlot, 1);
}
motX = event.getVelocity().getX();
motY = event.getVelocity().getY();
motZ = event.getVelocity().getZ();
itemstack = CraftItemStack.createNMSItemStack(event.getItem());
// CraftBukkit end
if (itemstack.id == Item.ARROW.id) {
EntityArrow entityarrow = new EntityArrow(world, d0, d1, d2);
entityarrow.shoot((double) b0, 0.10000000149011612D, (double) b1, 1.1F, 6.0F);
entityarrow.fromPlayer = true;
world.addEntity(entityarrow);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.EGG.id) {
EntityEgg entityegg = new EntityEgg(world, d0, d1, d2);
entityegg.a((double) b0, 0.10000000149011612D, (double) b1, 1.1F, 6.0F);
world.addEntity(entityegg);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.SNOW_BALL.id) {
EntitySnowball entitysnowball = new EntitySnowball(world, d0, d1, d2);
entitysnowball.a((double) b0, 0.10000000149011612D, (double) b1, 1.1F, 6.0F);
world.addEntity(entitysnowball);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.POTION.id && ItemPotion.c(itemstack.getData())) {
EntityPotion entitypotion = new EntityPotion(world, d0, d1, d2, itemstack.getData());
entitypotion.a((double) b0, 0.10000000149011612D, (double) b1, 1.375F, 3.0F);
world.addEntity(entitypotion);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.EXP_BOTTLE.id) {
EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, d0, d1, d2);
entitythrownexpbottle.a((double) b0, 0.10000000149011612D, (double) b1, 1.375F, 3.0F);
world.addEntity(entitythrownexpbottle);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.MONSTER_EGG.id) {
ItemMonsterEgg.a(world, itemstack.getData(), d0 + (double) b0 * 0.3D, d1 - 0.3D, d2 + (double) b1 * 0.3D);
world.triggerEffect(1002, i, j, k, 0);
} else if (itemstack.id == Item.FIREBALL.id) {
EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0 + (double) b0 * 0.3D, d1, d2 + (double) b1 * 0.3D, (double) b0 + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, (double) b1 + random.nextGaussian() * 0.05D);
world.addEntity(entitysmallfireball);
world.triggerEffect(1009, i, j, k, 0);
} else {
EntityItem entityitem = new EntityItem(world, d0, d1 - 0.3D, d2, itemstack);
// CraftBukkit start
// double d3 = random.nextDouble() * 0.1D + 0.2D; // Moved up
entityitem.motX = motX;
entityitem.motY = motY;
entityitem.motZ = motZ;
// CraftBukkit end
world.addEntity(entityitem);
world.triggerEffect(1000, i, j, k, 0);
}
world.triggerEffect(2000, i, j, k, b0 + 1 + (b1 + 1) * 3);
}
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (l > 0 && Block.byId[l].isPowerSource()) {
boolean flag = world.isBlockIndirectlyPowered(i, j, k) || world.isBlockIndirectlyPowered(i, j + 1, k);
protected IDispenseBehavior a(ItemStack itemstack) {
return (IDispenseBehavior) a.get(itemstack.getItem());
}
if (flag) {
world.c(i, j, k, this.id, this.d());
}
public void doPhysics(World world, int i, int j, int k, Block block) {
boolean flag = world.isBlockIndirectlyPowered(i, j, k) || world.isBlockIndirectlyPowered(i, j + 1, k);
int l = world.getData(i, j, k);
boolean flag1 = (l & 8) != 0;
if (flag && !flag1) {
world.a(i, j, k, this, this.a(world));
world.setData(i, j, k, l | 8, 4);
} else if (!flag && flag1) {
world.setData(i, j, k, l & -9, 4);
}
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic && (world.isBlockIndirectlyPowered(i, j, k) || world.isBlockIndirectlyPowered(i, j + 1, k))) {
this.dispense(world, i, j, k, random);
if (!world.isStatic) {
this.dispense(world, i, j, k);
}
}
public TileEntity a_() {
public TileEntity a(World world, int i) {
return new TileEntityDispenser();
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving) {
int l = MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3;
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = BlockPiston.a(world, i, j, k, entityliving);
if (l == 0) {
world.setData(i, j, k, 2);
}
if (l == 1) {
world.setData(i, j, k, 5);
}
if (l == 2) {
world.setData(i, j, k, 3);
}
if (l == 3) {
world.setData(i, j, k, 4);
world.setData(i, j, k, l, 2);
if (itemstack.hasName()) {
((TileEntityDispenser) world.getTileEntity(i, j, k)).a(itemstack.getName());
}
}
public void remove(World world, int i, int j, int k) {
public void remove(World world, int i, int j, int k, Block block, int l) {
TileEntityDispenser tileentitydispenser = (TileEntityDispenser) world.getTileEntity(i, j, k);
if (tileentitydispenser != null) {
for (int l = 0; l < tileentitydispenser.getSize(); ++l) {
ItemStack itemstack = tileentitydispenser.getItem(l);
for (int i1 = 0; i1 < tileentitydispenser.getSize(); ++i1) {
ItemStack itemstack = tileentitydispenser.getItem(i1);
if (itemstack != null) {
float f = this.a.nextFloat() * 0.8F + 0.1F;
float f1 = this.a.nextFloat() * 0.8F + 0.1F;
float f2 = this.a.nextFloat() * 0.8F + 0.1F;
float f = this.b.nextFloat() * 0.8F + 0.1F;
float f1 = this.b.nextFloat() * 0.8F + 0.1F;
float f2 = this.b.nextFloat() * 0.8F + 0.1F;
while (itemstack.count > 0) {
int i1 = this.a.nextInt(21) + 10;
int j1 = this.b.nextInt(21) + 10;
if (i1 > itemstack.count) {
i1 = itemstack.count;
if (j1 > itemstack.count) {
j1 = itemstack.count;
}
itemstack.count -= i1;
EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.id, i1, itemstack.getData()));
itemstack.count -= j1;
EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.getItem(), j1, itemstack.getData()));
if (itemstack.hasTag()) {
entityitem.itemStack.setTag((NBTTagCompound) itemstack.getTag().clone());
entityitem.getItemStack().setTag((NBTTagCompound) itemstack.getTag().clone());
}
float f3 = 0.05F;
entityitem.motX = (double) ((float) this.a.nextGaussian() * f3);
entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F);
entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3);
entityitem.motX = (double) ((float) this.b.nextGaussian() * f3);
entityitem.motY = (double) ((float) this.b.nextGaussian() * f3 + 0.2F);
entityitem.motZ = (double) ((float) this.b.nextGaussian() * f3);
world.addEntity(entityitem);
}
}
}
world.updateAdjacentComparators(i, j, k, block);
}
super.remove(world, i, j, k);
super.remove(world, i, j, k, block, l);
}
public static IPosition a(ISourceBlock isourceblock) {
EnumFacing enumfacing = b(isourceblock.h());
double d0 = isourceblock.getX() + 0.7D * (double) enumfacing.getAdjacentX();
double d1 = isourceblock.getY() + 0.7D * (double) enumfacing.getAdjacentY();
double d2 = isourceblock.getZ() + 0.7D * (double) enumfacing.getAdjacentZ();
return new Position(d0, d1, d2);
}
public static EnumFacing b(int i) {
return EnumFacing.a(i & 7);
}
public boolean isComplexRedstone() {
return true;
}
public int g(World world, int i, int j, int k, int l) {
return Container.b((IInventory) world.getTileEntity(i, j, k));
}
}

View File

@@ -6,55 +6,50 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockDoor extends Block {
protected BlockDoor(int i, Material material) {
super(i, material);
this.textureId = 97;
if (material == Material.ORE) {
++this.textureId;
}
protected BlockDoor(Material material) {
super(material);
float f = 0.5F;
float f1 = 1.0F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
int l = this.e(iblockaccess, i, j, k);
int l = this.g(iblockaccess, i, j, k);
return (l & 4) != 0;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 7;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
this.updateShape(world, i, j, k);
return super.e(world, i, j, k);
return super.a(world, i, j, k);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.d(this.e(iblockaccess, i, j, k));
this.b(this.g(iblockaccess, i, j, k));
}
public int c(IBlockAccess iblockaccess, int i, int j, int k) {
return this.e(iblockaccess, i, j, k) & 3;
public int e(IBlockAccess iblockaccess, int i, int j, int k) {
return this.g(iblockaccess, i, j, k) & 3;
}
public boolean d(IBlockAccess iblockaccess, int i, int j, int k) {
return (this.e(iblockaccess, i, j, k) & 4) != 0;
public boolean f(IBlockAccess iblockaccess, int i, int j, int k) {
return (this.g(iblockaccess, i, j, k) & 4) != 0;
}
private void d(int i) {
private void b(int i) {
float f = 0.1875F;
this.a(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F);
@@ -63,58 +58,64 @@ public class BlockDoor extends Block {
boolean flag1 = (i & 16) != 0;
if (j == 0) {
if (!flag) {
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
} else if (!flag1) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
if (flag) {
if (!flag1) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
} else {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
}
} else {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
}
} else if (j == 1) {
if (!flag) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
} else if (!flag1) {
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
if (flag) {
if (!flag1) {
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
} else {
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
}
} else {
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
}
} else if (j == 2) {
if (!flag) {
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
} else if (!flag1) {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
if (flag) {
if (!flag1) {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
} else {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
}
} else {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
} else if (j == 3) {
if (!flag) {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
} else if (!flag1) {
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
if (flag) {
if (!flag1) {
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
} else {
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
} else {
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
}
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.interact(world, i, j, k, entityhuman);
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (this.material == Material.ORE) {
return true;
} else {
int l = this.e((IBlockAccess) world, i, j, k);
int i1 = l & 7;
int i1 = this.g(world, i, j, k);
int j1 = i1 & 7;
i1 ^= 4;
if ((l & 8) != 0) {
world.setData(i, j - 1, k, i1);
world.b(i, j - 1, k, i, j, k);
j1 ^= 4;
if ((i1 & 8) == 0) {
world.setData(i, j, k, j1, 2);
world.c(i, j, k, i, j, k);
} else {
world.setData(i, j, k, i1);
world.b(i, j, k, i, j, k);
world.setData(i, j - 1, k, j1, 2);
world.c(i, j - 1, k, i, j, k);
}
world.a(entityhuman, 1003, i, j, k, 0);
@@ -123,79 +124,80 @@ public class BlockDoor extends Block {
}
public void setDoor(World world, int i, int j, int k, boolean flag) {
int l = this.e((IBlockAccess) world, i, j, k);
int l = this.g(world, i, j, k);
boolean flag1 = (l & 4) != 0;
if (flag1 != flag) {
int i1 = l & 7;
i1 ^= 4;
if ((l & 8) != 0) {
world.setData(i, j - 1, k, i1);
world.b(i, j - 1, k, i, j, k);
if ((l & 8) == 0) {
world.setData(i, j, k, i1, 2);
world.c(i, j, k, i, j, k);
} else {
world.setData(i, j, k, i1);
world.b(i, j, k, i, j, k);
world.setData(i, j - 1, k, i1, 2);
world.c(i, j - 1, k, i, j, k);
}
world.a((EntityHuman) null, 1003, i, j, k, 0);
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
int i1 = world.getData(i, j, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
int l = world.getData(i, j, k);
if ((i1 & 8) != 0) {
if (world.getTypeId(i, j - 1, k) != this.id) {
world.setTypeId(i, j, k, 0);
}
else if (l > 0 && l != this.id) { // CraftBukkit
this.doPhysics(world, i, j - 1, k, l);
}
} else {
if ((l & 8) == 0) {
boolean flag = false;
if (world.getTypeId(i, j + 1, k) != this.id) {
world.setTypeId(i, j, k, 0);
if (world.getType(i, j + 1, k) != this) {
world.setAir(i, j, k);
flag = true;
}
if (!world.e(i, j - 1, k)) {
world.setTypeId(i, j, k, 0);
if (!World.a((IBlockAccess) world, i, j - 1, k)) {
world.setAir(i, j, k);
flag = true;
if (world.getTypeId(i, j + 1, k) == this.id) {
world.setTypeId(i, j + 1, k, 0);
if (world.getType(i, j + 1, k) == this) {
world.setAir(i, j + 1, k);
}
}
if (flag) {
if (!world.isStatic) {
this.b(world, i, j, k, i1, 0);
this.b(world, i, j, k, l, 0);
}
// CraftBukkit start
} else if (l > 0 && Block.byId[l].isPowerSource()) {
} else if (block.isPowerSource()) {
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.Block block = bworld.getBlockAt(i, j, k);
org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(i, j, k);
org.bukkit.block.Block blockTop = bworld.getBlockAt(i, j + 1, k);
int power = block.getBlockPower();
int power = bukkitBlock.getBlockPower();
int powerTop = blockTop.getBlockPower();
if (powerTop > power) power = powerTop;
int oldPower = (world.getData(i, j, k) & 4) > 0 ? 15 : 0;
if (oldPower == 0 ^ power == 0) {
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, oldPower, power);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power);
world.getServer().getPluginManager().callEvent(eventRedstone);
this.setDoor(world, i, j, k, eventRedstone.getNewCurrent() > 0);
}
// CraftBukkit end
}
} else {
if (world.getType(i, j - 1, k) != this) {
world.setAir(i, j, k);
}
if (block != this) {
this.doPhysics(world, i, j - 1, k, block);
}
}
}
public int getDropType(int i, Random random, int j) {
return (i & 8) != 0 ? 0 : (this.material == Material.ORE ? Item.IRON_DOOR.id : Item.WOOD_DOOR.id);
public Item getDropType(int i, Random random, int j) {
return (i & 8) != 0 ? null : (this.material == Material.ORE ? Items.IRON_DOOR : Items.WOOD_DOOR);
}
public MovingObjectPosition a(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) {
@@ -204,14 +206,14 @@ public class BlockDoor extends Block {
}
public boolean canPlace(World world, int i, int j, int k) {
return j >= 255 ? false : world.e(i, j - 1, k) && super.canPlace(world, i, j, k) && super.canPlace(world, i, j + 1, k);
return j >= 255 ? false : World.a((IBlockAccess) world, i, j - 1, k) && super.canPlace(world, i, j, k) && super.canPlace(world, i, j + 1, k);
}
public int g() {
public int h() {
return 1;
}
public int e(IBlockAccess iblockaccess, int i, int j, int k) {
public int g(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
boolean flag = (l & 8) != 0;
int i1;
@@ -226,8 +228,13 @@ public class BlockDoor extends Block {
}
boolean flag1 = (j1 & 1) != 0;
int k1 = i1 & 7 | (flag ? 8 : 0) | (flag1 ? 16 : 0);
return k1;
return i1 & 7 | (flag ? 8 : 0) | (flag1 ? 16 : 0);
}
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (entityhuman.abilities.canInstantlyBuild && (l & 8) != 0 && world.getType(i, j - 1, k) == this) {
world.setAir(i, j - 1, k);
}
}
}

View File

@@ -2,80 +2,86 @@ package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit
public class BlockDragonEgg extends Block {
public BlockDragonEgg(int i, int j) {
super(i, j, Material.DRAGON_EGG);
public BlockDragonEgg() {
super(Material.DRAGON_EGG);
this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F);
}
public void onPlace(World world, int i, int j, int k) {
world.c(i, j, k, this.id, this.d());
world.a(i, j, k, this, this.a(world));
}
public void doPhysics(World world, int i, int j, int k, int l) {
world.c(i, j, k, this.id, this.d());
public void doPhysics(World world, int i, int j, int k, Block block) {
world.a(i, j, k, this, this.a(world));
}
public void a(World world, int i, int j, int k, Random random) {
this.g(world, i, j, k);
this.e(world, i, j, k);
}
private void g(World world, int i, int j, int k) {
if (BlockSand.canFall(world, i, j - 1, k) && j >= 0) {
private void e(World world, int i, int j, int k) {
if (BlockFalling.canFall(world, i, j - 1, k) && j >= 0) {
byte b0 = 32;
if (!BlockSand.instaFall && world.a(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) {
if (!BlockFalling.instaFall && world.b(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) {
// CraftBukkit - added data
EntityFallingBlock entityfallingblock = new EntityFallingBlock(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.id, world.getData(i, j, k));
EntityFallingBlock entityfallingblock = new EntityFallingBlock(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this, world.getData(i, j, k));
world.addEntity(entityfallingblock);
} else {
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
while (BlockSand.canFall(world, i, j - 1, k) && j > 0) {
while (BlockFalling.canFall(world, i, j - 1, k) && j > 0) {
--j;
}
if (j > 0) {
world.setTypeId(i, j, k, this.id);
world.setTypeAndData(i, j, k, this, 0, 2);
}
}
}
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
this.h(world, i, j, k);
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
this.m(world, i, j, k);
return true;
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.h(world, i, j, k);
this.m(world, i, j, k);
}
private void h(World world, int i, int j, int k) {
if (world.getTypeId(i, j, k) == this.id) {
if (!world.isStatic) {
for (int l = 0; l < 1000; ++l) {
int i1 = i + world.random.nextInt(16) - world.random.nextInt(16);
int j1 = j + world.random.nextInt(8) - world.random.nextInt(8);
int k1 = k + world.random.nextInt(16) - world.random.nextInt(16);
private void m(World world, int i, int j, int k) {
if (world.getType(i, j, k) == this) {
for (int l = 0; l < 1000; ++l) {
int i1 = i + world.random.nextInt(16) - world.random.nextInt(16);
int j1 = j + world.random.nextInt(8) - world.random.nextInt(8);
int k1 = k + world.random.nextInt(16) - world.random.nextInt(16);
if (world.getTypeId(i1, j1, k1) == 0) {
// CraftBukkit start
org.bukkit.block.Block from = world.getWorld().getBlockAt(i, j, k);
org.bukkit.block.Block to = world.getWorld().getBlockAt(i1, j1, k1);
org.bukkit.event.block.BlockFromToEvent event = new org.bukkit.event.block.BlockFromToEvent(from, to);
org.bukkit.Bukkit.getPluginManager().callEvent(event);
if (world.getType(i1, j1, k1).material == Material.AIR) {
// CraftBukkit start
org.bukkit.block.Block from = world.getWorld().getBlockAt(i, j, k);
org.bukkit.block.Block to = world.getWorld().getBlockAt(i1, j1, k1);
BlockFromToEvent event = new BlockFromToEvent(from, to);
org.bukkit.Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
i1 = event.getToBlock().getX();
j1 = event.getToBlock().getY();
k1 = event.getToBlock().getZ();
} else return;
// CraftBukkit end
if (event.isCancelled()) {
return;
}
world.setTypeIdAndData(i1, j1, k1, this.id, world.getData(i, j, k));
world.setTypeId(i, j, k, 0);
i1 = event.getToBlock().getX();
j1 = event.getToBlock().getY();
k1 = event.getToBlock().getZ();
// CraftBukkit end
if (!world.isStatic) {
world.setTypeAndData(i1, j1, k1, this, world.getData(i, j, k), 2);
world.setAir(i, j, k);
} else {
short short1 = 128;
for (int l1 = 0; l1 < short1; ++l1) {
@@ -87,33 +93,29 @@ public class BlockDragonEgg extends Block {
double d2 = (double) j1 + (double) (j - j1) * d0 + world.random.nextDouble() * 1.0D - 0.5D;
double d3 = (double) k1 + (double) (k - k1) * d0 + (world.random.nextDouble() - 0.5D) * 1.0D + 0.5D;
world.a("portal", d1, d2, d3, (double) f, (double) f1, (double) f2);
world.addParticle("portal", d1, d2, d3, (double) f, (double) f1, (double) f2);
}
return;
}
return;
}
}
}
}
public int d() {
return 3;
public int a(World world) {
return 5;
}
public boolean canPlace(World world, int i, int j, int k) {
return super.canPlace(world, i, j, k);
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 27;
}
}

View File

@@ -0,0 +1,75 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
// CraftBukkit end
public class BlockDropper extends BlockDispenser {
private final IDispenseBehavior P = new DispenseBehaviorItem();
public BlockDropper() {}
protected IDispenseBehavior a(ItemStack itemstack) {
return this.P;
}
public TileEntity a(World world, int i) {
return new TileEntityDropper();
}
public void dispense(World world, int i, int j, int k) { // CraftBukkit - protected -> public
SourceBlock sourceblock = new SourceBlock(world, i, j, k);
TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity();
if (tileentitydispenser != null) {
int l = tileentitydispenser.i();
if (l < 0) {
world.triggerEffect(1001, i, j, k, 0);
} else {
ItemStack itemstack = tileentitydispenser.getItem(l);
int i1 = world.getData(i, j, k) & 7;
IInventory iinventory = TileEntityHopper.getInventoryAt(world, (double) (i + Facing.b[i1]), (double) (j + Facing.c[i1]), (double) (k + Facing.d[i1]));
ItemStack itemstack1;
if (iinventory != null) {
// CraftBukkit start - Fire event when pushing items into other inventories
CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.cloneItemStack().a(1));
org.bukkit.inventory.Inventory destinationInventory;
// Have to special case large chests as they work oddly
if (iinventory instanceof InventoryLargeChest) {
destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory);
} else {
destinationInventory = iinventory.getOwner().getInventory();
}
InventoryMoveItemEvent event = new InventoryMoveItemEvent(tileentitydispenser.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true);
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
itemstack1 = TileEntityHopper.addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), Facing.OPPOSITE_FACING[i1]);
if (event.getItem().equals(oitemstack) && itemstack1 == null) {
// CraftBukkit end
itemstack1 = itemstack.cloneItemStack();
if (--itemstack1.count == 0) {
itemstack1 = null;
}
} else {
itemstack1 = itemstack.cloneItemStack();
}
} else {
itemstack1 = this.P.a(sourceblock, itemstack);
if (itemstack1 != null && itemstack1.count == 0) {
itemstack1 = null;
}
}
tileentitydispenser.setItem(l, itemstack1);
}
}
}
}

View File

@@ -0,0 +1,66 @@
package net.minecraft.server;
import java.util.List;
import java.util.Random;
import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit
public class BlockEnderPortal extends BlockContainer {
public static boolean a;
protected BlockEnderPortal(Material material) {
super(material);
this.a(1.0F);
}
public TileEntity a(World world, int i) {
return new TileEntityEnderPortal();
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
float f = 0.0625F;
this.a(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
}
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public int a(Random random) {
return 0;
}
public void a(World world, int i, int j, int k, Entity entity) {
if (entity.vehicle == null && entity.passenger == null && !world.isStatic) {
// CraftBukkit start - Entity in portal
EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), i, j, k));
world.getServer().getPluginManager().callEvent(event);
// CraftBukkit end
entity.b(1);
}
}
public int b() {
return -1;
}
public void onPlace(World world, int i, int j, int k) {
if (!a) {
if (world.worldProvider.dimension != 0) {
world.setAir(i, j, k);
}
}
}
public MaterialMapColor f(int i) {
return MaterialMapColor.J;
}
}

View File

@@ -4,11 +4,8 @@ import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.material.MaterialData;
// CraftBukkit end
public class BlockFire extends Block {
@@ -16,42 +13,55 @@ public class BlockFire extends Block {
private int[] a = new int[256];
private int[] b = new int[256];
protected BlockFire(int i, int j) {
super(i, j, Material.FIRE);
protected BlockFire() {
super(Material.FIRE);
this.a(true);
}
public void k() {
this.a(Block.WOOD.id, 5, 20);
this.a(Block.FENCE.id, 5, 20);
this.a(Block.WOOD_STAIRS.id, 5, 20);
this.a(Block.LOG.id, 5, 5);
this.a(Block.LEAVES.id, 30, 60);
this.a(Block.BOOKSHELF.id, 30, 20);
this.a(Block.TNT.id, 15, 100);
this.a(Block.LONG_GRASS.id, 60, 100);
this.a(Block.WOOL.id, 30, 60);
this.a(Block.VINE.id, 15, 100);
public static void e() {
Blocks.FIRE.a(getId(Blocks.WOOD), 5, 20);
Blocks.FIRE.a(getId(Blocks.WOOD_DOUBLE_STEP), 5, 20);
Blocks.FIRE.a(getId(Blocks.WOOD_STEP), 5, 20);
Blocks.FIRE.a(getId(Blocks.FENCE), 5, 20);
Blocks.FIRE.a(getId(Blocks.WOOD_STAIRS), 5, 20);
Blocks.FIRE.a(getId(Blocks.BIRCH_WOOD_STAIRS), 5, 20);
Blocks.FIRE.a(getId(Blocks.SPRUCE_WOOD_STAIRS), 5, 20);
Blocks.FIRE.a(getId(Blocks.JUNGLE_WOOD_STAIRS), 5, 20);
Blocks.FIRE.a(getId(Blocks.LOG), 5, 5);
Blocks.FIRE.a(getId(Blocks.LOG2), 5, 5);
Blocks.FIRE.a(getId(Blocks.LEAVES), 30, 60);
Blocks.FIRE.a(getId(Blocks.LEAVES2), 30, 60);
Blocks.FIRE.a(getId(Blocks.BOOKSHELF), 30, 20);
Blocks.FIRE.a(getId(Blocks.TNT), 15, 100);
Blocks.FIRE.a(getId(Blocks.LONG_GRASS), 60, 100);
Blocks.FIRE.a(getId(Blocks.DOUBLE_PLANT), 60, 100);
Blocks.FIRE.a(getId(Blocks.YELLOW_FLOWER), 60, 100);
Blocks.FIRE.a(getId(Blocks.RED_ROSE), 60, 100);
Blocks.FIRE.a(getId(Blocks.WOOL), 30, 60);
Blocks.FIRE.a(getId(Blocks.VINE), 15, 100);
Blocks.FIRE.a(getId(Blocks.COAL_BLOCK), 5, 5);
Blocks.FIRE.a(getId(Blocks.HAY_BLOCK), 60, 20);
Blocks.FIRE.a(getId(Blocks.WOOL_CARPET), 60, 20);
}
private void a(int i, int j, int k) {
public void a(int i, int j, int k) {
this.a[i] = j;
this.b[i] = k;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 3;
}
@@ -59,108 +69,100 @@ public class BlockFire extends Block {
return 0;
}
public int d() {
public int a(World world) {
return 30;
}
public void a(World world, int i, int j, int k, Random random) {
boolean flag = world.getTypeId(i, j - 1, k) == Block.NETHERRACK.id;
if (world.getGameRules().getBoolean("doFireTick")) {
boolean flag = world.getType(i, j - 1, k) == Blocks.NETHERRACK;
if (world.worldProvider instanceof WorldProviderTheEnd && world.getTypeId(i, j - 1, k) == Block.BEDROCK.id) {
flag = true;
}
if (!this.canPlace(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - invalid place location
}
if (!flag && world.x() && (world.y(i, j, k) || world.y(i - 1, j, k) || world.y(i + 1, j, k) || world.y(i, j, k - 1) || world.y(i, j, k + 1))) {
fireExtinguished(world, i, j, k); // CraftBukkit - extinguished by rain
} else {
int l = world.getData(i, j, k);
if (l < 15) {
world.setRawData(i, j, k, l + random.nextInt(3) / 2);
if (world.worldProvider instanceof WorldProviderTheEnd && world.getType(i, j - 1, k) == Blocks.BEDROCK) {
flag = true;
}
world.c(i, j, k, this.id, this.d() + random.nextInt(10));
if (!flag && !this.g(world, i, j, k)) {
if (!world.e(i, j - 1, k) || l > 3) {
fireExtinguished(world, i, j, k); // CraftBukkit - burn out
}
} else if (!flag && !this.c(world, i, j - 1, k) && l == 15 && random.nextInt(4) == 0) {
fireExtinguished(world, i, j, k); // CraftBukkit - burn out
if (!this.canPlace(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - invalid place location
}
if (!flag && world.Q() && (world.isRainingAt(i, j, k) || world.isRainingAt(i - 1, j, k) || world.isRainingAt(i + 1, j, k) || world.isRainingAt(i, j, k - 1) || world.isRainingAt(i, j, k + 1))) {
fireExtinguished(world, i, j, k); // CraftBukkit - extinguished by rain
} else {
boolean flag1 = world.z(i, j, k);
byte b0 = 0;
int l = world.getData(i, j, k);
if (flag1) {
b0 = -50;
if (l < 15) {
world.setData(i, j, k, l + random.nextInt(3) / 2, 4);
}
this.a(world, i + 1, j, k, 300 + b0, random, l);
this.a(world, i - 1, j, k, 300 + b0, random, l);
this.a(world, i, j - 1, k, 250 + b0, random, l);
this.a(world, i, j + 1, k, 250 + b0, random, l);
this.a(world, i, j, k - 1, 300 + b0, random, l);
this.a(world, i, j, k + 1, 300 + b0, random, l);
world.a(i, j, k, this, this.a(world) + random.nextInt(10));
if (!flag && !this.e(world, i, j, k)) {
if (!World.a((IBlockAccess) world, i, j - 1, k) || l > 3) {
fireExtinguished(world, i, j, k); // CraftBukkit - burn out of inflammable block
}
} else if (!flag && !this.e((IBlockAccess) world, i, j - 1, k) && l == 15 && random.nextInt(4) == 0) {
fireExtinguished(world, i, j, k); // CraftBukkit - burn out
} else {
boolean flag1 = world.z(i, j, k);
byte b0 = 0;
// CraftBukkit start - Call to stop spread of fire.
org.bukkit.Server server = world.getServer();
org.bukkit.World bworld = world.getWorld();
if (flag1) {
b0 = -50;
}
IgniteCause igniteCause = BlockIgniteEvent.IgniteCause.SPREAD;
org.bukkit.block.Block fromBlock = bworld.getBlockAt(i, j, k);
// CraftBukkit end
this.a(world, i + 1, j, k, 300 + b0, random, l);
this.a(world, i - 1, j, k, 300 + b0, random, l);
this.a(world, i, j - 1, k, 250 + b0, random, l);
this.a(world, i, j + 1, k, 250 + b0, random, l);
this.a(world, i, j, k - 1, 300 + b0, random, l);
this.a(world, i, j, k + 1, 300 + b0, random, l);
for (int i1 = i - 1; i1 <= i + 1; ++i1) {
for (int j1 = k - 1; j1 <= k + 1; ++j1) {
for (int k1 = j - 1; k1 <= j + 4; ++k1) {
if (i1 != i || k1 != j || j1 != k) {
int l1 = 100;
for (int i1 = i - 1; i1 <= i + 1; ++i1) {
for (int j1 = k - 1; j1 <= k + 1; ++j1) {
for (int k1 = j - 1; k1 <= j + 4; ++k1) {
if (i1 != i || k1 != j || j1 != k) {
int l1 = 100;
if (k1 > j + 1) {
l1 += (k1 - (j + 1)) * 100;
}
int i2 = this.h(world, i1, k1, j1);
if (i2 > 0) {
int j2 = (i2 + 40) / (l + 30);
if (flag1) {
j2 /= 2;
if (k1 > j + 1) {
l1 += (k1 - (j + 1)) * 100;
}
if (j2 > 0 && random.nextInt(l1) <= j2 && (!world.x() || !world.y(i1, k1, j1)) && !world.y(i1 - 1, k1, k) && !world.y(i1 + 1, k1, j1) && !world.y(i1, k1, j1 - 1) && !world.y(i1, k1, j1 + 1)) {
int k2 = l + random.nextInt(5) / 4;
int i2 = this.m(world, i1, k1, j1);
if (k2 > 15) {
k2 = 15;
if (i2 > 0) {
int j2 = (i2 + 40 + world.difficulty.a() * 7) / (l + 30);
if (flag1) {
j2 /= 2;
}
// CraftBukkit start - Call to stop spread of fire.
org.bukkit.block.Block block = bworld.getBlockAt(i1, k1, j1);
if (block.getTypeId() != Block.FIRE.id) {
BlockIgniteEvent event = new BlockIgniteEvent(block, igniteCause, null);
server.getPluginManager().callEvent(event);
if (j2 > 0 && random.nextInt(l1) <= j2 && (!world.Q() || !world.isRainingAt(i1, k1, j1)) && !world.isRainingAt(i1 - 1, k1, k) && !world.isRainingAt(i1 + 1, k1, j1) && !world.isRainingAt(i1, k1, j1 - 1) && !world.isRainingAt(i1, k1, j1 + 1)) {
int k2 = l + random.nextInt(5) / 4;
if (event.isCancelled()) {
continue;
if (k2 > 15) {
k2 = 15;
}
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, k1, j1).getState();
blockState.setTypeId(this.id);
blockState.setData(new MaterialData(this.id, (byte) k2));
// CraftBukkit start - Call to stop spread of fire
if (world.getType(i1, k1, j1) != Blocks.FIRE) {
if (CraftEventFactory.callBlockIgniteEvent(world, i1, k1, j1, i, j, k).isCancelled()) {
continue;
}
BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), fromBlock, blockState);
server.getPluginManager().callEvent(spreadEvent);
org.bukkit.Server server = world.getServer();
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, k1, j1).getState();
blockState.setTypeId(Block.getId(this));
blockState.setData(new org.bukkit.material.MaterialData(Block.getId(this), (byte) k2));
if (!spreadEvent.isCancelled()) {
blockState.update(true);
BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(i, j, k), blockState);
server.getPluginManager().callEvent(spreadEvent);
if (!spreadEvent.isCancelled()) {
blockState.update(true);
}
}
// CraftBukkit end
}
// CraftBukkit end
}
}
}
@@ -171,11 +173,16 @@ public class BlockFire extends Block {
}
}
public boolean L() {
return false;
}
private void a(World world, int i, int j, int k, int l, Random random, int i1) {
int j1 = this.b[world.getTypeId(i, j, k)];
int j1 = this.b[Block.getId(world.getType(i, j, k))];
if (random.nextInt(l) < j1) {
boolean flag = world.getTypeId(i, j, k) == Block.TNT.id;
boolean flag = world.getType(i, j, k) == Blocks.TNT;
// CraftBukkit start
org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(i, j, k);
@@ -187,82 +194,87 @@ public class BlockFire extends Block {
}
// CraftBukkit end
if (random.nextInt(i1 + 10) < 5 && !world.y(i, j, k)) {
if (random.nextInt(i1 + 10) < 5 && !world.isRainingAt(i, j, k)) {
int k1 = i1 + random.nextInt(5) / 4;
if (k1 > 15) {
k1 = 15;
}
world.setTypeIdAndData(i, j, k, this.id, k1);
world.setTypeAndData(i, j, k, this, k1, 3);
} else {
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
}
if (flag) {
Block.TNT.postBreak(world, i, j, k, 1);
Blocks.TNT.postBreak(world, i, j, k, 1);
}
}
}
private boolean g(World world, int i, int j, int k) {
return this.c(world, i + 1, j, k) ? true : (this.c(world, i - 1, j, k) ? true : (this.c(world, i, j - 1, k) ? true : (this.c(world, i, j + 1, k) ? true : (this.c(world, i, j, k - 1) ? true : this.c(world, i, j, k + 1)))));
private boolean e(World world, int i, int j, int k) {
return this.e((IBlockAccess) world, i + 1, j, k) ? true : (this.e((IBlockAccess) world, i - 1, j, k) ? true : (this.e((IBlockAccess) world, i, j - 1, k) ? true : (this.e((IBlockAccess) world, i, j + 1, k) ? true : (this.e((IBlockAccess) world, i, j, k - 1) ? true : this.e((IBlockAccess) world, i, j, k + 1)))));
}
private int h(World world, int i, int j, int k) {
private int m(World world, int i, int j, int k) {
byte b0 = 0;
if (!world.isEmpty(i, j, k)) {
return 0;
} else {
int l = this.f(world, i + 1, j, k, b0);
int l = this.a(world, i + 1, j, k, b0);
l = this.f(world, i - 1, j, k, l);
l = this.f(world, i, j - 1, k, l);
l = this.f(world, i, j + 1, k, l);
l = this.f(world, i, j, k - 1, l);
l = this.f(world, i, j, k + 1, l);
l = this.a(world, i - 1, j, k, l);
l = this.a(world, i, j - 1, k, l);
l = this.a(world, i, j + 1, k, l);
l = this.a(world, i, j, k - 1, l);
l = this.a(world, i, j, k + 1, l);
return l;
}
}
public boolean E_() {
public boolean v() {
return false;
}
public boolean c(IBlockAccess iblockaccess, int i, int j, int k) {
return this.a[iblockaccess.getTypeId(i, j, k)] > 0;
public boolean e(IBlockAccess iblockaccess, int i, int j, int k) {
return this.a[Block.getId(iblockaccess.getType(i, j, k))] > 0;
}
public int f(World world, int i, int j, int k, int l) {
int i1 = this.a[world.getTypeId(i, j, k)];
public int a(World world, int i, int j, int k, int l) {
int i1 = this.a[Block.getId(world.getType(i, j, k))];
return i1 > l ? i1 : l;
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i, j - 1, k) || this.g(world, i, j, k);
return World.a((IBlockAccess) world, i, j - 1, k) || this.e(world, i, j, k);
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (!world.e(i, j - 1, k) && !this.g(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - fuel block gone
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!World.a((IBlockAccess) world, i, j - 1, k) && !this.e(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - fuel block gone
}
}
public void onPlace(World world, int i, int j, int k) {
if (world.worldProvider.dimension > 0 || world.getTypeId(i, j - 1, k) != Block.OBSIDIAN.id || !Block.PORTAL.b_(world, i, j, k)) {
if (!world.e(i, j - 1, k) && !this.g(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - fuel block broke
if (world.worldProvider.dimension > 0 || !Blocks.PORTAL.e(world, i, j, k)) {
if (!World.a((IBlockAccess) world, i, j - 1, k) && !this.e(world, i, j, k)) {
fireExtinguished(world, i, j, k); // CraftBukkit - fuel block broke
} else {
world.c(i, j, k, this.id, this.d() + world.random.nextInt(10));
world.a(i, j, k, this, this.a(world) + world.random.nextInt(10));
}
}
}
public MaterialMapColor f(int i) {
return MaterialMapColor.f;
}
// CraftBukkit start
private void fireExtinguished(World world, int x, int y, int z) {
if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(x, y, z), 0).isCancelled() == false) {
world.setTypeId(x, y, z, 0);
if (!CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(x, y, z), Blocks.AIR).isCancelled()) {
world.setAir(x, y, z);
}
}
// CraftBukkit end

View File

@@ -9,24 +9,18 @@ import org.bukkit.event.block.BlockFromToEvent;
public class BlockFlowing extends BlockFluids {
int a = 0;
int a;
boolean[] b = new boolean[4];
int[] c = new int[4];
int[] M = new int[4];
protected BlockFlowing(int i, Material material) {
super(i, material);
protected BlockFlowing(Material material) {
super(material);
}
private void i(World world, int i, int j, int k) {
private void n(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
world.setRawTypeIdAndData(i, j, k, this.id + 1, l);
world.b(i, j, k, i, j, k);
world.notify(i, j, k);
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
return this.material != Material.LAVA;
world.setTypeAndData(i, j, k, Block.getById(Block.getId(this) + 1), l, 2);
}
public void a(World world, int i, int j, int k, Random random) {
@@ -36,104 +30,106 @@ public class BlockFlowing extends BlockFluids {
org.bukkit.block.Block source = bworld == null ? null : bworld.getBlockAt(i, j, k);
// CraftBukkit end
int l = this.g(world, i, j, k);
int l = this.e(world, i, j, k);
byte b0 = 1;
if (this.material == Material.LAVA && !world.worldProvider.d) {
if (this.material == Material.LAVA && !world.worldProvider.f) {
b0 = 2;
}
boolean flag = true;
int i1;
int i1 = this.a(world);
int j1;
if (l > 0) {
byte b1 = -100;
this.a = 0;
int j1 = this.f(world, i - 1, j, k, b1);
int k1 = this.a(world, i - 1, j, k, b1);
j1 = this.f(world, i + 1, j, k, j1);
j1 = this.f(world, i, j, k - 1, j1);
j1 = this.f(world, i, j, k + 1, j1);
i1 = j1 + b0;
if (i1 >= 8 || j1 < 0) {
i1 = -1;
k1 = this.a(world, i + 1, j, k, k1);
k1 = this.a(world, i, j, k - 1, k1);
k1 = this.a(world, i, j, k + 1, k1);
j1 = k1 + b0;
if (j1 >= 8 || k1 < 0) {
j1 = -1;
}
if (this.g(world, i, j + 1, k) >= 0) {
int k1 = this.g(world, i, j + 1, k);
if (this.e(world, i, j + 1, k) >= 0) {
int l1 = this.e(world, i, j + 1, k);
if (k1 >= 8) {
i1 = k1;
if (l1 >= 8) {
j1 = l1;
} else {
i1 = k1 + 8;
j1 = l1 + 8;
}
}
if (this.a >= 2 && this.material == Material.WATER) {
if (world.getMaterial(i, j - 1, k).isBuildable()) {
i1 = 0;
} else if (world.getMaterial(i, j - 1, k) == this.material && world.getData(i, j, k) == 0) {
i1 = 0;
if (world.getType(i, j - 1, k).getMaterial().isBuildable()) {
j1 = 0;
} else if (world.getType(i, j - 1, k).getMaterial() == this.material && world.getData(i, j - 1, k) == 0) {
j1 = 0;
}
}
if (this.material == Material.LAVA && l < 8 && i1 < 8 && i1 > l && random.nextInt(4) != 0) {
i1 = l;
flag = false;
if (this.material == Material.LAVA && l < 8 && j1 < 8 && j1 > l && random.nextInt(4) != 0) {
i1 *= 4;
}
if (i1 != l) {
l = i1;
if (i1 < 0) {
world.setTypeId(i, j, k, 0);
if (j1 == l) {
if (flag) {
this.n(world, i, j, k);
}
} else {
l = j1;
if (j1 < 0) {
world.setAir(i, j, k);
} else {
world.setData(i, j, k, i1);
world.c(i, j, k, this.id, this.d());
world.applyPhysics(i, j, k, this.id);
world.setData(i, j, k, j1, 2);
world.a(i, j, k, this, i1);
world.applyPhysics(i, j, k, this);
}
} else if (flag) {
this.i(world, i, j, k);
}
} else {
this.i(world, i, j, k);
this.n(world, i, j, k);
}
if (this.l(world, i, j - 1, k)) {
// CraftBukkit start - send "down" to the server
if (this.q(world, i, j - 1, k)) {
// CraftBukkit start - Send "down" to the server
BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN);
if (server != null) {
server.getPluginManager().callEvent(event);
}
if (!event.isCancelled()) {
if (this.material == Material.LAVA && world.getMaterial(i, j - 1, k) == Material.WATER) {
world.setTypeId(i, j - 1, k, Block.STONE.id);
if (this.material == Material.LAVA && world.getType(i, j - 1, k).getMaterial() == Material.WATER) {
world.setTypeUpdate(i, j - 1, k, Blocks.STONE);
this.fizz(world, i, j - 1, k);
return;
}
if (l >= 8) {
world.setTypeIdAndData(i, j - 1, k, this.id, l);
this.flow(world, i, j - 1, k, l);
} else {
world.setTypeIdAndData(i, j - 1, k, this.id, l + 8);
this.flow(world, i, j - 1, k, l + 8);
}
}
// CraftBukkit end
} else if (l >= 0 && (l == 0 || this.k(world, i, j - 1, k))) {
boolean[] aboolean = this.j(world, i, j, k);
} else if (l >= 0 && (l == 0 || this.p(world, i, j - 1, k))) {
boolean[] aboolean = this.o(world, i, j, k);
i1 = l + b0;
j1 = l + b0;
if (l >= 8) {
i1 = 1;
j1 = 1;
}
if (i1 >= 8) {
if (j1 >= 8) {
return;
}
// CraftBukkit start - all four cardinal directions. Do not change the order!
BlockFace[] faces = new BlockFace[] { BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST };
// CraftBukkit start - All four cardinal directions. Do not change the order!
BlockFace[] faces = new BlockFace[] { BlockFace.WEST, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH };
int index = 0;
for (BlockFace currentFace : faces) {
@@ -145,7 +141,7 @@ public class BlockFlowing extends BlockFluids {
}
if (!event.isCancelled()) {
this.flow(world, i + currentFace.getModX(), j, k + currentFace.getModZ(), i1);
this.flow(world, i + currentFace.getModX(), j, k + currentFace.getModZ(), j1);
}
}
index++;
@@ -155,18 +151,16 @@ public class BlockFlowing extends BlockFluids {
}
private void flow(World world, int i, int j, int k, int l) {
if (this.l(world, i, j, k)) {
int i1 = world.getTypeId(i, j, k);
if (this.q(world, i, j, k)) {
Block block = world.getType(i, j, k);
if (i1 > 0) {
if (this.material == Material.LAVA) {
this.fizz(world, i, j, k);
} else {
Block.byId[i1].b(world, i, j, k, world.getData(i, j, k), 0);
}
if (this.material == Material.LAVA) {
this.fizz(world, i, j, k);
} else {
block.b(world, i, j, k, world.getData(i, j, k), 0);
}
world.setTypeIdAndData(i, j, k, this.id, l);
world.setTypeAndData(i, j, k, this, l, 3);
}
}
@@ -194,8 +188,8 @@ public class BlockFlowing extends BlockFluids {
++i2;
}
if (!this.k(world, l1, j, i2) && (world.getMaterial(l1, j, i2) != this.material || world.getData(l1, j, i2) != 0)) {
if (!this.k(world, l1, j - 1, i2)) {
if (!this.p(world, l1, j, i2) && (world.getType(l1, j, i2).getMaterial() != this.material || world.getData(l1, j, i2) != 0)) {
if (!this.p(world, l1, j - 1, i2)) {
return l;
}
@@ -213,12 +207,12 @@ public class BlockFlowing extends BlockFluids {
return j1;
}
private boolean[] j(World world, int i, int j, int k) {
private boolean[] o(World world, int i, int j, int k) {
int l;
int i1;
for (l = 0; l < 4; ++l) {
this.c[l] = 1000;
this.M[l] = 1000;
i1 = i;
int j1 = k;
@@ -238,48 +232,38 @@ public class BlockFlowing extends BlockFluids {
++j1;
}
if (!this.k(world, i1, j, j1) && (world.getMaterial(i1, j, j1) != this.material || world.getData(i1, j, j1) != 0)) {
if (!this.k(world, i1, j - 1, j1)) {
this.c[l] = 0;
if (!this.p(world, i1, j, j1) && (world.getType(i1, j, j1).getMaterial() != this.material || world.getData(i1, j, j1) != 0)) {
if (this.p(world, i1, j - 1, j1)) {
this.M[l] = this.c(world, i1, j, j1, 1, l);
} else {
this.c[l] = this.c(world, i1, j, j1, 1, l);
this.M[l] = 0;
}
}
}
l = this.c[0];
l = this.M[0];
for (i1 = 1; i1 < 4; ++i1) {
if (this.c[i1] < l) {
l = this.c[i1];
if (this.M[i1] < l) {
l = this.M[i1];
}
}
for (i1 = 0; i1 < 4; ++i1) {
this.b[i1] = this.c[i1] == l;
this.b[i1] = this.M[i1] == l;
}
return this.b;
}
private boolean k(World world, int i, int j, int k) {
int l = world.getTypeId(i, j, k);
private boolean p(World world, int i, int j, int k) {
Block block = world.getType(i, j, k);
if (l != Block.WOODEN_DOOR.id && l != Block.IRON_DOOR_BLOCK.id && l != Block.SIGN_POST.id && l != Block.LADDER.id && l != Block.SUGAR_CANE_BLOCK.id) {
if (l == 0) {
return false;
} else {
Material material = Block.byId[l].material;
return material == Material.PORTAL ? true : material.isSolid();
}
} else {
return true;
}
return block != Blocks.WOODEN_DOOR && block != Blocks.IRON_DOOR_BLOCK && block != Blocks.SIGN_POST && block != Blocks.LADDER && block != Blocks.SUGAR_CANE_BLOCK ? (block.material == Material.PORTAL ? true : block.material.isSolid()) : true;
}
protected int f(World world, int i, int j, int k, int l) {
int i1 = this.g(world, i, j, k);
protected int a(World world, int i, int j, int k, int l) {
int i1 = this.e(world, i, j, k);
if (i1 < 0) {
return l;
@@ -296,16 +280,20 @@ public class BlockFlowing extends BlockFluids {
}
}
private boolean l(World world, int i, int j, int k) {
Material material = world.getMaterial(i, j, k);
private boolean q(World world, int i, int j, int k) {
Material material = world.getType(i, j, k).getMaterial();
return material == this.material ? false : (material == Material.LAVA ? false : !this.k(world, i, j, k));
return material == this.material ? false : (material == Material.LAVA ? false : !this.p(world, i, j, k));
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
if (world.getTypeId(i, j, k) == this.id) {
world.c(i, j, k, this.id, this.d());
if (world.getType(i, j, k) == this) {
world.a(i, j, k, this, this.a(world));
}
}
public boolean L() {
return true;
}
}

View File

@@ -2,30 +2,34 @@ package net.minecraft.server;
import java.util.Random;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// CraftBukkit start
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.BlockFadeEvent;
// CraftBukkit end
public class BlockGrass extends Block {
public class BlockGrass extends Block implements IBlockFragilePlantElement {
protected BlockGrass(int i) {
super(i, Material.GRASS);
this.textureId = 3;
private static final Logger a = LogManager.getLogger();
protected BlockGrass() {
super(Material.GRASS);
this.a(true);
}
public int a(int i, int j) {
return i == 1 ? 0 : (i == 0 ? 2 : 3);
this.a(CreativeModeTab.b);
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
if (world.getLightLevel(i, j + 1, k) < 4 && Block.lightBlock[world.getTypeId(i, j + 1, k)] > 2) {
// CraftBukkit start - reuse getLightLevel
if (world.getLightLevel(i, j + 1, k) < 4 && world.getType(i, j + 1, k).k() > 2) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i, j, k).getState();
blockState.setTypeId(Block.DIRT.id);
BlockState blockState = bworld.getBlockAt(i, j, k).getState();
blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT));
BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState);
world.getServer().getPluginManager().callEvent(event);
@@ -39,13 +43,13 @@ public class BlockGrass extends Block {
int i1 = i + random.nextInt(3) - 1;
int j1 = j + random.nextInt(5) - 3;
int k1 = k + random.nextInt(3) - 1;
int l1 = world.getTypeId(i1, j1 + 1, k1);
Block block = world.getType(i1, j1 + 1, k1);
if (world.getTypeId(i1, j1, k1) == Block.DIRT.id && world.getLightLevel(i1, j1 + 1, k1) >= 4 && Block.lightBlock[l1] <= 2) {
if (world.getType(i1, j1, k1) == Blocks.DIRT && world.getData(i1, j1, k1) == 0 && world.getLightLevel(i1, j1 + 1, k1) >= 4 && block.k() <= 2) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setTypeId(this.id);
BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setType(CraftMagicNumbers.getMaterial(Blocks.GRASS));
BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(i, j, k), blockState);
world.getServer().getPluginManager().callEvent(event);
@@ -60,7 +64,58 @@ public class BlockGrass extends Block {
}
}
public int getDropType(int i, Random random, int j) {
return Block.DIRT.getDropType(0, random, j);
public Item getDropType(int i, Random random, int j) {
return Blocks.DIRT.getDropType(0, random, j);
}
public boolean a(World world, int i, int j, int k, boolean flag) {
return true;
}
public boolean a(World world, Random random, int i, int j, int k) {
return true;
}
public void b(World world, Random random, int i, int j, int k) {
int l = 0;
while (l < 128) {
int i1 = i;
int j1 = j + 1;
int k1 = k;
int l1 = 0;
while (true) {
if (l1 < l / 16) {
i1 += random.nextInt(3) - 1;
j1 += (random.nextInt(3) - 1) * random.nextInt(3) / 2;
k1 += random.nextInt(3) - 1;
if (world.getType(i1, j1 - 1, k1) == Blocks.GRASS && !world.getType(i1, j1, k1).r()) {
++l1;
continue;
}
} else if (world.getType(i1, j1, k1).material == Material.AIR) {
if (random.nextInt(8) != 0) {
if (Blocks.LONG_GRASS.j(world, i1, j1, k1)) {
CraftEventFactory.handleBlockGrowEvent(world, i1, j1, k1, Blocks.LONG_GRASS, 1); // CraftBukkit
}
} else {
String s = world.getBiome(i1, k1).a(random, i1, j1, k1);
a.debug("Flower in " + world.getBiome(i1, k1).af + ": " + s);
BlockFlowers blockflowers = BlockFlowers.e(s);
if (blockflowers != null && blockflowers.j(world, i1, j1, k1)) {
int i2 = BlockFlowers.f(s);
CraftEventFactory.handleBlockGrowEvent(world, i1, j1, k1, blockflowers, i2); // CraftBukkit
}
}
}
++l;
break;
}
}
}
}

View File

@@ -1,15 +0,0 @@
package net.minecraft.server;
import java.util.Random;
public class BlockGravel extends BlockSand {
public BlockGravel(int i, int j) {
super(i, j);
}
public int getDropType(int i, Random random, int j) {
j = Math.min(j, 3); // CraftBukkit - added to fix crash when j > 3
return random.nextInt(10 - j * 3) == 0 ? Item.FLINT.id : this.id;
}
}

View File

@@ -0,0 +1,166 @@
package net.minecraft.server;
import java.util.List;
import java.util.Random;
public class BlockHopper extends BlockContainer {
private final Random a = new Random();
public BlockHopper() {
super(Material.ORE);
this.a(CreativeModeTab.d);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F);
super.a(world, i, j, k, axisalignedbb, list, entity);
float f = 0.125F;
this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
int j1 = Facing.OPPOSITE_FACING[l];
if (j1 == 1) {
j1 = 0;
}
return j1;
}
public TileEntity a(World world, int i) {
return new TileEntityHopper();
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
super.postPlace(world, i, j, k, entityliving, itemstack);
if (itemstack.hasName()) {
TileEntityHopper tileentityhopper = e((IBlockAccess) world, i, j, k);
tileentityhopper.a(itemstack.getName());
}
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
this.e(world, i, j, k);
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (world.isStatic) {
return true;
} else {
TileEntityHopper tileentityhopper = e((IBlockAccess) world, i, j, k);
if (tileentityhopper != null) {
entityhuman.openHopper(tileentityhopper);
}
return true;
}
}
public void doPhysics(World world, int i, int j, int k, Block block) {
this.e(world, i, j, k);
}
private void e(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
int i1 = b(l);
boolean flag = !world.isBlockIndirectlyPowered(i, j, k);
boolean flag1 = c(l);
if (flag != flag1) {
world.setData(i, j, k, i1 | (flag ? 0 : 8), 4);
}
}
public void remove(World world, int i, int j, int k, Block block, int l) {
TileEntityHopper tileentityhopper = (TileEntityHopper) world.getTileEntity(i, j, k);
if (tileentityhopper != null) {
for (int i1 = 0; i1 < tileentityhopper.getSize(); ++i1) {
ItemStack itemstack = tileentityhopper.getItem(i1);
if (itemstack != null) {
float f = this.a.nextFloat() * 0.8F + 0.1F;
float f1 = this.a.nextFloat() * 0.8F + 0.1F;
float f2 = this.a.nextFloat() * 0.8F + 0.1F;
while (itemstack.count > 0) {
int j1 = this.a.nextInt(21) + 10;
if (j1 > itemstack.count) {
j1 = itemstack.count;
}
itemstack.count -= j1;
EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.getItem(), j1, itemstack.getData()));
if (itemstack.hasTag()) {
entityitem.getItemStack().setTag((NBTTagCompound) itemstack.getTag().clone());
}
float f3 = 0.05F;
entityitem.motX = (double) ((float) this.a.nextGaussian() * f3);
entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F);
entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3);
world.addEntity(entityitem);
}
}
}
world.updateAdjacentComparators(i, j, k, block);
}
super.remove(world, i, j, k, block, l);
}
public int b() {
return 38;
}
public boolean d() {
return false;
}
public boolean c() {
return false;
}
public static int b(int i) {
return Math.min(i & 7, 5); // CraftBukkit - Fix AIOOBE in callers
}
public static boolean c(int i) {
return (i & 8) != 8;
}
public boolean isComplexRedstone() {
return true;
}
public int g(World world, int i, int j, int k, int l) {
return Container.b((IInventory) e((IBlockAccess) world, i, j, k));
}
public static TileEntityHopper e(IBlockAccess iblockaccess, int i, int j, int k) {
return (TileEntityHopper) iblockaccess.getTileEntity(i, j, k);
}
}

View File

@@ -1,22 +1,39 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockIce extends BlockHalfTransparant {
public class BlockIce extends BlockHalfTransparent {
public BlockIce(int i, int j) {
super(i, j, Material.ICE, false);
public BlockIce() {
super("ice", Material.ICE, false);
this.frictionFactor = 0.98F;
this.a(true);
this.a(CreativeModeTab.b);
}
public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
super.a(world, entityhuman, i, j, k, l);
Material material = world.getMaterial(i, j - 1, k);
entityhuman.a(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)], 1);
entityhuman.applyExhaustion(0.025F);
if (this.E() && EnchantmentManager.hasSilkTouchEnchantment(entityhuman)) {
ItemStack itemstack = this.j(l);
if (material.isSolid() || material.isLiquid()) {
world.setTypeId(i, j, k, Block.WATER.id);
if (itemstack != null) {
this.a(world, i, j, k, itemstack);
}
} else {
if (world.worldProvider.f) {
world.setAir(i, j, k);
return;
}
int i1 = EnchantmentManager.getBonusBlockLootEnchantmentLevel(entityhuman);
this.b(world, i, j, k, l, i1);
Material material = world.getType(i, j - 1, k).getMaterial();
if (material.isSolid() || material.isLiquid()) {
world.setTypeUpdate(i, j, k, Blocks.WATER);
}
}
}
@@ -25,23 +42,24 @@ public class BlockIce extends BlockHalfTransparant {
}
public void a(World world, int i, int j, int k, Random random) {
if (world.a(EnumSkyBlock.BLOCK, i, j, k) > 11 - Block.lightBlock[this.id]) {
if (world.b(EnumSkyBlock.BLOCK, i, j, k) > 11 - this.k()) {
// CraftBukkit start
if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(i, j, k), Block.STATIONARY_WATER.id).isCancelled()) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(i, j, k), world.worldProvider.f ? Blocks.AIR : Blocks.STATIONARY_WATER).isCancelled()) {
return;
}
// CraftBukkit end
if (world.worldProvider.f) {
world.setAir(i, j, k);
return;
}
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, Block.STATIONARY_WATER.id);
world.setTypeUpdate(i, j, k, Blocks.STATIONARY_WATER);
}
}
public int g() {
public int h() {
return 0;
}
protected ItemStack a_(int i) {
return null;
}
}

View File

@@ -4,31 +4,32 @@ import java.util.Random;
import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit
public class BlockLeaves extends BlockTransparant {
public abstract class BlockLeaves extends BlockTransparent {
private int c;
int[] a;
protected IIcon[][] M = new IIcon[2][];
protected BlockLeaves(int i, int j) {
super(i, j, Material.LEAVES, false);
this.c = j;
public BlockLeaves() {
super(Material.LEAVES, false);
this.a(true);
this.a(CreativeModeTab.c);
this.c(0.2F);
this.g(1);
this.a(h);
}
public void remove(World world, int i, int j, int k) {
public void remove(World world, int i, int j, int k, Block block, int l) {
byte b0 = 1;
int l = b0 + 1;
int i1 = b0 + 1;
if (world.a(i - l, j - l, k - l, i + l, j + l, k + l)) {
for (int i1 = -b0; i1 <= b0; ++i1) {
for (int j1 = -b0; j1 <= b0; ++j1) {
for (int k1 = -b0; k1 <= b0; ++k1) {
int l1 = world.getTypeId(i + i1, j + j1, k + k1);
if (world.b(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) {
for (int j1 = -b0; j1 <= b0; ++j1) {
for (int k1 = -b0; k1 <= b0; ++k1) {
for (int l1 = -b0; l1 <= b0; ++l1) {
if (world.getType(i + j1, j + k1, k + l1).getMaterial() == Material.LEAVES) {
int i2 = world.getData(i + j1, j + k1, k + l1);
if (l1 == Block.LEAVES.id) {
int i2 = world.getData(i + i1, j + j1, k + k1);
world.setRawData(i + i1, j + j1, k + k1, i2 | 8);
world.setData(i + j1, j + k1, k + l1, i2 | 8, 4);
}
}
}
@@ -53,21 +54,23 @@ public class BlockLeaves extends BlockTransparant {
int l1;
if (world.a(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) {
if (world.b(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) {
int i2;
int j2;
int k2;
for (l1 = -b0; l1 <= b0; ++l1) {
for (i2 = -b0; i2 <= b0; ++i2) {
for (j2 = -b0; j2 <= b0; ++j2) {
k2 = world.getTypeId(i + l1, j + i2, k + j2);
if (k2 == Block.LOG.id) {
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = 0;
} else if (k2 == Block.LEAVES.id) {
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -2;
Block block = world.getType(i + l1, j + i2, k + j2);
if (block != Blocks.LOG && block != Blocks.LOG2) {
if (block.getMaterial() == Material.LEAVES) {
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -2;
} else {
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -1;
}
} else {
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -1;
this.a[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = 0;
}
}
}
@@ -76,7 +79,7 @@ public class BlockLeaves extends BlockTransparant {
for (l1 = 1; l1 <= 4; ++l1) {
for (i2 = -b0; i2 <= b0; ++i2) {
for (j2 = -b0; j2 <= b0; ++j2) {
for (k2 = -b0; k2 <= b0; ++k2) {
for (int k2 = -b0; k2 <= b0; ++k2) {
if (this.a[(i2 + k1) * j1 + (j2 + k1) * b1 + k2 + k1] == l1 - 1) {
if (this.a[(i2 + k1 - 1) * j1 + (j2 + k1) * b1 + k2 + k1] == -2) {
this.a[(i2 + k1 - 1) * j1 + (j2 + k1) * b1 + k2 + k1] = l1;
@@ -110,76 +113,91 @@ public class BlockLeaves extends BlockTransparant {
l1 = this.a[k1 * j1 + k1 * b1 + k1];
if (l1 >= 0) {
world.setRawData(i, j, k, l & -9);
world.setData(i, j, k, l & -9, 4);
} else {
this.g(world, i, j, k);
this.e(world, i, j, k);
}
}
}
}
private void g(World world, int i, int j, int k) {
private void e(World world, int i, int j, int k) {
// CraftBukkit start
LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(i, j, k));
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) return;
if (event.isCancelled()) {
return;
}
// CraftBukkit end
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
}
public int a(Random random) {
return random.nextInt(20) == 0 ? 1 : 0;
}
public int getDropType(int i, Random random, int j) {
return Block.SAPLING.id;
public Item getDropType(int i, Random random, int j) {
return Item.getItemOf(Blocks.SAPLING);
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (!world.isStatic) {
byte b0 = 20;
int j1 = this.b(l);
if ((l & 3) == 3) {
b0 = 40;
if (i1 > 0) {
j1 -= 2 << i1;
if (j1 < 10) {
j1 = 10;
}
}
if (world.random.nextInt(b0) == 0) {
int j1 = this.getDropType(l, world.random, i1);
if (world.random.nextInt(j1) == 0) {
Item item = this.getDropType(l, world.random, i1);
this.a(world, i, j, k, new ItemStack(j1, 1, this.getDropData(l)));
this.a(world, i, j, k, new ItemStack(item, 1, this.getDropData(l)));
}
if ((l & 3) == 0 && world.random.nextInt(200) == 0) {
this.a(world, i, j, k, new ItemStack(Item.APPLE, 1, 0));
j1 = 200;
if (i1 > 0) {
j1 -= 10 << i1;
if (j1 < 40) {
j1 = 40;
}
}
this.c(world, i, j, k, l, j1);
}
}
protected void c(World world, int i, int j, int k, int l, int i1) {}
protected int b(int i) {
return 20;
}
public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
if (!world.isStatic && entityhuman.U() != null && entityhuman.U().id == Item.SHEARS.id) {
entityhuman.a(StatisticList.C[this.id], 1);
this.a(world, i, j, k, new ItemStack(Block.LEAVES.id, 1, l & 3));
if (!world.isStatic && entityhuman.bF() != null && entityhuman.bF().getItem() == Items.SHEARS) {
entityhuman.a(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)], 1);
this.a(world, i, j, k, new ItemStack(Item.getItemOf(this), 1, l & 3));
} else {
super.a(world, entityhuman, i, j, k, l);
}
}
protected int getDropData(int i) {
public int getDropData(int i) {
return i & 3;
}
public boolean a() {
return !this.b;
public boolean c() {
return !this.P;
}
public int a(int i, int j) {
return (j & 3) == 1 ? this.textureId + 80 : ((j & 3) == 3 ? this.textureId + 144 : this.textureId);
protected ItemStack j(int i) {
return new ItemStack(Item.getItemOf(this), 1, i & 3);
}
public void b(World world, int i, int j, int k, Entity entity) {
super.b(world, i, j, k, entity);
}
public abstract String[] e();
}

View File

@@ -4,108 +4,160 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockLever extends Block {
protected BlockLever(int i, int j) {
super(i, j, Material.ORIENTABLE);
protected BlockLever() {
super(Material.ORIENTABLE);
this.a(CreativeModeTab.d);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 12;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
return l == 1 && world.e(i, j - 1, k) ? true : (l == 2 && world.e(i, j, k + 1) ? true : (l == 3 && world.e(i, j, k - 1) ? true : (l == 4 && world.e(i + 1, j, k) ? true : l == 5 && world.e(i - 1, j, k))));
return l == 0 && world.getType(i, j + 1, k).r() ? true : (l == 1 && World.a((IBlockAccess) world, i, j - 1, k) ? true : (l == 2 && world.getType(i, j, k + 1).r() ? true : (l == 3 && world.getType(i, j, k - 1).r() ? true : (l == 4 && world.getType(i + 1, j, k).r() ? true : l == 5 && world.getType(i - 1, j, k).r()))));
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i - 1, j, k) ? true : (world.e(i + 1, j, k) ? true : (world.e(i, j, k - 1) ? true : (world.e(i, j, k + 1) ? true : world.e(i, j - 1, k))));
return world.getType(i - 1, j, k).r() ? true : (world.getType(i + 1, j, k).r() ? true : (world.getType(i, j, k - 1).r() ? true : (world.getType(i, j, k + 1).r() ? true : (World.a((IBlockAccess) world, i, j - 1, k) ? true : world.getType(i, j + 1, k).r()))));
}
public void postPlace(World world, int i, int j, int k, int l) {
int i1 = world.getData(i, j, k);
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
int j1 = i1 & 8;
int k1 = i1 & 7;
byte b0 = -1;
i1 &= 7;
i1 = -1;
if (l == 1 && world.e(i, j - 1, k)) {
i1 = 5 + world.random.nextInt(2);
if (l == 0 && world.getType(i, j + 1, k).r()) {
b0 = 0;
}
if (l == 2 && world.e(i, j, k + 1)) {
i1 = 4;
if (l == 1 && World.a((IBlockAccess) world, i, j - 1, k)) {
b0 = 5;
}
if (l == 3 && world.e(i, j, k - 1)) {
i1 = 3;
if (l == 2 && world.getType(i, j, k + 1).r()) {
b0 = 4;
}
if (l == 4 && world.e(i + 1, j, k)) {
i1 = 2;
if (l == 3 && world.getType(i, j, k - 1).r()) {
b0 = 3;
}
if (l == 5 && world.e(i - 1, j, k)) {
i1 = 1;
if (l == 4 && world.getType(i + 1, j, k).r()) {
b0 = 2;
}
if (i1 == -1) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
} else {
world.setData(i, j, k, i1 + j1);
if (l == 5 && world.getType(i - 1, j, k).r()) {
b0 = 1;
}
return b0 + j1;
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = world.getData(i, j, k);
int i1 = l & 7;
int j1 = l & 8;
if (i1 == b(1)) {
if ((MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) {
world.setData(i, j, k, 5 | j1, 2);
} else {
world.setData(i, j, k, 6 | j1, 2);
}
} else if (i1 == b(0)) {
if ((MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) {
world.setData(i, j, k, 7 | j1, 2);
} else {
world.setData(i, j, k, 0 | j1, 2);
}
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (this.g(world, i, j, k)) {
int i1 = world.getData(i, j, k) & 7;
public static int b(int i) {
switch (i) {
case 0:
return 0;
case 1:
return 5;
case 2:
return 4;
case 3:
return 3;
case 4:
return 2;
case 5:
return 1;
default:
return -1;
}
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (this.e(world, i, j, k)) {
int l = world.getData(i, j, k) & 7;
boolean flag = false;
if (!world.e(i - 1, j, k) && i1 == 1) {
if (!world.getType(i - 1, j, k).r() && l == 1) {
flag = true;
}
if (!world.e(i + 1, j, k) && i1 == 2) {
if (!world.getType(i + 1, j, k).r() && l == 2) {
flag = true;
}
if (!world.e(i, j, k - 1) && i1 == 3) {
if (!world.getType(i, j, k - 1).r() && l == 3) {
flag = true;
}
if (!world.e(i, j, k + 1) && i1 == 4) {
if (!world.getType(i, j, k + 1).r() && l == 4) {
flag = true;
}
if (!world.e(i, j - 1, k) && i1 == 5) {
if (!World.a((IBlockAccess) world, i, j - 1, k) && l == 5) {
flag = true;
}
if (!world.e(i, j - 1, k) && i1 == 6) {
if (!World.a((IBlockAccess) world, i, j - 1, k) && l == 6) {
flag = true;
}
if (!world.getType(i, j + 1, k).r() && l == 0) {
flag = true;
}
if (!world.getType(i, j + 1, k).r() && l == 7) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
}
}
}
private boolean g(World world, int i, int j, int k) {
private boolean e(World world, int i, int j, int k) {
if (!this.canPlace(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
return false;
} else {
return true;
@@ -124,93 +176,99 @@ public class BlockLever extends Block {
this.a(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F);
} else if (l == 4) {
this.a(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F);
} else if (l != 5 && l != 6) {
if (l == 0 || l == 7) {
f = 0.25F;
this.a(0.5F - f, 0.4F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f);
}
} else {
f = 0.25F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.6F, 0.5F + f);
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.interact(world, i, j, k, entityhuman);
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (world.isStatic) {
return true;
} else {
int l = world.getData(i, j, k);
int i1 = l & 7;
int j1 = 8 - (l & 8);
int i1 = world.getData(i, j, k);
int j1 = i1 & 7;
int k1 = 8 - (i1 & 8);
// CraftBukkit start - Interact Lever
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int old = (j1 != 8) ? 1 : 0;
int current = (j1 == 8) ? 1 : 0;
int old = (k1 != 8) ? 15 : 0;
int current = (k1 == 8) ? 15 : 0;
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current);
world.getServer().getPluginManager().callEvent(eventRedstone);
if ((eventRedstone.getNewCurrent() > 0) != (j1 == 8)) {
if ((eventRedstone.getNewCurrent() > 0) != (k1 == 8)) {
return true;
}
// CraftBukkit end
world.setData(i, j, k, i1 + j1);
world.b(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, j1 > 0 ? 0.6F : 0.5F);
world.applyPhysics(i, j, k, this.id);
if (i1 == 1) {
world.applyPhysics(i - 1, j, k, this.id);
} else if (i1 == 2) {
world.applyPhysics(i + 1, j, k, this.id);
} else if (i1 == 3) {
world.applyPhysics(i, j, k - 1, this.id);
} else if (i1 == 4) {
world.applyPhysics(i, j, k + 1, this.id);
world.setData(i, j, k, j1 + k1, 3);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "random.click", 0.3F, k1 > 0 ? 0.6F : 0.5F);
world.applyPhysics(i, j, k, this);
if (j1 == 1) {
world.applyPhysics(i - 1, j, k, this);
} else if (j1 == 2) {
world.applyPhysics(i + 1, j, k, this);
} else if (j1 == 3) {
world.applyPhysics(i, j, k - 1, this);
} else if (j1 == 4) {
world.applyPhysics(i, j, k + 1, this);
} else if (j1 != 5 && j1 != 6) {
if (j1 == 0 || j1 == 7) {
world.applyPhysics(i, j + 1, k, this);
}
} else {
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i, j - 1, k, this);
}
return true;
}
}
public void remove(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
public void remove(World world, int i, int j, int k, Block block, int l) {
if ((l & 8) > 0) {
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j, k, this);
int i1 = l & 7;
if (i1 == 1) {
world.applyPhysics(i - 1, j, k, this.id);
world.applyPhysics(i - 1, j, k, this);
} else if (i1 == 2) {
world.applyPhysics(i + 1, j, k, this.id);
world.applyPhysics(i + 1, j, k, this);
} else if (i1 == 3) {
world.applyPhysics(i, j, k - 1, this.id);
world.applyPhysics(i, j, k - 1, this);
} else if (i1 == 4) {
world.applyPhysics(i, j, k + 1, this.id);
world.applyPhysics(i, j, k + 1, this);
} else if (i1 != 5 && i1 != 6) {
if (i1 == 0 || i1 == 7) {
world.applyPhysics(i, j + 1, k, this);
}
} else {
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i, j - 1, k, this);
}
}
super.remove(world, i, j, k);
super.remove(world, i, j, k, block, l);
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) > 0;
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) > 0 ? 15 : 0;
}
public boolean d(World world, int i, int j, int k, int l) {
int i1 = world.getData(i, j, k);
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = iblockaccess.getData(i, j, k);
if ((i1 & 8) == 0) {
return false;
return 0;
} else {
int j1 = i1 & 7;
return j1 == 6 && l == 1 ? true : (j1 == 5 && l == 1 ? true : (j1 == 4 && l == 2 ? true : (j1 == 3 && l == 3 ? true : (j1 == 2 && l == 4 ? true : j1 == 1 && l == 5))));
return j1 == 0 && l == 0 ? 15 : (j1 == 7 && l == 0 ? 15 : (j1 == 6 && l == 1 ? 15 : (j1 == 5 && l == 1 ? 15 : (j1 == 4 && l == 2 ? 15 : (j1 == 3 && l == 3 ? 15 : (j1 == 2 && l == 4 ? 15 : (j1 == 1 && l == 5 ? 15 : 0)))))));
}
}

View File

@@ -5,14 +5,14 @@ import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockMinecartDetector extends BlockMinecartTrack {
public class BlockMinecartDetector extends BlockMinecartTrackAbstract {
public BlockMinecartDetector(int i, int j) {
super(i, j, true);
public BlockMinecartDetector() {
super(true);
this.a(true);
}
public int d() {
public int a(World world) {
return 20;
}
@@ -25,7 +25,7 @@ public class BlockMinecartDetector extends BlockMinecartTrack {
int l = world.getData(i, j, k);
if ((l & 8) == 0) {
this.f(world, i, j, k, l);
this.a(world, i, j, k, l);
}
}
}
@@ -35,26 +35,26 @@ public class BlockMinecartDetector extends BlockMinecartTrack {
int l = world.getData(i, j, k);
if ((l & 8) != 0) {
this.f(world, i, j, k, l);
this.a(world, i, j, k, l);
}
}
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) != 0;
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) != 0 ? 15 : 0;
}
public boolean d(World world, int i, int j, int k, int l) {
return (world.getData(i, j, k) & 8) == 0 ? false : l == 1;
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) == 0 ? 0 : (l == 1 ? 15 : 0);
}
private void f(World world, int i, int j, int k, int l) {
private void a(World world, int i, int j, int k, int l) {
boolean flag = (l & 8) != 0;
boolean flag1 = false;
float f = 0.125F;
List list = world.a(EntityMinecart.class, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f)));
List list = world.a(EntityMinecartAbstract.class, AxisAlignedBB.a((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f)));
if (list.size() > 0) {
if (!list.isEmpty()) {
flag1 = true;
}
@@ -62,7 +62,7 @@ public class BlockMinecartDetector extends BlockMinecartTrack {
if (flag != flag1) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 1 : 0, flag1 ? 1 : 0);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0);
world.getServer().getPluginManager().callEvent(eventRedstone);
flag1 = eventRedstone.getNewCurrent() > 0;
@@ -70,21 +70,51 @@ public class BlockMinecartDetector extends BlockMinecartTrack {
// CraftBukkit end
if (flag1 && !flag) {
world.setData(i, j, k, l | 8);
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.b(i, j, k, i, j, k);
world.setData(i, j, k, l | 8, 3);
world.applyPhysics(i, j, k, this);
world.applyPhysics(i, j - 1, k, this);
world.c(i, j, k, i, j, k);
}
if (!flag1 && flag) {
world.setData(i, j, k, l & 7);
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.b(i, j, k, i, j, k);
world.setData(i, j, k, l & 7, 3);
world.applyPhysics(i, j, k, this);
world.applyPhysics(i, j - 1, k, this);
world.c(i, j, k, i, j, k);
}
if (flag1) {
world.c(i, j, k, this.id, this.d());
world.a(i, j, k, this, this.a(world));
}
world.updateAdjacentComparators(i, j, k, this);
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
this.a(world, i, j, k, world.getData(i, j, k));
}
public boolean isComplexRedstone() {
return true;
}
public int g(World world, int i, int j, int k, int l) {
if ((world.getData(i, j, k) & 8) > 0) {
float f = 0.125F;
List list = world.a(EntityMinecartCommandBlock.class, AxisAlignedBB.a((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f)));
if (list.size() > 0) {
return ((EntityMinecartCommandBlock) list.get(0)).getCommandBlock().g();
}
List list1 = world.a(EntityMinecartAbstract.class, AxisAlignedBB.a((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) ((float) (j + 1) - f), (double) ((float) (k + 1) - f)), IEntitySelector.c);
if (list1.size() > 0) {
return Container.b((IInventory) list1.get(0));
}
}
return 0;
}
}

View File

@@ -1,265 +0,0 @@
package net.minecraft.server;
import java.util.Random;
public class BlockMinecartTrack extends Block {
private final boolean a;
public static final boolean g(World world, int i, int j, int k) {
int l = world.getTypeId(i, j, k);
return l == Block.RAILS.id || l == Block.GOLDEN_RAIL.id || l == Block.DETECTOR_RAIL.id;
}
public static final boolean d(int i) {
return i == Block.RAILS.id || i == Block.GOLDEN_RAIL.id || i == Block.DETECTOR_RAIL.id;
}
protected BlockMinecartTrack(int i, int j, boolean flag) {
super(i, j, Material.ORIENTABLE);
this.a = flag;
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
}
public boolean i() {
return this.a;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
return null;
}
public boolean a() {
return false;
}
public MovingObjectPosition a(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) {
this.updateShape(world, i, j, k);
return super.a(world, i, j, k, vec3d, vec3d1);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
if (l >= 2 && l <= 5) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F);
} else {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
}
}
public int a(int i, int j) {
if (this.a) {
if (this.id == Block.GOLDEN_RAIL.id && (j & 8) == 0) {
return this.textureId - 16;
}
} else if (j >= 6) {
return this.textureId - 16;
}
return this.textureId;
}
public boolean b() {
return false;
}
public int c() {
return 9;
}
public int a(Random random) {
return 1;
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i, j - 1, k);
}
public void onPlace(World world, int i, int j, int k) {
if (!world.isStatic) {
this.a(world, i, j, k, true);
if (this.id == Block.GOLDEN_RAIL.id) {
// this.doPhysics(world, i, j, k, this.id); CraftBukkit - Fix issues with rails
}
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (!world.isStatic) {
int i1 = world.getData(i, j, k);
int j1 = i1;
if (this.a) {
j1 = i1 & 7;
}
boolean flag = false;
if (!world.e(i, j - 1, k)) {
flag = true;
}
if (j1 == 2 && !world.e(i + 1, j, k)) {
flag = true;
}
if (j1 == 3 && !world.e(i - 1, j, k)) {
flag = true;
}
if (j1 == 4 && !world.e(i, j, k - 1)) {
flag = true;
}
if (j1 == 5 && !world.e(i, j, k + 1)) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
} else if (this.id == Block.GOLDEN_RAIL.id) {
boolean flag1 = world.isBlockIndirectlyPowered(i, j, k);
flag1 = flag1 || this.a(world, i, j, k, i1, true, 0) || this.a(world, i, j, k, i1, false, 0);
boolean flag2 = false;
if (flag1 && (i1 & 8) == 0) {
world.setData(i, j, k, j1 | 8);
flag2 = true;
} else if (!flag1 && (i1 & 8) != 0) {
world.setData(i, j, k, j1);
flag2 = true;
}
if (flag2) {
world.applyPhysics(i, j - 1, k, this.id);
if (j1 == 2 || j1 == 3 || j1 == 4 || j1 == 5) {
world.applyPhysics(i, j + 1, k, this.id);
}
}
} else if (l > 0 && Block.byId[l].isPowerSource() && !this.a && MinecartTrackLogic.a(new MinecartTrackLogic(this, world, i, j, k)) == 3) {
this.a(world, i, j, k, false);
}
}
}
private void a(World world, int i, int j, int k, boolean flag) {
if (!world.isStatic) {
(new MinecartTrackLogic(this, world, i, j, k)).a(world.isBlockIndirectlyPowered(i, j, k), flag);
}
}
private boolean a(World world, int i, int j, int k, int l, boolean flag, int i1) {
if (i1 >= 8) {
return false;
} else {
int j1 = l & 7;
boolean flag1 = true;
switch (j1) {
case 0:
if (flag) {
++k;
} else {
--k;
}
break;
case 1:
if (flag) {
--i;
} else {
++i;
}
break;
case 2:
if (flag) {
--i;
} else {
++i;
++j;
flag1 = false;
}
j1 = 1;
break;
case 3:
if (flag) {
--i;
++j;
flag1 = false;
} else {
++i;
}
j1 = 1;
break;
case 4:
if (flag) {
++k;
} else {
--k;
++j;
flag1 = false;
}
j1 = 0;
break;
case 5:
if (flag) {
++k;
++j;
flag1 = false;
} else {
--k;
}
j1 = 0;
}
return this.a(world, i, j, k, flag, i1, j1) ? true : flag1 && this.a(world, i, j - 1, k, flag, i1, j1);
}
}
private boolean a(World world, int i, int j, int k, boolean flag, int l, int i1) {
int j1 = world.getTypeId(i, j, k);
if (j1 == Block.GOLDEN_RAIL.id) {
int k1 = world.getData(i, j, k);
int l1 = k1 & 7;
if (i1 == 1 && (l1 == 0 || l1 == 4 || l1 == 5)) {
return false;
}
if (i1 == 0 && (l1 == 1 || l1 == 2 || l1 == 3)) {
return false;
}
if ((k1 & 8) != 0) {
if (world.isBlockIndirectlyPowered(i, j, k)) {
return true;
}
return this.a(world, i, j, k, k1, flag, l + 1);
}
}
return false;
}
public int g() {
return 0;
}
static boolean a(BlockMinecartTrack blockminecarttrack) {
return blockminecarttrack.a;
}
}

View File

@@ -0,0 +1,41 @@
package net.minecraft.server;
import java.util.Random;
public class BlockMobSpawner extends BlockContainer {
protected BlockMobSpawner() {
super(Material.STONE);
}
public TileEntity a(World world, int i) {
return new TileEntityMobSpawner();
}
public Item getDropType(int i, Random random, int j) {
return null;
}
public int a(Random random) {
return 0;
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
super.dropNaturally(world, i, j, k, l, f, i1);
/* CraftBukkit start - Delegate to getExpDrop
int j1 = 15 + world.random.nextInt(15) + world.random.nextInt(15);
this.dropExperience(world, i, j, k, j1)*/
}
public int getExpDrop(World world, int data, int enchantmentLevel) {
int j1 = 15 + world.random.nextInt(15) + world.random.nextInt(15);
return j1;
// CraftBukkit end
}
public boolean c() {
return false;
}
}

View File

@@ -0,0 +1,121 @@
package net.minecraft.server;
import java.util.Random;
import net.minecraft.util.org.apache.commons.lang3.tuple.ImmutablePair;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit
public class BlockMonsterEggs extends Block {
public static final String[] a = new String[] { "stone", "cobble", "brick", "mossybrick", "crackedbrick", "chiseledbrick"};
public BlockMonsterEggs() {
super(Material.CLAY);
this.c(0.0F);
this.a(CreativeModeTab.c);
}
public void postBreak(World world, int i, int j, int k, int l) {
if (!world.isStatic) {
EntitySilverfish entitysilverfish = new EntitySilverfish(world);
entitysilverfish.setPositionRotation((double) i + 0.5D, (double) j, (double) k + 0.5D, 0.0F, 0.0F);
world.addEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason
entitysilverfish.s();
}
super.postBreak(world, i, j, k, l);
}
public int a(Random random) {
return 0;
}
public static boolean a(Block block) {
return block == Blocks.STONE || block == Blocks.COBBLESTONE || block == Blocks.SMOOTH_BRICK;
}
public static int a(Block block, int i) {
if (i == 0) {
if (block == Blocks.COBBLESTONE) {
return 1;
}
if (block == Blocks.SMOOTH_BRICK) {
return 2;
}
} else if (block == Blocks.SMOOTH_BRICK) {
switch (i) {
case 1:
return 3;
case 2:
return 4;
case 3:
return 5;
}
}
return 0;
}
public static ImmutablePair b(int i) {
switch (i) {
case 1:
return new ImmutablePair(Blocks.COBBLESTONE, Integer.valueOf(0));
case 2:
return new ImmutablePair(Blocks.SMOOTH_BRICK, Integer.valueOf(0));
case 3:
return new ImmutablePair(Blocks.SMOOTH_BRICK, Integer.valueOf(1));
case 4:
return new ImmutablePair(Blocks.SMOOTH_BRICK, Integer.valueOf(2));
case 5:
return new ImmutablePair(Blocks.SMOOTH_BRICK, Integer.valueOf(3));
default:
return new ImmutablePair(Blocks.STONE, Integer.valueOf(0));
}
}
protected ItemStack j(int i) {
switch (i) {
case 1:
return new ItemStack(Blocks.COBBLESTONE);
case 2:
return new ItemStack(Blocks.SMOOTH_BRICK);
case 3:
return new ItemStack(Blocks.SMOOTH_BRICK, 1, 1);
case 4:
return new ItemStack(Blocks.SMOOTH_BRICK, 1, 2);
case 5:
return new ItemStack(Blocks.SMOOTH_BRICK, 1, 3);
default:
return new ItemStack(Blocks.STONE);
}
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (!world.isStatic) {
EntitySilverfish entitysilverfish = new EntitySilverfish(world);
entitysilverfish.setPositionRotation((double) i + 0.5D, (double) j, (double) k + 0.5D, 0.0F, 0.0F);
world.addEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason
entitysilverfish.s();
}
}
public int getDropData(World world, int i, int j, int k) {
return world.getData(i, j, k);
}
}

View File

@@ -1,21 +1,16 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.Random;
// CraftBukkit start
import org.bukkit.BlockChangeDelegate;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.world.StructureGrowEvent;
// CraftBukkit end
public class BlockMushroom extends BlockFlower {
public class BlockMushroom extends BlockPlant implements IBlockFragilePlantElement {
protected BlockMushroom(int i, int j) {
super(i, j);
protected BlockMushroom() {
float f = 0.2F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
@@ -23,6 +18,7 @@ public class BlockMushroom extends BlockFlower {
}
public void a(World world, int i, int j, int k, Random random) {
final int sourceX = i, sourceY = j, sourceZ = k; // CraftBukkit
if (random.nextInt(25) == 0) {
byte b0 = 4;
int l = 5;
@@ -34,7 +30,7 @@ public class BlockMushroom extends BlockFlower {
for (i1 = i - b0; i1 <= i + b0; ++i1) {
for (j1 = k - b0; j1 <= k + b0; ++j1) {
for (k1 = j - 1; k1 <= j + 1; ++k1) {
if (world.getTypeId(i1, k1, j1) == this.id) {
if (world.getType(i1, k1, j1) == this) {
--l;
if (l <= 0) {
return;
@@ -49,7 +45,7 @@ public class BlockMushroom extends BlockFlower {
k1 = k + random.nextInt(3) - 1;
for (int l1 = 0; l1 < 4; ++l1) {
if (world.isEmpty(i1, j1, k1) && this.f(world, i1, j1, k1)) {
if (world.isEmpty(i1, j1, k1) && this.j(world, i1, j1, k1)) {
i = i1;
j = j1;
k = k1;
@@ -60,13 +56,13 @@ public class BlockMushroom extends BlockFlower {
k1 = k + random.nextInt(3) - 1;
}
if (world.isEmpty(i1, j1, k1) && this.f(world, i1, j1, k1)) {
if (world.isEmpty(i1, j1, k1) && this.j(world, i1, j1, k1)) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setTypeId(this.id);
BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setType(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this)); // nms: this.id, 0, 2
BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(i, j, k), blockState);
BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
@@ -78,52 +74,53 @@ public class BlockMushroom extends BlockFlower {
}
public boolean canPlace(World world, int i, int j, int k) {
return super.canPlace(world, i, j, k) && this.f(world, i, j, k);
return super.canPlace(world, i, j, k) && this.j(world, i, j, k);
}
protected boolean d(int i) {
return Block.n[i];
protected boolean a(Block block) {
return block.j();
}
public boolean f(World world, int i, int j, int k) {
public boolean j(World world, int i, int j, int k) {
if (j >= 0 && j < 256) {
int l = world.getTypeId(i, j - 1, k);
Block block = world.getType(i, j - 1, k);
return l == Block.MYCEL.id || world.m(i, j, k) < 13 && this.d(l);
return block == Blocks.MYCEL || block == Blocks.DIRT && world.getData(i, j - 1, k) == 2 || world.j(i, j, k) < 13 && this.a(block);
} else {
return false;
}
}
// CraftBukkit - added bonemeal, player and itemstack
public boolean grow(World world, int i, int j, int k, Random random, boolean bonemeal, Player player, ItemStack itemstack) {
public boolean grow(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
world.setRawTypeId(i, j, k, 0);
// CraftBukkit start
boolean grown = false;
StructureGrowEvent event = null;
Location location = new Location(world.getWorld(), i, j, k);
world.setAir(i, j, k);
WorldGenHugeMushroom worldgenhugemushroom = null;
if (this.id == Block.BROWN_MUSHROOM.id) {
event = new StructureGrowEvent(location, TreeType.BROWN_MUSHROOM, bonemeal, player, new ArrayList<BlockState>());
if (this == Blocks.BROWN_MUSHROOM) {
BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit
worldgenhugemushroom = new WorldGenHugeMushroom(0);
} else if (this.id == Block.RED_MUSHROOM.id) {
event = new StructureGrowEvent(location, TreeType.RED_MUSHROOM, bonemeal, player, new ArrayList<BlockState>());
} else if (this == Blocks.RED_MUSHROOM) {
BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit
worldgenhugemushroom = new WorldGenHugeMushroom(1);
}
if (worldgenhugemushroom != null && event != null) {
grown = worldgenhugemushroom.grow((BlockChangeDelegate)world, random, i, j, k, event, itemstack, world.getWorld());
if (event.isFromBonemeal() && itemstack != null) {
--itemstack.count;
}
}
if (!grown || event.isCancelled()) {
world.setRawTypeIdAndData(i, j, k, this.id, l);
if (worldgenhugemushroom != null && worldgenhugemushroom.generate(world, random, i, j, k)) {
return true;
} else {
world.setTypeAndData(i, j, k, this, l, 3);
return false;
}
}
public boolean a(World world, int i, int j, int k, boolean flag) {
return true;
// CraftBukkit end
}
public boolean a(World world, Random random, int i, int j, int k) {
return (double) random.nextFloat() < 0.4D;
}
public void b(World world, Random random, int i, int j, int k) {
this.grow(world, i, j, k, random);
}
}

View File

@@ -1,28 +1,29 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockFadeEvent; // CraftBukkit
import org.bukkit.event.block.BlockSpreadEvent; // CraftBukkit
// CraftBukkit start
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockSpreadEvent;
// CraftBukkit end
public class BlockMycel extends Block {
protected BlockMycel(int i) {
super(i, Material.GRASS);
this.textureId = 77;
protected BlockMycel() {
super(Material.GRASS);
this.a(true);
}
public int a(int i, int j) {
return i == 1 ? 78 : (i == 0 ? 2 : 77);
this.a(CreativeModeTab.b);
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
if (world.getLightLevel(i, j + 1, k) < 4 && Block.lightBlock[world.getTypeId(i, j + 1, k)] > 2) {
if (world.getLightLevel(i, j + 1, k) < 4 && world.getType(i, j + 1, k).k() > 2) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i, j, k).getState();
blockState.setTypeId(Block.DIRT.id);
BlockState blockState = bworld.getBlockAt(i, j, k).getState();
blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT));
BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState);
world.getServer().getPluginManager().callEvent(event);
@@ -36,13 +37,13 @@ public class BlockMycel extends Block {
int i1 = i + random.nextInt(3) - 1;
int j1 = j + random.nextInt(5) - 3;
int k1 = k + random.nextInt(3) - 1;
int l1 = world.getTypeId(i1, j1 + 1, k1);
Block block = world.getType(i1, j1 + 1, k1);
if (world.getTypeId(i1, j1, k1) == Block.DIRT.id && world.getLightLevel(i1, j1 + 1, k1) >= 4 && Block.lightBlock[l1] <= 2) {
if (world.getType(i1, j1, k1) == Blocks.DIRT && world.getData(i1, j1, k1) == 0 && world.getLightLevel(i1, j1 + 1, k1) >= 4 && block.k() <= 2) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setTypeId(this.id);
BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState();
blockState.setType(CraftMagicNumbers.getMaterial(this));
BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(i, j, k), blockState);
world.getServer().getPluginManager().callEvent(event);
@@ -57,7 +58,7 @@ public class BlockMycel extends Block {
}
}
public int getDropType(int i, Random random, int j) {
return Block.DIRT.getDropType(0, random, j);
public Item getDropType(int i, Random random, int j) {
return Blocks.DIRT.getDropType(0, random, j);
}
}

View File

@@ -2,43 +2,36 @@ package net.minecraft.server;
import java.util.Random;
public class BlockNetherWart extends BlockFlower {
public class BlockNetherWart extends BlockPlant {
protected BlockNetherWart(int i) {
super(i, 226);
protected BlockNetherWart() {
this.a(true);
float f = 0.5F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
this.a((CreativeModeTab) null);
}
protected boolean d(int i) {
return i == Block.SOUL_SAND.id;
protected boolean a(Block block) {
return block == Blocks.SOUL_SAND;
}
public boolean f(World world, int i, int j, int k) {
return this.d(world.getTypeId(i, j - 1, k));
public boolean j(World world, int i, int j, int k) {
return this.a(world.getType(i, j - 1, k));
}
public void a(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
if (l < 3) {
BiomeBase biomebase = world.getBiome(i, k);
if (biomebase instanceof BiomeHell && random.nextInt(10) == 0) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this.id, ++l); // CraftBukkit
}
if (l < 3 && random.nextInt(10) == 0) {
++l;
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
}
super.a(world, i, j, k, random);
}
public int a(int i, int j) {
return j >= 3 ? this.textureId + 2 : (j > 0 ? this.textureId + 1 : this.textureId);
}
public int c() {
public int b() {
return 6;
}
@@ -54,13 +47,13 @@ public class BlockNetherWart extends BlockFlower {
}
for (int k1 = 0; k1 < j1; ++k1) {
this.a(world, i, j, k, new ItemStack(Item.NETHER_STALK));
this.a(world, i, j, k, new ItemStack(Items.NETHER_STALK));
}
}
}
public int getDropType(int i, Random random, int j) {
return 0;
public Item getDropType(int i, Random random, int j) {
return null;
}
public int a(Random random) {

View File

@@ -0,0 +1,83 @@
package net.minecraft.server;
import java.util.Random;
public class BlockOre extends Block {
public BlockOre() {
super(Material.STONE);
this.a(CreativeModeTab.b);
}
public Item getDropType(int i, Random random, int j) {
return this == Blocks.COAL_ORE ? Items.COAL : (this == Blocks.DIAMOND_ORE ? Items.DIAMOND : (this == Blocks.LAPIS_ORE ? Items.INK_SACK : (this == Blocks.EMERALD_ORE ? Items.EMERALD : (this == Blocks.QUARTZ_ORE ? Items.QUARTZ : Item.getItemOf(this)))));
}
public int a(Random random) {
return this == Blocks.LAPIS_ORE ? 4 + random.nextInt(5) : 1;
}
public int getDropCount(int i, Random random) {
if (i > 0 && Item.getItemOf(this) != this.getDropType(0, random, i)) {
int j = random.nextInt(i + 2) - 1;
if (j < 0) {
j = 0;
}
return this.a(random) * (j + 1);
} else {
return this.a(random);
}
}
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
super.dropNaturally(world, i, j, k, l, f, i1);
/* CraftBukkit start - Delegated to getExpDrop
if (this.getDropType(l, world.random, i1) != Item.getItemOf(this)) {
int j1 = 0;
if (this == Blocks.COAL_ORE) {
j1 = MathHelper.nextInt(world.random, 0, 2);
} else if (this == Blocks.DIAMOND_ORE) {
j1 = MathHelper.nextInt(world.random, 3, 7);
} else if (this == Blocks.EMERALD_ORE) {
j1 = MathHelper.nextInt(world.random, 3, 7);
} else if (this == Blocks.LAPIS_ORE) {
j1 = MathHelper.nextInt(world.random, 2, 5);
} else if (this == Blocks.QUARTZ_ORE) {
j1 = MathHelper.nextInt(world.random, 2, 5);
}
this.dropExperience(world, i, j, k, j1);
}
// */
}
public int getExpDrop(World world, int l, int i1) {
if (this.getDropType(l, world.random, i1) != Item.getItemOf(this)) {
int j1 = 0;
if (this == Blocks.COAL_ORE) {
j1 = MathHelper.nextInt(world.random, 0, 2);
} else if (this == Blocks.DIAMOND_ORE) {
j1 = MathHelper.nextInt(world.random, 3, 7);
} else if (this == Blocks.EMERALD_ORE) {
j1 = MathHelper.nextInt(world.random, 3, 7);
} else if (this == Blocks.LAPIS_ORE) {
j1 = MathHelper.nextInt(world.random, 2, 5);
} else if (this == Blocks.QUARTZ_ORE) {
j1 = MathHelper.nextInt(world.random, 2, 5);
}
return j1;
}
return 0;
// CraftBukkit end
}
public int getDropData(int i) {
return this == Blocks.LAPIS_ORE ? 4 : 0;
}
}

View File

@@ -1,6 +1,6 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.List;
// CraftBukkit start
import org.bukkit.craftbukkit.block.CraftBlock;
@@ -10,67 +10,61 @@ import org.bukkit.event.block.BlockPistonExtendEvent;
public class BlockPiston extends Block {
private boolean a;
private static boolean b;
private final boolean a;
public BlockPiston(int i, int j, boolean flag) {
super(i, j, Material.PISTON);
public BlockPiston(boolean flag) {
super(Material.PISTON);
this.a = flag;
this.a(h);
this.a(i);
this.c(0.5F);
this.a(CreativeModeTab.d);
}
public int a(int i, int j) {
int k = d(j);
return k > 5 ? this.textureId : (i == k ? (!e(j) && this.minX <= 0.0D && this.minY <= 0.0D && this.minZ <= 0.0D && this.maxX >= 1.0D && this.maxY >= 1.0D && this.maxZ >= 1.0D ? this.textureId : 110) : (i == Facing.OPPOSITE_FACING[k] ? 109 : 108));
}
public int c() {
public int b() {
return 16;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
return false;
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving) {
int l = c(world, i, j, k, (EntityHuman) entityliving);
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = a(world, i, j, k, entityliving);
world.setData(i, j, k, l);
if (!world.isStatic && !b) {
this.g(world, i, j, k);
world.setData(i, j, k, l, 2);
if (!world.isStatic) {
this.e(world, i, j, k);
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (!world.isStatic && !b) {
this.g(world, i, j, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic) {
this.e(world, i, j, k);
}
}
public void onPlace(World world, int i, int j, int k) {
if (!world.isStatic && world.getTileEntity(i, j, k) == null && !b) {
this.g(world, i, j, k);
if (!world.isStatic && world.getTileEntity(i, j, k) == null) {
this.e(world, i, j, k);
}
}
private void g(World world, int i, int j, int k) {
private void e(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
int i1 = d(l);
boolean flag = this.f(world, i, j, k, i1);
int i1 = b(l);
if (l != 7) {
if (flag && !e(l)) {
if (i1 != 7) {
boolean flag = this.a(world, i, j, k, i1);
if (flag && !c(l)) {
// CraftBukkit start
int length = g(world, i, j, k, i1);
int length = h(world, i, j, k, i1);
if (length >= 0) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockPistonExtendEvent event = new BlockPistonExtendEvent(block, length, CraftBlock.notchToBlockFace(i1));
world.getServer().getPluginManager().callEvent(event);
@@ -79,13 +73,11 @@ public class BlockPiston extends Block {
}
// CraftBukkit end
world.setRawData(i, j, k, i1 | 8);
world.playNote(i, j, k, 0, i1);
world.playBlockAction(i, j, k, this, 0, i1);
}
} else if (!flag && e(l)) {
} else if (!flag && c(l)) {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, CraftBlock.notchToBlockFace(i1));
world.getServer().getPluginManager().callEvent(event);
@@ -94,88 +86,96 @@ public class BlockPiston extends Block {
}
// CraftBukkit end
world.setRawData(i, j, k, i1);
world.playNote(i, j, k, 1, i1);
world.setData(i, j, k, i1, 2);
world.playBlockAction(i, j, k, this, 1, i1);
}
}
}
private boolean f(World world, int i, int j, int k, int l) {
return l != 0 && world.isBlockFaceIndirectlyPowered(i, j - 1, k, 0) ? true : (l != 1 && world.isBlockFaceIndirectlyPowered(i, j + 1, k, 1) ? true : (l != 2 && world.isBlockFaceIndirectlyPowered(i, j, k - 1, 2) ? true : (l != 3 && world.isBlockFaceIndirectlyPowered(i, j, k + 1, 3) ? true : (l != 5 && world.isBlockFaceIndirectlyPowered(i + 1, j, k, 5) ? true : (l != 4 && world.isBlockFaceIndirectlyPowered(i - 1, j, k, 4) ? true : (world.isBlockFaceIndirectlyPowered(i, j, k, 0) ? true : (world.isBlockFaceIndirectlyPowered(i, j + 2, k, 1) ? true : (world.isBlockFaceIndirectlyPowered(i, j + 1, k - 1, 2) ? true : (world.isBlockFaceIndirectlyPowered(i, j + 1, k + 1, 3) ? true : (world.isBlockFaceIndirectlyPowered(i - 1, j + 1, k, 4) ? true : world.isBlockFaceIndirectlyPowered(i + 1, j + 1, k, 5)))))))))));
private boolean a(World world, int i, int j, int k, int l) {
return l != 0 && world.isBlockFacePowered(i, j - 1, k, 0) ? true : (l != 1 && world.isBlockFacePowered(i, j + 1, k, 1) ? true : (l != 2 && world.isBlockFacePowered(i, j, k - 1, 2) ? true : (l != 3 && world.isBlockFacePowered(i, j, k + 1, 3) ? true : (l != 5 && world.isBlockFacePowered(i + 1, j, k, 5) ? true : (l != 4 && world.isBlockFacePowered(i - 1, j, k, 4) ? true : (world.isBlockFacePowered(i, j, k, 0) ? true : (world.isBlockFacePowered(i, j + 2, k, 1) ? true : (world.isBlockFacePowered(i, j + 1, k - 1, 2) ? true : (world.isBlockFacePowered(i, j + 1, k + 1, 3) ? true : (world.isBlockFacePowered(i - 1, j + 1, k, 4) ? true : world.isBlockFacePowered(i + 1, j + 1, k, 5)))))))))));
}
public void a(World world, int i, int j, int k, int l, int i1) {
b = true;
if (l == 0) {
if (this.h(world, i, j, k, i1)) {
world.setData(i, j, k, i1 | 8);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "tile.piston.out", 0.5F, world.random.nextFloat() * 0.25F + 0.6F);
} else {
world.setRawData(i, j, k, i1);
public boolean a(World world, int i, int j, int k, int l, int i1) {
if (!world.isStatic) {
boolean flag = this.a(world, i, j, k, i1);
if (flag && l == 1) {
world.setData(i, j, k, i1 | 8, 2);
return false;
}
if (!flag && l == 0) {
return false;
}
}
if (l == 0) {
if (!this.i(world, i, j, k, i1)) {
return false;
}
world.setData(i, j, k, i1 | 8, 2);
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "tile.piston.out", 0.5F, world.random.nextFloat() * 0.25F + 0.6F);
} else if (l == 1) {
TileEntity tileentity = world.getTileEntity(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1]);
if (tileentity != null && tileentity instanceof TileEntityPiston) {
((TileEntityPiston) tileentity).g();
if (tileentity instanceof TileEntityPiston) {
((TileEntityPiston) tileentity).f();
}
world.setRawTypeIdAndData(i, j, k, Block.PISTON_MOVING.id, i1);
world.setTileEntity(i, j, k, BlockPistonMoving.a(this.id, i1, i1, false, true));
world.setTypeAndData(i, j, k, Blocks.PISTON_MOVING, i1, 3);
world.setTileEntity(i, j, k, BlockPistonMoving.a(this, i1, i1, false, true));
if (this.a) {
int j1 = i + Facing.b[i1] * 2;
int k1 = j + Facing.c[i1] * 2;
int l1 = k + Facing.d[i1] * 2;
int i2 = world.getTypeId(j1, k1, l1);
int j2 = world.getData(j1, k1, l1);
boolean flag = false;
Block block = world.getType(j1, k1, l1);
int i2 = world.getData(j1, k1, l1);
boolean flag1 = false;
if (i2 == Block.PISTON_MOVING.id) {
if (block == Blocks.PISTON_MOVING) {
TileEntity tileentity1 = world.getTileEntity(j1, k1, l1);
if (tileentity1 != null && tileentity1 instanceof TileEntityPiston) {
if (tileentity1 instanceof TileEntityPiston) {
TileEntityPiston tileentitypiston = (TileEntityPiston) tileentity1;
if (tileentitypiston.f() == i1 && tileentitypiston.e()) {
tileentitypiston.g();
i2 = tileentitypiston.c();
j2 = tileentitypiston.k();
flag = true;
if (tileentitypiston.c() == i1 && tileentitypiston.b()) {
tileentitypiston.f();
block = tileentitypiston.a();
i2 = tileentitypiston.p();
flag1 = true;
}
}
}
if (!flag && i2 > 0 && a(i2, world, j1, k1, l1, false) && (Block.byId[i2].g() == 0 || i2 == Block.PISTON.id || i2 == Block.PISTON_STICKY.id)) {
if (!flag1 && block.getMaterial() != Material.AIR && a(block, world, j1, k1, l1, false) && (block.h() == 0 || block == Blocks.PISTON || block == Blocks.PISTON_STICKY)) {
i += Facing.b[i1];
j += Facing.c[i1];
k += Facing.d[i1];
world.setRawTypeIdAndData(i, j, k, Block.PISTON_MOVING.id, j2);
world.setTileEntity(i, j, k, BlockPistonMoving.a(i2, j2, i1, false, false));
b = false;
world.setTypeId(j1, k1, l1, 0);
b = true;
} else if (!flag) {
b = false;
world.setTypeId(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1], 0);
b = true;
world.setTypeAndData(i, j, k, Blocks.PISTON_MOVING, i2, 3);
world.setTileEntity(i, j, k, BlockPistonMoving.a(block, i2, i1, false, false));
world.setAir(j1, k1, l1);
} else if (!flag1) {
world.setAir(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1]);
}
} else {
b = false;
world.setTypeId(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1], 0);
b = true;
world.setAir(i + Facing.b[i1], j + Facing.c[i1], k + Facing.d[i1]);
}
world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, "tile.piston.in", 0.5F, world.random.nextFloat() * 0.15F + 0.6F);
}
b = false;
return true;
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
if (e(l)) {
switch (d(l)) {
if (c(l)) {
float f = 0.25F;
switch (b(l)) {
case 0:
this.a(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F);
break;
@@ -204,36 +204,36 @@ public class BlockPiston extends Block {
}
}
public void f() {
public void g() {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, ArrayList arraylist) {
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
this.updateShape(world, i, j, k);
return super.e(world, i, j, k);
return super.a(world, i, j, k);
}
public boolean b() {
public boolean d() {
return false;
}
public static int d(int i) {
if ((i & 7) >= Facing.OPPOSITE_FACING.length) return 0; // CraftBukkit - check for AIOOB on piston data
public static int b(int i) {
if ((i & 7) >= Facing.OPPOSITE_FACING.length) return 7; // CraftBukkit - check for AIOOB on piston data
return i & 7;
}
public static boolean e(int i) {
public static boolean c(int i) {
return (i & 8) != 0;
}
private static int c(World world, int i, int j, int k, EntityHuman entityhuman) {
if (MathHelper.abs((float) entityhuman.locX - (float) i) < 2.0F && MathHelper.abs((float) entityhuman.locZ - (float) k) < 2.0F) {
double d0 = entityhuman.locY + 1.82D - (double) entityhuman.height;
public static int a(World world, int i, int j, int k, EntityLiving entityliving) {
if (MathHelper.abs((float) entityliving.locX - (float) i) < 2.0F && MathHelper.abs((float) entityliving.locZ - (float) k) < 2.0F) {
double d0 = entityliving.locY + 1.82D - (double) entityliving.height;
if (d0 - (double) j > 2.0D) {
return 1;
@@ -244,37 +244,41 @@ public class BlockPiston extends Block {
}
}
int l = MathHelper.floor((double) (entityhuman.yaw * 4.0F / 360.0F) + 0.5D) & 3;
int l = MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3;
return l == 0 ? 2 : (l == 1 ? 5 : (l == 2 ? 3 : (l == 3 ? 4 : 0)));
}
private static boolean a(int i, World world, int j, int k, int l, boolean flag) {
if (i == Block.OBSIDIAN.id) {
private static boolean a(Block block, World world, int i, int j, int k, boolean flag) {
if (block == Blocks.OBSIDIAN) {
return false;
} else {
if (i != Block.PISTON.id && i != Block.PISTON_STICKY.id) {
if (Block.byId[i].m() == -1.0F) {
if (block != Blocks.PISTON && block != Blocks.PISTON_STICKY) {
if (block.f(world, i, j, k) == -1.0F) {
return false;
}
if (Block.byId[i].g() == 2) {
if (block.h() == 2) {
return false;
}
if (!flag && Block.byId[i].g() == 1) {
return false;
if (block.h() == 1) {
if (!flag) {
return false;
}
return true;
}
} else if (e(world.getData(j, k, l))) {
} else if (c(world.getData(i, j, k))) {
return false;
}
return !(Block.byId[i] instanceof BlockContainer);
return !(block instanceof IContainer);
}
}
// CraftBukkit - boolean -> int
private static int g(World world, int i, int j, int k, int l) {
// CraftBukkit - boolean -> int return
private static int h(World world, int i, int j, int k, int l) {
int i1 = i + Facing.b[l];
int j1 = j + Facing.c[l];
int k1 = k + Facing.d[l];
@@ -286,14 +290,14 @@ public class BlockPiston extends Block {
return -1; // CraftBukkit
}
int i2 = world.getTypeId(i1, j1, k1);
Block block = world.getType(i1, j1, k1);
if (i2 != 0) {
if (!a(i2, world, i1, j1, k1, true)) {
if (block.getMaterial() != Material.AIR) {
if (!a(block, world, i1, j1, k1, true)) {
return -1; // CraftBukkit
}
if (Block.byId[i2].g() != 1) {
if (block.h() != 1) {
if (l1 == 12) {
return -1; // CraftBukkit
}
@@ -311,27 +315,26 @@ public class BlockPiston extends Block {
}
}
private boolean h(World world, int i, int j, int k, int l) {
private boolean i(World world, int i, int j, int k, int l) {
int i1 = i + Facing.b[l];
int j1 = j + Facing.c[l];
int k1 = k + Facing.d[l];
int l1 = 0;
while (true) {
int i2;
if (l1 < 13) {
if (j1 <= 0 || j1 >= 255) {
return false;
}
i2 = world.getTypeId(i1, j1, k1);
if (i2 != 0) {
if (!a(i2, world, i1, j1, k1, true)) {
Block block = world.getType(i1, j1, k1);
if (block.getMaterial() != Material.AIR) {
if (!a(block, world, i1, j1, k1, true)) {
return false;
}
if (Block.byId[i2].g() != 1) {
if (block.h() != 1) {
if (l1 == 12) {
return false;
}
@@ -343,29 +346,52 @@ public class BlockPiston extends Block {
continue;
}
Block.byId[i2].b(world, i1, j1, k1, world.getData(i1, j1, k1), 0);
world.setTypeId(i1, j1, k1, 0);
block.b(world, i1, j1, k1, world.getData(i1, j1, k1), 0);
world.setAir(i1, j1, k1);
}
}
while (i1 != i || j1 != j || k1 != k) {
l1 = i1 - Facing.b[l];
i2 = j1 - Facing.c[l];
int j2 = k1 - Facing.d[l];
int k2 = world.getTypeId(l1, i2, j2);
int l2 = world.getData(l1, i2, j2);
l1 = i1;
int i2 = j1;
int j2 = k1;
int k2 = 0;
if (k2 == this.id && l1 == i && i2 == j && j2 == k) {
world.setRawTypeIdAndData(i1, j1, k1, Block.PISTON_MOVING.id, l | (this.a ? 8 : 0));
world.setTileEntity(i1, j1, k1, BlockPistonMoving.a(Block.PISTON_EXTENSION.id, l | (this.a ? 8 : 0), l, true, false));
Block[] ablock;
int l2;
int i3;
int j3;
for (ablock = new Block[13]; i1 != i || j1 != j || k1 != k; k1 = j3) {
l2 = i1 - Facing.b[l];
i3 = j1 - Facing.c[l];
j3 = k1 - Facing.d[l];
Block block1 = world.getType(l2, i3, j3);
int k3 = world.getData(l2, i3, j3);
if (block1 == this && l2 == i && i3 == j && j3 == k) {
world.setTypeAndData(i1, j1, k1, Blocks.PISTON_MOVING, l | (this.a ? 8 : 0), 4);
world.setTileEntity(i1, j1, k1, BlockPistonMoving.a(Blocks.PISTON_EXTENSION, l | (this.a ? 8 : 0), l, true, false));
} else {
world.setRawTypeIdAndData(i1, j1, k1, Block.PISTON_MOVING.id, l2);
world.setTileEntity(i1, j1, k1, BlockPistonMoving.a(k2, l2, l, true, false));
world.setTypeAndData(i1, j1, k1, Blocks.PISTON_MOVING, k3, 4);
world.setTileEntity(i1, j1, k1, BlockPistonMoving.a(block1, k3, l, true, false));
}
i1 = l1;
j1 = i2;
k1 = j2;
ablock[k2++] = block1;
i1 = l2;
j1 = i3;
}
i1 = l1;
j1 = i2;
k1 = j2;
for (k2 = 0; i1 != i || j1 != j || k1 != k; k1 = j3) {
l2 = i1 - Facing.b[l];
i3 = j1 - Facing.c[l];
j3 = k1 - Facing.d[l];
world.applyPhysics(l2, i3, j3, ablock[k2++]);
i1 = l2;
j1 = i3;
}
return true;

View File

@@ -1,53 +1,57 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BlockPistonExtension extends Block {
private int a = -1;
public BlockPistonExtension(int i, int j) {
super(i, j, Material.PISTON);
this.a(h);
public BlockPistonExtension() {
super(Material.PISTON);
this.a(i);
this.c(0.5F);
}
public void remove(World world, int i, int j, int k) {
super.remove(world, i, j, k);
int l = world.getData(i, j, k);
if (l > 5 || l < 0) return; // CraftBukkit - fixed a piston AIOOBE issue.
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (entityhuman.abilities.canInstantlyBuild) {
int i1 = b(l);
Block block = world.getType(i - Facing.b[i1], j - Facing.c[i1], k - Facing.d[i1]);
if (block == Blocks.PISTON || block == Blocks.PISTON_STICKY) {
world.setAir(i - Facing.b[i1], j - Facing.c[i1], k - Facing.d[i1]);
}
}
super.a(world, i, j, k, l, entityhuman);
}
public void remove(World world, int i, int j, int k, Block block, int l) {
super.remove(world, i, j, k, block, l);
if ((l & 7) >= Facing.OPPOSITE_FACING.length) return; // CraftBukkit - fix a piston AIOOBE issue
int i1 = Facing.OPPOSITE_FACING[b(l)];
i += Facing.b[i1];
j += Facing.c[i1];
k += Facing.d[i1];
int j1 = world.getTypeId(i, j, k);
Block block1 = world.getType(i, j, k);
if (j1 == Block.PISTON.id || j1 == Block.PISTON_STICKY.id) {
if (block1 == Blocks.PISTON || block1 == Blocks.PISTON_STICKY) {
l = world.getData(i, j, k);
if (BlockPiston.e(l)) {
Block.byId[j1].b(world, i, j, k, l, 0);
world.setTypeId(i, j, k, 0);
if (BlockPiston.c(l)) {
block1.b(world, i, j, k, l, 0);
world.setAir(i, j, k);
}
}
}
public int a(int i, int j) {
int k = b(j);
return i == k ? (this.a >= 0 ? this.a : ((j & 8) != 0 ? this.textureId - 1 : this.textureId)) : (i == Facing.OPPOSITE_FACING[k] ? 107 : 108);
}
public int c() {
public int b() {
return 17;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
@@ -63,50 +67,55 @@ public class BlockPistonExtension extends Block {
return 0;
}
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, ArrayList arraylist) {
public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
int l = world.getData(i, j, k);
float f = 0.25F;
float f1 = 0.375F;
float f2 = 0.625F;
float f3 = 0.25F;
float f4 = 0.75F;
switch (b(l)) {
case 0:
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.375F, 0.25F, 0.375F, 0.625F, 1.0F, 0.625F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
break;
case 1:
this.a(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.375F, 0.0F, 0.375F, 0.625F, 0.75F, 0.625F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
break;
case 2:
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
break;
case 3:
this.a(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.25F, 0.375F, 0.0F, 0.75F, 0.625F, 0.75F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
break;
case 4:
this.a(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.375F, 0.25F, 0.25F, 0.625F, 0.75F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
break;
case 5:
this.a(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
this.a(0.0F, 0.375F, 0.25F, 0.75F, 0.625F, 0.75F);
super.a(world, i, j, k, axisalignedbb, arraylist);
super.a(world, i, j, k, axisalignedbb, list, entity);
}
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
@@ -114,6 +123,7 @@ public class BlockPistonExtension extends Block {
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
float f = 0.25F;
switch (b(l)) {
case 0:
@@ -141,19 +151,19 @@ public class BlockPistonExtension extends Block {
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
int i1 = b(world.getData(i, j, k));
if (i1 > 5 || i1 < 0) return; // CraftBukkit - fixed a piston AIOOBE issue.
int j1 = world.getTypeId(i - Facing.b[i1], j - Facing.c[i1], k - Facing.d[i1]);
public void doPhysics(World world, int i, int j, int k, Block block) {
int l = b(world.getData(i, j, k));
if ((l & 7) >= Facing.OPPOSITE_FACING.length) return; // CraftBukkit - fix a piston AIOOBE issue
Block block1 = world.getType(i - Facing.b[l], j - Facing.c[l], k - Facing.d[l]);
if (j1 != Block.PISTON.id && j1 != Block.PISTON_STICKY.id) {
world.setTypeId(i, j, k, 0);
if (block1 != Blocks.PISTON && block1 != Blocks.PISTON_STICKY) {
world.setAir(i, j, k);
} else {
Block.byId[j1].doPhysics(world, i - Facing.b[i1], j - Facing.c[i1], k - Facing.d[i1], l);
block1.doPhysics(world, i - Facing.b[l], j - Facing.c[l], k - Facing.d[l], block);
}
}
public static int b(int i) {
return i & 7;
return MathHelper.a(i & 7, 0, Facing.b.length - 1);
}
}

View File

@@ -2,156 +2,102 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.world.PortalCreateEvent;
// CraftBukkit end
import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit
public class BlockPortal extends BlockHalfTransparant {
public class BlockPortal extends BlockHalfTransparent {
public BlockPortal(int i, int j) {
super(i, j, Material.PORTAL, false);
public static final int[][] a = new int[][] { new int[0], { 3, 1}, { 2, 0}};
public BlockPortal() {
super("portal", Material.PORTAL, false);
this.a(true);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public void a(World world, int i, int j, int k, Random random) {
super.a(world, i, j, k, random);
if (world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.difficulty.a()) {
int l;
for (l = j; !World.a((IBlockAccess) world, i, l, k) && l > 0; --l) {
;
}
if (l > 0 && !world.getType(i, l + 1, k).r()) {
// CraftBukkit - set spawn reason to NETHER_PORTAL
Entity entity = ItemMonsterEgg.spawnCreature(world, 57, (double) i + 0.5D, (double) l + 1.1D, (double) k + 0.5D, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
if (entity != null) {
entity.portalCooldown = entity.ai();
}
}
}
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
float f;
float f1;
int l = b(iblockaccess.getData(i, j, k));
if (iblockaccess.getTypeId(i - 1, j, k) != this.id && iblockaccess.getTypeId(i + 1, j, k) != this.id) {
f = 0.125F;
f1 = 0.5F;
this.a(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
} else {
f = 0.5F;
f1 = 0.125F;
this.a(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
}
}
public boolean a() {
return false;
}
public boolean b() {
return false;
}
public boolean b_(World world, int i, int j, int k) {
byte b0 = 0;
byte b1 = 0;
if (world.getTypeId(i - 1, j, k) == Block.OBSIDIAN.id || world.getTypeId(i + 1, j, k) == Block.OBSIDIAN.id) {
b0 = 1;
}
if (world.getTypeId(i, j, k - 1) == Block.OBSIDIAN.id || world.getTypeId(i, j, k + 1) == Block.OBSIDIAN.id) {
b1 = 1;
}
if (b0 == b1) {
return false;
} else {
// CraftBukkit start
java.util.Collection<org.bukkit.block.Block> blocks = new java.util.HashSet<org.bukkit.block.Block>();
org.bukkit.World bworld = world.getWorld();
// CraftBukkit end
if (world.getTypeId(i - b0, j, k - b1) == 0) {
i -= b0;
k -= b1;
}
int l;
int i1;
for (l = -1; l <= 2; ++l) {
for (i1 = -1; i1 <= 3; ++i1) {
boolean flag = l == -1 || l == 2 || i1 == -1 || i1 == 3;
if (l != -1 && l != 2 || i1 != -1 && i1 != 3) {
int j1 = world.getTypeId(i + b0 * l, j + i1, k + b1 * l);
if (flag) {
if (j1 != Block.OBSIDIAN.id) {
return false;
} else {
blocks.add(bworld.getBlockAt(i + b0 * l, j + i1, k + b1 * l)); // CraftBukkit
}
} else if (j1 != 0 && j1 != Block.FIRE.id) {
return false;
}
}
}
}
// CraftBukkit start
for (l = 0; l < 2; ++l) {
for (i1 = 0; i1 < 3; ++i1) {
blocks.add(bworld.getBlockAt(i + b0 * l, j + i1, k + b1 * l));
}
}
PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, PortalCreateEvent.CreateReason.FIRE);
world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
// CraftBukkit end
world.suppressPhysics = true;
for (l = 0; l < 2; ++l) {
for (i1 = 0; i1 < 3; ++i1) {
world.setTypeId(i + b0 * l, j + i1, k + b1 * l, Block.PORTAL.id);
}
}
world.suppressPhysics = false;
return true;
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
byte b0 = 0;
byte b1 = 1;
if (world.getTypeId(i - 1, j, k) == this.id || world.getTypeId(i + 1, j, k) == this.id) {
b0 = 1;
b1 = 0;
}
int i1;
for (i1 = j; world.getTypeId(i, i1 - 1, k) == this.id; --i1) {
;
}
if (world.getTypeId(i, i1 - 1, k) != Block.OBSIDIAN.id) {
world.setTypeId(i, j, k, 0);
} else {
int j1;
for (j1 = 1; j1 < 4 && world.getTypeId(i, i1 + j1, k) == this.id; ++j1) {
;
}
if (j1 == 3 && world.getTypeId(i, i1 + j1, k) == Block.OBSIDIAN.id) {
boolean flag = world.getTypeId(i - 1, j, k) == this.id || world.getTypeId(i + 1, j, k) == this.id;
boolean flag1 = world.getTypeId(i, j, k - 1) == this.id || world.getTypeId(i, j, k + 1) == this.id;
if (flag && flag1) {
world.setTypeId(i, j, k, 0);
} else if ((world.getTypeId(i + b0, j, k + b1) != Block.OBSIDIAN.id || world.getTypeId(i - b0, j, k - b1) != this.id) && (world.getTypeId(i - b0, j, k - b1) != Block.OBSIDIAN.id || world.getTypeId(i + b0, j, k + b1) != this.id)) {
world.setTypeId(i, j, k, 0);
}
if (l == 0) {
if (iblockaccess.getType(i - 1, j, k) != this && iblockaccess.getType(i + 1, j, k) != this) {
l = 2;
} else {
world.setTypeId(i, j, k, 0);
l = 1;
}
if (iblockaccess instanceof World && !((World) iblockaccess).isStatic) {
((World) iblockaccess).setData(i, j, k, l, 2);
}
}
float f = 0.125F;
float f1 = 0.125F;
if (l == 1) {
f = 0.5F;
}
if (l == 2) {
f1 = 0.5F;
}
this.a(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
}
public boolean d() {
return false;
}
public boolean e(World world, int i, int j, int k) {
PortalCreator portalcreator = new PortalCreator(world, i, j, k, 1);
PortalCreator portalcreator1 = new PortalCreator(world, i, j, k, 2);
if (portalcreator.b() && PortalCreator.a(portalcreator) == 0) {
// CraftBukkit start - return portalcreator
return portalcreator.c();
// return true;
} else if (portalcreator1.b() && PortalCreator.a(portalcreator1) == 0) {
return portalcreator1.c();
// return true;
// CraftBukkit end
} else {
return false;
}
}
public void doPhysics(World world, int i, int j, int k, Block block) {
int l = b(world.getData(i, j, k));
PortalCreator portalcreator = new PortalCreator(world, i, j, k, 1);
PortalCreator portalcreator1 = new PortalCreator(world, i, j, k, 2);
if (l == 1 && (!portalcreator.b() || PortalCreator.a(portalcreator) < PortalCreator.b(portalcreator) * PortalCreator.c(portalcreator))) {
world.setTypeUpdate(i, j, k, Blocks.AIR);
} else if (l == 2 && (!portalcreator1.b() || PortalCreator.a(portalcreator1) < PortalCreator.b(portalcreator1) * PortalCreator.c(portalcreator1))) {
world.setTypeUpdate(i, j, k, Blocks.AIR);
} else if (l == 0 && !portalcreator.b() && !portalcreator1.b()) {
world.setTypeUpdate(i, j, k, Blocks.AIR);
}
}
@@ -166,7 +112,11 @@ public class BlockPortal extends BlockHalfTransparant {
world.getServer().getPluginManager().callEvent(event);
// CraftBukkit end
entity.ad();
entity.ah();
}
}
public static int b(int i) {
return i & 3;
}
}

View File

@@ -0,0 +1,146 @@
package net.minecraft.server;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockPoweredRail extends BlockMinecartTrackAbstract {
protected BlockPoweredRail() {
super(true);
}
protected boolean a(World world, int i, int j, int k, int l, boolean flag, int i1) {
if (i1 >= 8) {
return false;
} else {
int j1 = l & 0x7;
boolean flag1 = true;
switch (j1) {
case 0:
if (flag) {
++k;
} else {
--k;
}
break;
case 1:
if (flag) {
--i;
} else {
++i;
}
break;
case 2:
if (flag) {
i--;
} else {
++i;
++j;
flag1 = false;
}
j1 = 1;
break;
case 3:
if (flag) {
--i;
++j;
flag1 = false;
} else {
++i;
}
j1 = 1;
break;
case 4:
if (flag) {
++k;
} else {
--k;
++j;
flag1 = false;
}
j1 = 0;
break;
case 5:
if (flag) {
++k;
++j;
flag1 = false;
} else {
--k;
}
j1 = 0;
}
return this.a(world, i, j, k, flag, i1, j1) ? true : flag1 && this.a(world, i, j - 1, k, flag, i1, j1);
}
}
protected boolean a(World world, int i, int j, int k, boolean flag, int l, int i1) {
Block block = world.getType(i, j, k);
if (block == this) {
int j1 = world.getData(i, j, k);
int k1 = j1 & 0x7;
if (i1 == 1 && (k1 == 0 || k1 == 4 || k1 == 5)) {
return false;
}
if (i1 == 0 && (k1 == 1 || k1 == 2 || k1 == 3)) {
return false;
}
if ((j1 & 0x8) != 0) {
if (world.isBlockIndirectlyPowered(i, j, k)) {
return true;
}
return this.a(world, i, j, k, j1, flag, l + 1);
}
}
return false;
}
protected void a(World world, int i, int j, int k, int l, int i1, Block block) {
boolean flag = world.isBlockIndirectlyPowered(i, j, k);
flag = flag || this.a(world, i, j, k, l, true, 0) || this.a(world, i, j, k, l, false, 0);
boolean flag1 = false;
if (flag && (l & 0x8) == 0) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 0, 15).getNewCurrent() <= 0) {
return;
}
// CraftBukkit end
world.setData(i, j, k, i1 | 0x8, 3);
flag1 = true;
} else if (!flag && (l & 0x8) != 0) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 15, 0).getNewCurrent() > 0) {
return;
}
// CraftBukkit end
world.setData(i, j, k, i1, 3);
flag1 = true;
}
if (flag1) {
world.applyPhysics(i, j - 1, k, this);
if (i1 == 2 || i1 == 3 || i1 == 4 || i1 == 5) {
world.applyPhysics(i, j + 1, k, this);
}
}
}
}

View File

@@ -1,200 +0,0 @@
package net.minecraft.server;
import java.util.List;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.entity.EntityInteractEvent;
// CraftBukkit end
public class BlockPressurePlate extends Block {
private EnumMobType a;
protected BlockPressurePlate(int i, int j, EnumMobType enummobtype, Material material) {
super(i, j, material);
this.a = enummobtype;
this.a(true);
float f = 0.0625F;
this.a(f, 0.0F, f, 1.0F - f, 0.03125F, 1.0F - f);
}
public int d() {
return 20;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
return null;
}
public boolean a() {
return false;
}
public boolean b() {
return false;
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
return true;
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i, j - 1, k) || world.getTypeId(i, j - 1, k) == Block.FENCE.id;
}
public void onPlace(World world, int i, int j, int k) {}
public void doPhysics(World world, int i, int j, int k, int l) {
boolean flag = false;
if (!world.e(i, j - 1, k) && world.getTypeId(i, j - 1, k) != Block.FENCE.id) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
}
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
if (world.getData(i, j, k) != 0) {
this.g(world, i, j, k);
}
}
}
public void a(World world, int i, int j, int k, Entity entity) {
if (!world.isStatic) {
if (world.getData(i, j, k) != 1) {
this.g(world, i, j, k);
}
}
}
private void g(World world, int i, int j, int k) {
boolean flag = world.getData(i, j, k) == 1;
boolean flag1 = false;
float f = 0.125F;
List list = null;
if (this.a == EnumMobType.EVERYTHING) {
list = world.getEntities((Entity) null, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f)));
}
if (this.a == EnumMobType.MOBS) {
list = world.a(EntityLiving.class, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f)));
}
if (this.a == EnumMobType.PLAYERS) {
list = world.a(EntityHuman.class, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f)));
}
if (list.size() > 0) {
flag1 = true;
}
// CraftBukkit start - Interact Pressure Plate
org.bukkit.World bworld = world.getWorld();
org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager();
if (flag != flag1) {
if (flag1) {
for (Object object : list) {
if (object != null) {
org.bukkit.event.Cancellable cancellable;
if (object instanceof EntityHuman) {
cancellable = CraftEventFactory.callPlayerInteractEvent((EntityHuman) object, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
} else if (object instanceof Entity) {
cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), bworld.getBlockAt(i, j, k));
manager.callEvent((EntityInteractEvent) cancellable);
} else {
continue;
}
if (cancellable.isCancelled()) {
return;
}
}
}
}
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(i, j, k), flag ? 1 : 0, flag1 ? 1 : 0);
manager.callEvent(eventRedstone);
flag1 = eventRedstone.getNewCurrent() > 0;
}
// CraftBukkit end
if (flag1 && !flag) {
world.setData(i, j, k, 1);
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.b(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.3F, 0.6F);
}
if (!flag1 && flag) {
world.setData(i, j, k, 0);
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.b(i, j, k, i, j, k);
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.3F, 0.5F);
}
if (flag1) {
world.c(i, j, k, this.id, this.d());
}
}
public void remove(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
if (l > 0) {
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
}
super.remove(world, i, j, k);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
boolean flag = iblockaccess.getData(i, j, k) == 1;
float f = 0.0625F;
if (flag) {
this.a(f, 0.0F, f, 1.0F - f, 0.03125F, 1.0F - f);
} else {
this.a(f, 0.0F, f, 1.0F - f, 0.0625F, 1.0F - f);
}
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return iblockaccess.getData(i, j, k) > 0;
}
public boolean d(World world, int i, int j, int k, int l) {
return world.getData(i, j, k) == 0 ? false : l == 1;
}
public boolean isPowerSource() {
return true;
}
public void f() {
float f = 0.5F;
float f1 = 0.125F;
float f2 = 0.5F;
this.a(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2);
}
public int g() {
return 1;
}
}

View File

@@ -0,0 +1,174 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public abstract class BlockPressurePlateAbstract extends Block {
private String a;
protected BlockPressurePlateAbstract(String s, Material material) {
super(material);
this.a = s;
this.a(CreativeModeTab.d);
this.a(true);
this.b(this.d(15));
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.b(iblockaccess.getData(i, j, k));
}
protected void b(int i) {
boolean flag = this.c(i) > 0;
float f = 0.0625F;
if (flag) {
this.a(f, 0.0F, f, 1.0F - f, 0.03125F, 1.0F - f);
} else {
this.a(f, 0.0F, f, 1.0F - f, 0.0625F, 1.0F - f);
}
}
public int a(World world) {
return 20;
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
return true;
}
public boolean canPlace(World world, int i, int j, int k) {
return World.a((IBlockAccess) world, i, j - 1, k) || BlockFence.a(world.getType(i, j - 1, k));
}
public void doPhysics(World world, int i, int j, int k, Block block) {
boolean flag = false;
if (!World.a((IBlockAccess) world, i, j - 1, k) && !BlockFence.a(world.getType(i, j - 1, k))) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
}
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
int l = this.c(world.getData(i, j, k));
if (l > 0) {
this.a(world, i, j, k, l);
}
}
}
public void a(World world, int i, int j, int k, Entity entity) {
if (!world.isStatic) {
int l = this.c(world.getData(i, j, k));
if (l == 0) {
this.a(world, i, j, k, l);
}
}
}
protected void a(World world, int i, int j, int k, int l) {
int i1 = this.e(world, i, j, k);
boolean flag = l > 0;
boolean flag1 = i1 > 0;
// CraftBukkit start - Interact Pressure Plate
org.bukkit.World bworld = world.getWorld();
org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager();
if (flag != flag1) {
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(i, j, k), l, i1);
manager.callEvent(eventRedstone);
flag1 = eventRedstone.getNewCurrent() > 0;
i1 = eventRedstone.getNewCurrent();
}
// CraftBukkit end
if (l != i1) {
world.setData(i, j, k, this.d(i1), 2);
this.a_(world, i, j, k);
world.c(i, j, k, i, j, k);
}
if (!flag1 && flag) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.3F, 0.5F);
} else if (flag1 && !flag) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.3F, 0.6F);
}
if (flag1) {
world.a(i, j, k, this, this.a(world));
}
}
protected AxisAlignedBB a(int i, int j, int k) {
float f = 0.125F;
return AxisAlignedBB.a((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f));
}
public void remove(World world, int i, int j, int k, Block block, int l) {
if (this.c(l) > 0) {
this.a_(world, i, j, k);
}
super.remove(world, i, j, k, block, l);
}
protected void a_(World world, int i, int j, int k) {
world.applyPhysics(i, j, k, this);
world.applyPhysics(i, j - 1, k, this);
}
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return this.c(iblockaccess.getData(i, j, k));
}
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return l == 1 ? this.c(iblockaccess.getData(i, j, k)) : 0;
}
public boolean isPowerSource() {
return true;
}
public void g() {
float f = 0.5F;
float f1 = 0.125F;
float f2 = 0.5F;
this.a(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2);
}
public int h() {
return 1;
}
protected abstract int e(World world, int i, int j, int k);
protected abstract int c(int i);
protected abstract int d(int i);
}

View File

@@ -0,0 +1,74 @@
package net.minecraft.server;
import java.util.Iterator;
import java.util.List;
import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit
public class BlockPressurePlateBinary extends BlockPressurePlateAbstract {
private EnumMobType a;
protected BlockPressurePlateBinary(String s, Material material, EnumMobType enummobtype) {
super(s, material);
this.a = enummobtype;
}
protected int d(int i) {
return i > 0 ? 1 : 0;
}
protected int c(int i) {
return i == 1 ? 15 : 0;
}
protected int e(World world, int i, int j, int k) {
List list = null;
if (this.a == EnumMobType.EVERYTHING) {
list = world.getEntities((Entity) null, this.a(i, j, k));
}
if (this.a == EnumMobType.MOBS) {
list = world.a(EntityLiving.class, this.a(i, j, k));
}
if (this.a == EnumMobType.PLAYERS) {
list = world.a(EntityHuman.class, this.a(i, j, k));
}
if (list != null && !list.isEmpty()) {
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
// CraftBukkit start - Call interact event when turning on a pressure plate
if (this.c(world.getData(i, j, k)) == 0) {
org.bukkit.World bworld = world.getWorld();
org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager();
org.bukkit.event.Cancellable cancellable;
if (entity instanceof EntityHuman) {
cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
} else {
cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(i, j, k));
manager.callEvent((EntityInteractEvent) cancellable);
}
// We only want to block turning the plate on if all events are cancelled
if (cancellable.isCancelled()) {
continue;
}
}
// CraftBukkit end
if (!entity.az()) {
return 15;
}
}
}
return 0;
}
}

View File

@@ -0,0 +1,58 @@
package net.minecraft.server;
import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit
public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract {
private final int a;
protected BlockPressurePlateWeighted(String s, Material material, int i) {
super(s, material);
this.a = i;
}
protected int e(World world, int i, int j, int k) {
// CraftBukkit start
int l = 0;
java.util.Iterator iterator = world.a(Entity.class, this.a(i, j, k)).iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
org.bukkit.event.Cancellable cancellable;
if (entity instanceof EntityHuman) {
cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
} else {
cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(i, j, k));
world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable);
}
// We only want to block turning the plate on if all events are cancelled
if (!cancellable.isCancelled()) {
l++;
}
}
l = Math.min(l, this.a);
// CraftBukkit end
if (l <= 0) {
return 0;
}
float f = (float) Math.min(this.a, l) / (float) this.a;
return MathHelper.f(f * 15.0F);
}
protected int c(int i) {
return i;
}
protected int d(int i) {
return i;
}
public int a(World world) {
return 10;
}
}

View File

@@ -10,37 +10,16 @@ public class BlockPumpkin extends BlockDirectional {
private boolean a;
protected BlockPumpkin(int i, int j, boolean flag) {
super(i, Material.PUMPKIN);
this.textureId = j;
protected BlockPumpkin(boolean flag) {
super(Material.PUMPKIN);
this.a(true);
this.a = flag;
}
public int a(int i, int j) {
if (i == 1) {
return this.textureId;
} else if (i == 0) {
return this.textureId;
} else {
int k = this.textureId + 1 + 16;
if (this.a) {
++k;
}
return j == 2 && i == 2 ? k : (j == 3 && i == 5 ? k : (j == 0 && i == 3 ? k : (j == 1 && i == 4 ? k : this.textureId + 16)));
}
}
public int a(int i) {
return i == 1 ? this.textureId : (i == 0 ? this.textureId : (i == 3 ? this.textureId + 1 + 16 : this.textureId + 16));
this.a(CreativeModeTab.b);
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
if (world.suppressPhysics) return; // CraftBukkit
if (world.getTypeId(i, j - 1, k) == Block.SNOW_BLOCK.id && world.getTypeId(i, j - 2, k) == Block.SNOW_BLOCK.id) {
if (world.getType(i, j - 1, k) == Blocks.SNOW_BLOCK && world.getType(i, j - 2, k) == Blocks.SNOW_BLOCK) {
if (!world.isStatic) {
// CraftBukkit start - Use BlockStateListPopulator
BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld());
@@ -48,7 +27,6 @@ public class BlockPumpkin extends BlockDirectional {
blockList.setTypeId(i, j, k, 0);
blockList.setTypeId(i, j - 1, k, 0);
blockList.setTypeId(i, j - 2, k, 0);
EntitySnowman entitysnowman = new EntitySnowman(world);
entitysnowman.setPositionRotation((double) i + 0.5D, (double) j - 1.95D, (double) k + 0.5D, 0.0F, 0.0F);
@@ -59,11 +37,11 @@ public class BlockPumpkin extends BlockDirectional {
}
for (int l = 0; l < 120; ++l) {
world.a("snowshovel", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 2.5D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
world.addParticle("snowshovel", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 2.5D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
}
} else if (world.getTypeId(i, j - 1, k) == Block.IRON_BLOCK.id && world.getTypeId(i, j - 2, k) == Block.IRON_BLOCK.id) {
boolean flag = world.getTypeId(i - 1, j - 1, k) == Block.IRON_BLOCK.id && world.getTypeId(i + 1, j - 1, k) == Block.IRON_BLOCK.id;
boolean flag1 = world.getTypeId(i, j - 1, k - 1) == Block.IRON_BLOCK.id && world.getTypeId(i, j - 1, k + 1) == Block.IRON_BLOCK.id;
} else if (world.getType(i, j - 1, k) == Blocks.IRON_BLOCK && world.getType(i, j - 2, k) == Blocks.IRON_BLOCK) {
boolean flag = world.getType(i - 1, j - 1, k) == Blocks.IRON_BLOCK && world.getType(i + 1, j - 1, k) == Blocks.IRON_BLOCK;
boolean flag1 = world.getType(i, j - 1, k - 1) == Blocks.IRON_BLOCK && world.getType(i, j - 1, k + 1) == Blocks.IRON_BLOCK;
if (flag || flag1) {
// CraftBukkit start - Use BlockStateListPopulator
@@ -82,11 +60,11 @@ public class BlockPumpkin extends BlockDirectional {
EntityIronGolem entityirongolem = new EntityIronGolem(world);
entityirongolem.b(true);
entityirongolem.setPlayerCreated(true);
entityirongolem.setPositionRotation((double) i + 0.5D, (double) j - 1.95D, (double) k + 0.5D, 0.0F, 0.0F);
if (world.addEntity(entityirongolem, SpawnReason.BUILD_IRONGOLEM)) {
for (int i1 = 0; i1 < 120; ++i1) {
world.a("snowballpoof", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 3.9D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
world.addParticle("snowballpoof", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 3.9D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
}
blockList.updateList();
@@ -97,24 +75,22 @@ public class BlockPumpkin extends BlockDirectional {
}
public boolean canPlace(World world, int i, int j, int k) {
int l = world.getTypeId(i, j, k);
return (l == 0 || Block.byId[l].material.isReplacable()) && world.e(i, j - 1, k);
return world.getType(i, j, k).material.isReplaceable() && World.a((IBlockAccess) world, i, j - 1, k);
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving) {
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 2.5D) & 3;
world.setData(i, j, k, l);
world.setData(i, j, k, l, 2);
}
// CraftBukkit start
public void doPhysics(World world, int i, int j, int k, int l) {
if (net.minecraft.server.Block.byId[l] != null && net.minecraft.server.Block.byId[l].isPowerSource()) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int power = block.getBlockPower();
public void doPhysics(World world, int i, int j, int k, Block block) {
if (block != null && block.isPowerSource()) {
org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i, j, k);
int power = bukkitBlock.getBlockPower();
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, power, power);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, power, power);
world.getServer().getPluginManager().callEvent(eventRedstone);
}
}

View File

@@ -2,50 +2,48 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.block.BlockRedstoneEvent;
// CraftBukkit end
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockRedstoneLamp extends Block {
private final boolean a;
public BlockRedstoneLamp(int i, boolean flag) {
super(i, 211, Material.BUILDABLE_GLASS);
public BlockRedstoneLamp(boolean flag) {
super(Material.BUILDABLE_GLASS);
this.a = flag;
if (flag) {
this.a(1.0F);
++this.textureId;
}
}
public void onPlace(World world, int i, int j, int k) {
if (!world.isStatic) {
if (this.a && !world.isBlockIndirectlyPowered(i, j, k)) {
world.c(i, j, k, this.id, 4);
world.a(i, j, k, this, 4);
} else if (!this.a && world.isBlockIndirectlyPowered(i, j, k)) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 0, 15).getNewCurrent() != 15) {
return;
}
// CraftBukkit end
world.setTypeId(i, j, k, Block.REDSTONE_LAMP_ON.id);
world.setTypeAndData(i, j, k, Blocks.REDSTONE_LAMP_ON, 0, 2);
}
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic) {
if (this.a && !world.isBlockIndirectlyPowered(i, j, k)) {
world.c(i, j, k, this.id, 4);
world.a(i, j, k, this, 4);
} else if (!this.a && world.isBlockIndirectlyPowered(i, j, k)) {
// CraftBukkit start
if (CraftEventFactory.callRedstoneChange(world, i, j, k, 0, 15).getNewCurrent() != 15) {
return;
}
// CraftBukkit end
world.setTypeId(i, j, k, Block.REDSTONE_LAMP_ON.id);
world.setTypeAndData(i, j, k, Blocks.REDSTONE_LAMP_ON, 0, 2);
}
}
}
@@ -57,11 +55,16 @@ public class BlockRedstoneLamp extends Block {
return;
}
// CraftBukkit end
world.setTypeId(i, j, k, Block.REDSTONE_LAMP_OFF.id);
world.setTypeAndData(i, j, k, Blocks.REDSTONE_LAMP_OFF, 0, 2);
}
}
public int getDropType(int i, Random random, int j) {
return Block.REDSTONE_LAMP_OFF.id;
public Item getDropType(int i, Random random, int j) {
return Item.getItemOf(Blocks.REDSTONE_LAMP_OFF);
}
protected ItemStack j(int i) {
return new ItemStack(Blocks.REDSTONE_LAMP_OFF);
}
}

View File

@@ -2,12 +2,17 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.entity.EntityInteractEvent;
// CraftBukkit end
public class BlockRedstoneOre extends Block {
private boolean a;
public BlockRedstoneOre(int i, int j, boolean flag) {
super(i, j, Material.STONE);
public BlockRedstoneOre(boolean flag) {
super(Material.STONE);
if (flag) {
this.a(true);
}
@@ -15,12 +20,12 @@ public class BlockRedstoneOre extends Block {
this.a = flag;
}
public int d() {
public int a(World world) {
return 30;
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.g(world, i, j, k);
this.e(world, i, j, k, entityhuman); // CraftBukkit - add entityhuman
super.attack(world, i, j, k, entityhuman);
}
@@ -29,40 +34,50 @@ public class BlockRedstoneOre extends Block {
if (entity instanceof EntityHuman) {
org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
if (!event.isCancelled()) {
this.g(world, i, j, k);
this.e(world, i, j, k, entity); // add entity
super.b(world, i, j, k, entity);
}
} else {
org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(i, j, k));
EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(i, j, k));
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
this.g(world, i, j, k);
this.e(world, i, j, k, entity); // add entity
super.b(world, i, j, k, entity);
}
}
// CraftBukkit end
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
this.g(world, i, j, k);
return super.interact(world, i, j, k, entityhuman);
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
this.e(world, i, j, k, entityhuman); // CraftBukkit - add entityhuman
return super.interact(world, i, j, k, entityhuman, l, f, f1, f2);
}
private void g(World world, int i, int j, int k) {
this.h(world, i, j, k);
if (this.id == Block.REDSTONE_ORE.id) {
world.setTypeId(i, j, k, Block.GLOWING_REDSTONE_ORE.id);
private void e(World world, int i, int j, int k, Entity entity) { // CraftBukkit - add Entity
this.m(world, i, j, k);
if (this == Blocks.REDSTONE_ORE) {
// CraftBukkit start
if (CraftEventFactory.callEntityChangeBlockEvent(entity, i, j, k, Blocks.GLOWING_REDSTONE_ORE, 0).isCancelled()) {
return;
}
// CraftBukkit end
world.setTypeUpdate(i, j, k, Blocks.GLOWING_REDSTONE_ORE);
}
}
public void a(World world, int i, int j, int k, Random random) {
if (this.id == Block.GLOWING_REDSTONE_ORE.id) {
world.setTypeId(i, j, k, Block.REDSTONE_ORE.id);
if (this == Blocks.GLOWING_REDSTONE_ORE) {
// CraftBukkit start
if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(i, j, k), Blocks.REDSTONE_ORE).isCancelled()) {
return;
}
// CraftBukkit end
world.setTypeUpdate(i, j, k, Blocks.REDSTONE_ORE);
}
}
public int getDropType(int i, Random random, int j) {
return Item.REDSTONE.id;
public Item getDropType(int i, Random random, int j) {
return Items.REDSTONE;
}
public int getDropCount(int i, Random random) {
@@ -73,7 +88,29 @@ public class BlockRedstoneOre extends Block {
return 4 + random.nextInt(2);
}
private void h(World world, int i, int j, int k) {
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
super.dropNaturally(world, i, j, k, l, f, i1);
/* CraftBukkit start - Delegated to getExpDrop
if (this.getDropType(l, world.random, i1) != Item.getItemOf(this)) {
int j1 = 1 + world.random.nextInt(5);
this.dropExperience(world, i, j, k, j1);
}
// */
}
public int getExpDrop(World world, int l, int i1) {
if (this.getDropType(l, world.random, i1) != Item.getItemOf(this)) {
int j1 = 1 + world.random.nextInt(5);
return j1;
}
return 0;
// CraftBukkit end
}
private void m(World world, int i, int j, int k) {
Random random = world.random;
double d0 = 0.0625D;
@@ -82,37 +119,37 @@ public class BlockRedstoneOre extends Block {
double d2 = (double) ((float) j + random.nextFloat());
double d3 = (double) ((float) k + random.nextFloat());
if (l == 0 && !world.r(i, j + 1, k)) {
if (l == 0 && !world.getType(i, j + 1, k).c()) {
d2 = (double) (j + 1) + d0;
}
if (l == 1 && !world.r(i, j - 1, k)) {
if (l == 1 && !world.getType(i, j - 1, k).c()) {
d2 = (double) (j + 0) - d0;
}
if (l == 2 && !world.r(i, j, k + 1)) {
if (l == 2 && !world.getType(i, j, k + 1).c()) {
d3 = (double) (k + 1) + d0;
}
if (l == 3 && !world.r(i, j, k - 1)) {
if (l == 3 && !world.getType(i, j, k - 1).c()) {
d3 = (double) (k + 0) - d0;
}
if (l == 4 && !world.r(i + 1, j, k)) {
if (l == 4 && !world.getType(i + 1, j, k).c()) {
d1 = (double) (i + 1) + d0;
}
if (l == 5 && !world.r(i - 1, j, k)) {
if (l == 5 && !world.getType(i - 1, j, k).c()) {
d1 = (double) (i + 0) - d0;
}
if (d1 < (double) i || d1 > (double) (i + 1) || d2 < 0.0D || d2 > (double) (j + 1) || d3 < (double) k || d3 > (double) (k + 1)) {
world.a("reddust", d1, d2, d3, 0.0D, 0.0D, 0.0D);
world.addParticle("reddust", d1, d2, d3, 0.0D, 0.0D, 0.0D);
}
}
}
protected ItemStack a_(int i) {
return new ItemStack(Block.REDSTONE_ORE);
protected ItemStack j(int i) {
return new ItemStack(Blocks.REDSTONE_ORE);
}
}

View File

@@ -1,29 +1,33 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockRedstoneTorch extends BlockTorch {
private boolean isOn = false;
private static List b = new ArrayList();
public int a(int i, int j) {
return i == 1 ? Block.REDSTONE_WIRE.a(i, j) : super.a(i, j);
}
private boolean isOn;
private static Map b = new HashMap();
private boolean a(World world, int i, int j, int k, boolean flag) {
if (!b.containsKey(world)) {
b.put(world, new ArrayList());
}
List list = (List) b.get(world);
if (flag) {
b.add(new RedstoneUpdateInfo(i, j, k, world.getTime()));
list.add(new RedstoneUpdateInfo(i, j, k, world.getTime()));
}
int l = 0;
for (int i1 = 0; i1 < b.size(); ++i1) {
RedstoneUpdateInfo redstoneupdateinfo = (RedstoneUpdateInfo) b.get(i1);
for (int i1 = 0; i1 < list.size(); ++i1) {
RedstoneUpdateInfo redstoneupdateinfo = (RedstoneUpdateInfo) list.get(i1);
if (redstoneupdateinfo.a == i && redstoneupdateinfo.b == j && redstoneupdateinfo.c == k) {
++l;
@@ -36,13 +40,13 @@ public class BlockRedstoneTorch extends BlockTorch {
return false;
}
protected BlockRedstoneTorch(int i, int j, boolean flag) {
super(i, j);
protected BlockRedstoneTorch(boolean flag) {
this.isOn = flag;
this.a(true);
this.a((CreativeModeTab) null);
}
public int d() {
public int a(World world) {
return 2;
}
@@ -52,47 +56,48 @@ public class BlockRedstoneTorch extends BlockTorch {
}
if (this.isOn) {
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i, j + 1, k, this.id);
world.applyPhysics(i - 1, j, k, this.id);
world.applyPhysics(i + 1, j, k, this.id);
world.applyPhysics(i, j, k - 1, this.id);
world.applyPhysics(i, j, k + 1, this.id);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i, j + 1, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i, j, k - 1, this);
world.applyPhysics(i, j, k + 1, this);
}
}
public void remove(World world, int i, int j, int k) {
public void remove(World world, int i, int j, int k, Block block, int l) {
if (this.isOn) {
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i, j + 1, k, this.id);
world.applyPhysics(i - 1, j, k, this.id);
world.applyPhysics(i + 1, j, k, this.id);
world.applyPhysics(i, j, k - 1, this.id);
world.applyPhysics(i, j, k + 1, this.id);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i, j + 1, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i, j, k - 1, this);
world.applyPhysics(i, j, k + 1, this);
}
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
if (!this.isOn) {
return false;
return 0;
} else {
int i1 = iblockaccess.getData(i, j, k);
return i1 == 5 && l == 1 ? false : (i1 == 3 && l == 3 ? false : (i1 == 4 && l == 2 ? false : (i1 == 1 && l == 5 ? false : i1 != 2 || l != 4)));
return i1 == 5 && l == 1 ? 0 : (i1 == 3 && l == 3 ? 0 : (i1 == 4 && l == 2 ? 0 : (i1 == 1 && l == 5 ? 0 : (i1 == 2 && l == 4 ? 0 : 15))));
}
}
private boolean g(World world, int i, int j, int k) {
private boolean m(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
return l == 5 && world.isBlockFaceIndirectlyPowered(i, j - 1, k, 0) ? true : (l == 3 && world.isBlockFaceIndirectlyPowered(i, j, k - 1, 2) ? true : (l == 4 && world.isBlockFaceIndirectlyPowered(i, j, k + 1, 3) ? true : (l == 1 && world.isBlockFaceIndirectlyPowered(i - 1, j, k, 4) ? true : l == 2 && world.isBlockFaceIndirectlyPowered(i + 1, j, k, 5))));
return l == 5 && world.isBlockFacePowered(i, j - 1, k, 0) ? true : (l == 3 && world.isBlockFacePowered(i, j, k - 1, 2) ? true : (l == 4 && world.isBlockFacePowered(i, j, k + 1, 3) ? true : (l == 1 && world.isBlockFacePowered(i - 1, j, k, 4) ? true : l == 2 && world.isBlockFacePowered(i + 1, j, k, 5))));
}
public void a(World world, int i, int j, int k, Random random) {
boolean flag = this.g(world, i, j, k);
boolean flag = this.m(world, i, j, k);
List list = (List) b.get(world);
while (b.size() > 0 && world.getTime() - ((RedstoneUpdateInfo) b.get(0)).d > 60L) {
b.remove(0);
while (list != null && !list.isEmpty() && world.getTime() - ((RedstoneUpdateInfo) list.get(0)).d > 60L) {
list.remove(0);
}
// CraftBukkit start
@@ -115,7 +120,7 @@ public class BlockRedstoneTorch extends BlockTorch {
}
// CraftBukkit end
world.setTypeIdAndData(i, j, k, Block.REDSTONE_TORCH_OFF.id, world.getData(i, j, k));
world.setTypeAndData(i, j, k, Blocks.REDSTONE_TORCH_OFF, world.getData(i, j, k), 3);
if (this.a(world, i, j, k, true)) {
world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), "random.fizz", 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F);
@@ -124,7 +129,7 @@ public class BlockRedstoneTorch extends BlockTorch {
double d1 = (double) j + random.nextDouble() * 0.6D + 0.2D;
double d2 = (double) k + random.nextDouble() * 0.6D + 0.2D;
world.a("smoke", d0, d1, d2, 0.0D, 0.0D, 0.0D);
world.addParticle("smoke", d0, d1, d2, 0.0D, 0.0D, 0.0D);
}
}
}
@@ -139,24 +144,33 @@ public class BlockRedstoneTorch extends BlockTorch {
}
// CraftBukkit end
world.setTypeIdAndData(i, j, k, Block.REDSTONE_TORCH_ON.id, world.getData(i, j, k));
world.setTypeAndData(i, j, k, Blocks.REDSTONE_TORCH_ON, world.getData(i, j, k), 3);
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
super.doPhysics(world, i, j, k, l);
world.c(i, j, k, this.id, this.d());
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!this.b(world, i, j, k, block)) {
boolean flag = this.m(world, i, j, k);
if (this.isOn && flag || !this.isOn && !flag) {
world.a(i, j, k, this, this.a(world));
}
}
}
public boolean d(World world, int i, int j, int k, int l) {
return l == 0 ? this.a(world, i, j, k, l) : false;
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return l == 0 ? this.b(iblockaccess, i, j, k, l) : 0;
}
public int getDropType(int i, Random random, int j) {
return Block.REDSTONE_TORCH_ON.id;
public Item getDropType(int i, Random random, int j) {
return Item.getItemOf(Blocks.REDSTONE_TORCH_ON);
}
public boolean isPowerSource() {
return true;
}
public boolean c(Block block) {
return block == Blocks.REDSTONE_TORCH_OFF || block == Blocks.REDSTONE_TORCH_ON;
}
}

View File

@@ -12,36 +12,32 @@ public class BlockRedstoneWire extends Block {
private boolean a = true;
private Set b = new HashSet();
public BlockRedstoneWire(int i, int j) {
super(i, j, Material.ORIENTABLE);
public BlockRedstoneWire() {
super(Material.ORIENTABLE);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F);
}
public int a(int i, int j) {
return this.textureId;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 5;
}
public boolean canPlace(World world, int i, int j, int k) {
return world.e(i, j - 1, k) || world.getTypeId(i, j - 1, k) == Block.GLOWSTONE.id;
return World.a((IBlockAccess) world, i, j - 1, k) || world.getType(i, j - 1, k) == Blocks.GLOWSTONE;
}
private void g(World world, int i, int j, int k) {
private void e(World world, int i, int j, int k) {
this.a(world, i, j, k, i, j, k);
ArrayList arraylist = new ArrayList(this.b);
@@ -50,62 +46,68 @@ public class BlockRedstoneWire extends Block {
for (int l = 0; l < arraylist.size(); ++l) {
ChunkPosition chunkposition = (ChunkPosition) arraylist.get(l);
world.applyPhysics(chunkposition.x, chunkposition.y, chunkposition.z, this.id);
world.applyPhysics(chunkposition.x, chunkposition.y, chunkposition.z, this);
}
}
private void a(World world, int i, int j, int k, int l, int i1, int j1) {
int k1 = world.getData(i, j, k);
int l1 = 0;
byte b0 = 0;
int l1 = this.getPower(world, l, i1, j1, b0);
this.a = false;
boolean flag = world.isBlockIndirectlyPowered(i, j, k);
int i2 = world.getHighestNeighborSignal(i, j, k);
this.a = true;
int i2;
int j2;
int k2;
if (i2 > 0 && i2 > l1 - 1) {
l1 = i2;
}
if (flag) {
l1 = 15;
int j2 = 0;
for (int k2 = 0; k2 < 4; ++k2) {
int l2 = i;
int i3 = k;
if (k2 == 0) {
l2 = i - 1;
}
if (k2 == 1) {
++l2;
}
if (k2 == 2) {
i3 = k - 1;
}
if (k2 == 3) {
++i3;
}
if (l2 != l || i3 != j1) {
j2 = this.getPower(world, l2, j, i3, j2);
}
if (world.getType(l2, j, i3).r() && !world.getType(i, j + 1, k).r()) {
if ((l2 != l || i3 != j1) && j >= i1) {
j2 = this.getPower(world, l2, j + 1, i3, j2);
}
} else if (!world.getType(l2, j, i3).r() && (l2 != l || i3 != j1) && j <= i1) {
j2 = this.getPower(world, l2, j - 1, i3, j2);
}
}
if (j2 > l1) {
l1 = j2 - 1;
} else if (l1 > 0) {
--l1;
} else {
for (i2 = 0; i2 < 4; ++i2) {
j2 = i;
k2 = k;
if (i2 == 0) {
j2 = i - 1;
}
l1 = 0;
}
if (i2 == 1) {
++j2;
}
if (i2 == 2) {
k2 = k - 1;
}
if (i2 == 3) {
++k2;
}
if (j2 != l || j != i1 || k2 != j1) {
l1 = this.getPower(world, j2, j, k2, l1);
}
if (world.e(j2, j, k2) && !world.e(i, j + 1, k)) {
if (j2 != l || j + 1 != i1 || k2 != j1) {
l1 = this.getPower(world, j2, j + 1, k2, l1);
}
} else if (!world.e(j2, j, k2) && (j2 != l || j - 1 != i1 || k2 != j1)) {
l1 = this.getPower(world, j2, j - 1, k2, l1);
}
}
if (l1 > 0) {
--l1;
} else {
l1 = 0;
}
if (i2 > l1 - 1) {
l1 = i2;
}
// CraftBukkit start
@@ -116,165 +118,109 @@ public class BlockRedstoneWire extends Block {
l1 = event.getNewCurrent();
}
// CraftBukkit end
if (k1 != l1) {
world.suppressPhysics = true;
world.setData(i, j, k, l1);
world.b(i, j, k, i, j, k);
world.suppressPhysics = false;
for (i2 = 0; i2 < 4; ++i2) {
j2 = i;
k2 = k;
int l2 = j - 1;
if (i2 == 0) {
j2 = i - 1;
}
if (i2 == 1) {
++j2;
}
if (i2 == 2) {
k2 = k - 1;
}
if (i2 == 3) {
++k2;
}
if (world.e(j2, j, k2)) {
l2 += 2;
}
boolean flag1 = false;
int i3 = this.getPower(world, j2, j, k2, -1);
l1 = world.getData(i, j, k);
if (l1 > 0) {
--l1;
}
if (i3 >= 0 && i3 != l1) {
this.a(world, j2, j, k2, i, j, k);
}
i3 = this.getPower(world, j2, l2, k2, -1);
l1 = world.getData(i, j, k);
if (l1 > 0) {
--l1;
}
if (i3 >= 0 && i3 != l1) {
this.a(world, j2, l2, k2, i, j, k);
}
}
if (k1 < l1 || l1 == 0) {
this.b.add(new ChunkPosition(i, j, k));
this.b.add(new ChunkPosition(i - 1, j, k));
this.b.add(new ChunkPosition(i + 1, j, k));
this.b.add(new ChunkPosition(i, j - 1, k));
this.b.add(new ChunkPosition(i, j + 1, k));
this.b.add(new ChunkPosition(i, j, k - 1));
this.b.add(new ChunkPosition(i, j, k + 1));
}
world.setData(i, j, k, l1, 2);
this.b.add(new ChunkPosition(i, j, k));
this.b.add(new ChunkPosition(i - 1, j, k));
this.b.add(new ChunkPosition(i + 1, j, k));
this.b.add(new ChunkPosition(i, j - 1, k));
this.b.add(new ChunkPosition(i, j + 1, k));
this.b.add(new ChunkPosition(i, j, k - 1));
this.b.add(new ChunkPosition(i, j, k + 1));
}
}
private void h(World world, int i, int j, int k) {
if (world.getTypeId(i, j, k) == this.id) {
world.applyPhysics(i, j, k, this.id);
world.applyPhysics(i - 1, j, k, this.id);
world.applyPhysics(i + 1, j, k, this.id);
world.applyPhysics(i, j, k - 1, this.id);
world.applyPhysics(i, j, k + 1, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i, j + 1, k, this.id);
private void m(World world, int i, int j, int k) {
if (world.getType(i, j, k) == this) {
world.applyPhysics(i, j, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i, j, k - 1, this);
world.applyPhysics(i, j, k + 1, this);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i, j + 1, k, this);
}
}
public void onPlace(World world, int i, int j, int k) {
if (world.suppressPhysics) return; // CraftBukkit
super.onPlace(world, i, j, k);
if (!world.isStatic) {
this.g(world, i, j, k);
world.applyPhysics(i, j + 1, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
this.h(world, i - 1, j, k);
this.h(world, i + 1, j, k);
this.h(world, i, j, k - 1);
this.h(world, i, j, k + 1);
if (world.e(i - 1, j, k)) {
this.h(world, i - 1, j + 1, k);
this.e(world, i, j, k);
world.applyPhysics(i, j + 1, k, this);
world.applyPhysics(i, j - 1, k, this);
this.m(world, i - 1, j, k);
this.m(world, i + 1, j, k);
this.m(world, i, j, k - 1);
this.m(world, i, j, k + 1);
if (world.getType(i - 1, j, k).r()) {
this.m(world, i - 1, j + 1, k);
} else {
this.h(world, i - 1, j - 1, k);
this.m(world, i - 1, j - 1, k);
}
if (world.e(i + 1, j, k)) {
this.h(world, i + 1, j + 1, k);
if (world.getType(i + 1, j, k).r()) {
this.m(world, i + 1, j + 1, k);
} else {
this.h(world, i + 1, j - 1, k);
this.m(world, i + 1, j - 1, k);
}
if (world.e(i, j, k - 1)) {
this.h(world, i, j + 1, k - 1);
if (world.getType(i, j, k - 1).r()) {
this.m(world, i, j + 1, k - 1);
} else {
this.h(world, i, j - 1, k - 1);
this.m(world, i, j - 1, k - 1);
}
if (world.e(i, j, k + 1)) {
this.h(world, i, j + 1, k + 1);
if (world.getType(i, j, k + 1).r()) {
this.m(world, i, j + 1, k + 1);
} else {
this.h(world, i, j - 1, k + 1);
this.m(world, i, j - 1, k + 1);
}
}
}
public void remove(World world, int i, int j, int k) {
super.remove(world, i, j, k);
public void remove(World world, int i, int j, int k, Block block, int l) {
super.remove(world, i, j, k, block, l);
if (!world.isStatic) {
world.applyPhysics(i, j + 1, k, this.id);
world.applyPhysics(i, j - 1, k, this.id);
world.applyPhysics(i + 1, j, k, this.id);
world.applyPhysics(i - 1, j, k, this.id);
world.applyPhysics(i, j, k + 1, this.id);
world.applyPhysics(i, j, k - 1, this.id);
this.g(world, i, j, k);
this.h(world, i - 1, j, k);
this.h(world, i + 1, j, k);
this.h(world, i, j, k - 1);
this.h(world, i, j, k + 1);
if (world.e(i - 1, j, k)) {
this.h(world, i - 1, j + 1, k);
world.applyPhysics(i, j + 1, k, this);
world.applyPhysics(i, j - 1, k, this);
world.applyPhysics(i + 1, j, k, this);
world.applyPhysics(i - 1, j, k, this);
world.applyPhysics(i, j, k + 1, this);
world.applyPhysics(i, j, k - 1, this);
this.e(world, i, j, k);
this.m(world, i - 1, j, k);
this.m(world, i + 1, j, k);
this.m(world, i, j, k - 1);
this.m(world, i, j, k + 1);
if (world.getType(i - 1, j, k).r()) {
this.m(world, i - 1, j + 1, k);
} else {
this.h(world, i - 1, j - 1, k);
this.m(world, i - 1, j - 1, k);
}
if (world.e(i + 1, j, k)) {
this.h(world, i + 1, j + 1, k);
if (world.getType(i + 1, j, k).r()) {
this.m(world, i + 1, j + 1, k);
} else {
this.h(world, i + 1, j - 1, k);
this.m(world, i + 1, j - 1, k);
}
if (world.e(i, j, k - 1)) {
this.h(world, i, j + 1, k - 1);
if (world.getType(i, j, k - 1).r()) {
this.m(world, i, j + 1, k - 1);
} else {
this.h(world, i, j - 1, k - 1);
this.m(world, i, j - 1, k - 1);
}
if (world.e(i, j, k + 1)) {
this.h(world, i, j + 1, k + 1);
if (world.getType(i, j, k + 1).r()) {
this.m(world, i, j + 1, k + 1);
} else {
this.h(world, i, j - 1, k + 1);
this.m(world, i, j - 1, k + 1);
}
}
}
// CraftBukkit - private -> public
public int getPower(World world, int i, int j, int k, int l) {
if (world.getTypeId(i, j, k) != this.id) {
if (world.getType(i, j, k) != this) {
return l;
} else {
int i1 = world.getData(i, j, k);
@@ -283,62 +229,65 @@ public class BlockRedstoneWire extends Block {
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic) {
int i1 = world.getData(i, j, k);
boolean flag = this.canPlace(world, i, j, k);
if (!flag) {
this.b(world, i, j, k, i1, 0);
world.setTypeId(i, j, k, 0);
if (flag) {
this.e(world, i, j, k);
} else {
this.g(world, i, j, k);
this.b(world, i, j, k, 0, 0);
world.setAir(i, j, k);
}
super.doPhysics(world, i, j, k, l);
super.doPhysics(world, i, j, k, block);
}
}
public int getDropType(int i, Random random, int j) {
return Item.REDSTONE.id;
public Item getDropType(int i, Random random, int j) {
return Items.REDSTONE;
}
public boolean d(World world, int i, int j, int k, int l) {
return !this.a ? false : this.a(world, i, j, k, l);
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return !this.a ? 0 : this.b(iblockaccess, i, j, k, l);
}
public boolean a(IBlockAccess iblockaccess, int i, int j, int k, int l) {
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
if (!this.a) {
return false;
} else if (iblockaccess.getData(i, j, k) == 0) {
return false;
} else if (l == 1) {
return true;
return 0;
} else {
boolean flag = d(iblockaccess, i - 1, j, k, 1) || !iblockaccess.e(i - 1, j, k) && d(iblockaccess, i - 1, j - 1, k, -1);
boolean flag1 = d(iblockaccess, i + 1, j, k, 3) || !iblockaccess.e(i + 1, j, k) && d(iblockaccess, i + 1, j - 1, k, -1);
boolean flag2 = d(iblockaccess, i, j, k - 1, 2) || !iblockaccess.e(i, j, k - 1) && d(iblockaccess, i, j - 1, k - 1, -1);
boolean flag3 = d(iblockaccess, i, j, k + 1, 0) || !iblockaccess.e(i, j, k + 1) && d(iblockaccess, i, j - 1, k + 1, -1);
int i1 = iblockaccess.getData(i, j, k);
if (!iblockaccess.e(i, j + 1, k)) {
if (iblockaccess.e(i - 1, j, k) && d(iblockaccess, i - 1, j + 1, k, -1)) {
flag = true;
if (i1 == 0) {
return 0;
} else if (l == 1) {
return i1;
} else {
boolean flag = g(iblockaccess, i - 1, j, k, 1) || !iblockaccess.getType(i - 1, j, k).r() && g(iblockaccess, i - 1, j - 1, k, -1);
boolean flag1 = g(iblockaccess, i + 1, j, k, 3) || !iblockaccess.getType(i + 1, j, k).r() && g(iblockaccess, i + 1, j - 1, k, -1);
boolean flag2 = g(iblockaccess, i, j, k - 1, 2) || !iblockaccess.getType(i, j, k - 1).r() && g(iblockaccess, i, j - 1, k - 1, -1);
boolean flag3 = g(iblockaccess, i, j, k + 1, 0) || !iblockaccess.getType(i, j, k + 1).r() && g(iblockaccess, i, j - 1, k + 1, -1);
if (!iblockaccess.getType(i, j + 1, k).r()) {
if (iblockaccess.getType(i - 1, j, k).r() && g(iblockaccess, i - 1, j + 1, k, -1)) {
flag = true;
}
if (iblockaccess.getType(i + 1, j, k).r() && g(iblockaccess, i + 1, j + 1, k, -1)) {
flag1 = true;
}
if (iblockaccess.getType(i, j, k - 1).r() && g(iblockaccess, i, j + 1, k - 1, -1)) {
flag2 = true;
}
if (iblockaccess.getType(i, j, k + 1).r() && g(iblockaccess, i, j + 1, k + 1, -1)) {
flag3 = true;
}
}
if (iblockaccess.e(i + 1, j, k) && d(iblockaccess, i + 1, j + 1, k, -1)) {
flag1 = true;
}
if (iblockaccess.e(i, j, k - 1) && d(iblockaccess, i, j + 1, k - 1, -1)) {
flag2 = true;
}
if (iblockaccess.e(i, j, k + 1) && d(iblockaccess, i, j + 1, k + 1, -1)) {
flag3 = true;
}
return !flag2 && !flag1 && !flag && !flag3 && l >= 2 && l <= 5 ? i1 : (l == 2 && flag2 && !flag && !flag1 ? i1 : (l == 3 && flag3 && !flag && !flag1 ? i1 : (l == 4 && flag && !flag2 && !flag3 ? i1 : (l == 5 && flag1 && !flag2 && !flag3 ? i1 : 0))));
}
return !flag2 && !flag1 && !flag && !flag3 && l >= 2 && l <= 5 ? true : (l == 2 && flag2 && !flag && !flag1 ? true : (l == 3 && flag3 && !flag && !flag1 ? true : (l == 4 && flag && !flag2 && !flag3 ? true : l == 5 && flag1 && !flag2 && !flag3)));
}
}
@@ -346,35 +295,29 @@ public class BlockRedstoneWire extends Block {
return this.a;
}
public static boolean c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = iblockaccess.getTypeId(i, j, k);
public static boolean f(IBlockAccess iblockaccess, int i, int j, int k, int l) {
Block block = iblockaccess.getType(i, j, k);
if (i1 == Block.REDSTONE_WIRE.id) {
if (block == Blocks.REDSTONE_WIRE) {
return true;
} else if (i1 == 0) {
return false;
} else if (i1 != Block.DIODE_OFF.id && i1 != Block.DIODE_ON.id) {
return Block.byId[i1].isPowerSource() && l != -1;
} else if (!Blocks.DIODE_OFF.e(block)) {
return block.isPowerSource() && l != -1;
} else {
int j1 = iblockaccess.getData(i, j, k);
int i1 = iblockaccess.getData(i, j, k);
return l == (j1 & 3) || l == Direction.e[j1 & 3];
return l == (i1 & 3) || l == Direction.f[i1 & 3];
}
}
public static boolean d(IBlockAccess iblockaccess, int i, int j, int k, int l) {
if (c(iblockaccess, i, j, k, l)) {
public static boolean g(IBlockAccess iblockaccess, int i, int j, int k, int l) {
if (f(iblockaccess, i, j, k, l)) {
return true;
} else if (iblockaccess.getType(i, j, k) == Blocks.DIODE_ON) {
int i1 = iblockaccess.getData(i, j, k);
return l == (i1 & 3);
} else {
int i1 = iblockaccess.getTypeId(i, j, k);
if (i1 == Block.DIODE_ON.id) {
int j1 = iblockaccess.getData(i, j, k);
return l == (j1 & 3);
} else {
return false;
}
return false;
}
}
}

View File

@@ -4,9 +4,8 @@ import java.util.Random;
public class BlockReed extends Block {
protected BlockReed(int i, int j) {
super(i, Material.PLANT);
this.textureId = j;
protected BlockReed() {
super(Material.PLANT);
float f = 0.375F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f);
@@ -14,64 +13,69 @@ public class BlockReed extends Block {
}
public void a(World world, int i, int j, int k, Random random) {
if (world.isEmpty(i, j + 1, k)) {
int l;
if (world.getType(i, j - 1, k) == Blocks.SUGAR_CANE_BLOCK || this.e(world, i, j, k)) {
if (world.isEmpty(i, j + 1, k)) {
int l;
for (l = 1; world.getTypeId(i, j - l, k) == this.id; ++l) {
;
}
for (l = 1; world.getType(i, j - l, k) == this; ++l) {
;
}
if (l < 3) {
int i1 = world.getData(i, j, k);
if (l < 3) {
int i1 = world.getData(i, j, k);
if (i1 == 15) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this.id, 0); // CraftBukkit
world.setData(i, j, k, 0);
} else {
world.setData(i, j, k, i1 + 1);
if (i1 == 15) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
world.setData(i, j, k, 0, 4);
} else {
world.setData(i, j, k, i1 + 1, 4);
}
}
}
}
}
public boolean canPlace(World world, int i, int j, int k) {
int l = world.getTypeId(i, j - 1, k);
Block block = world.getType(i, j - 1, k);
return l == this.id ? true : (l != Block.GRASS.id && l != Block.DIRT.id && l != Block.SAND.id ? false : (world.getMaterial(i - 1, j - 1, k) == Material.WATER ? true : (world.getMaterial(i + 1, j - 1, k) == Material.WATER ? true : (world.getMaterial(i, j - 1, k - 1) == Material.WATER ? true : world.getMaterial(i, j - 1, k + 1) == Material.WATER))));
return block == this ? true : (block != Blocks.GRASS && block != Blocks.DIRT && block != Blocks.SAND ? false : (world.getType(i - 1, j - 1, k).getMaterial() == Material.WATER ? true : (world.getType(i + 1, j - 1, k).getMaterial() == Material.WATER ? true : (world.getType(i, j - 1, k - 1).getMaterial() == Material.WATER ? true : world.getType(i, j - 1, k + 1).getMaterial() == Material.WATER))));
}
public void doPhysics(World world, int i, int j, int k, int l) {
this.g(world, i, j, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
this.e(world, i, j, k);
}
protected final void g(World world, int i, int j, int k) {
if (!this.f(world, i, j, k)) {
protected final boolean e(World world, int i, int j, int k) {
if (!this.j(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
return false;
} else {
return true;
}
}
public boolean f(World world, int i, int j, int k) {
public boolean j(World world, int i, int j, int k) {
return this.canPlace(world, i, j, k);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public int getDropType(int i, Random random, int j) {
return Item.SUGAR_CANE.id;
public Item getDropType(int i, Random random, int j) {
return Items.SUGAR_CANE;
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int c() {
public int b() {
return 1;
}
}

View File

@@ -1,67 +0,0 @@
package net.minecraft.server;
import java.util.Random;
public class BlockSand extends Block {
public static boolean instaFall = false;
public BlockSand(int i, int j) {
super(i, j, Material.SAND);
}
public void onPlace(World world, int i, int j, int k) {
world.c(i, j, k, this.id, this.d());
}
public void doPhysics(World world, int i, int j, int k, int l) {
world.c(i, j, k, this.id, this.d());
}
public void a(World world, int i, int j, int k, Random random) {
this.h(world, i, j, k);
}
private void h(World world, int i, int j, int k) {
if (canFall(world, i, j - 1, k) && j >= 0) {
byte b0 = 32;
if (!instaFall && world.a(i - b0, j - b0, k - b0, i + b0, j + b0, k + b0)) {
if (!world.isStatic) {
// CraftBukkit - Change call to add data
EntityFallingBlock entityfallingblock = new EntityFallingBlock(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), this.id, world.getData(i, j, k));
world.addEntity(entityfallingblock);
}
} else {
world.setTypeId(i, j, k, 0);
while (canFall(world, i, j - 1, k) && j > 0) {
--j;
}
if (j > 0) {
world.setTypeId(i, j, k, this.id);
}
}
}
}
public int d() {
return 3;
}
public static boolean canFall(World world, int i, int j, int k) {
int l = world.getTypeId(i, j, k);
if (l == 0) {
return true;
} else if (l == Block.FIRE.id) {
return true;
} else {
Material material = Block.byId[l].material;
return material == Material.WATER ? true : material == Material.LAVA;
}
}
}

View File

@@ -1,146 +1,203 @@
package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.BlockChangeDelegate;
import org.bukkit.Bukkit;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.StructureGrowDelegate;
import org.bukkit.entity.Player;
import org.bukkit.event.world.StructureGrowEvent;
// CraftBukkit end
public class BlockSapling extends BlockFlower {
public class BlockSapling extends BlockPlant implements IBlockFragilePlantElement {
protected BlockSapling(int i, int j) {
super(i, j);
public static final String[] a = new String[] { "oak", "spruce", "birch", "jungle", "acacia", "roofed_oak"};
private static final IIcon[] b = new IIcon[a.length];
public static TreeType treeType; // CraftBukkit
protected BlockSapling() {
float f = 0.4F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
this.a(CreativeModeTab.c);
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
super.a(world, i, j, k, random);
if (world.getLightLevel(i, j + 1, k) >= 9 && random.nextInt(7) == 0) {
int l = world.getData(i, j, k);
if ((l & 8) == 0) {
world.setData(i, j, k, l | 8);
} else {
this.grow(world, i, j, k, random, false, null, null); // CraftBukkit - added bonemeal, player and itemstack
}
}
}
}
public int a(int i, int j) {
j &= 3;
return j == 1 ? 63 : (j == 2 ? 79 : (j == 3 ? 30 : super.a(i, j)));
}
// CraftBukkit - added bonemeal, player and itemstack
public void grow(World world, int i, int j, int k, Random random, boolean bonemeal, Player player, ItemStack itemstack) {
int l = world.getData(i, j, k) & 3;
int i1 = 0;
int j1 = 0;
// CraftBukkit start - records tree generation and calls StructureGrowEvent
StructureGrowDelegate delegate = new StructureGrowDelegate(world);
TreeType treeType = null;
TreeGenerator gen = null;
boolean grownTree = false;
boolean flag = false;
if (l == 1) {
treeType = TreeType.REDWOOD;
gen = new WorldGenTaiga2(false);
} else if (l == 2) {
treeType = TreeType.BIRCH;
gen = new WorldGenForest(false);
} else if (l == 3) {
for (i1 = 0; i1 >= -1; --i1) {
for (j1 = 0; j1 >= -1; --j1) {
if (this.f(world, i + i1, j, k + j1, 3) && this.f(world, i + i1 + 1, j, k + j1, 3) && this.f(world, i + i1, j, k + j1 + 1, 3) && this.f(world, i + i1 + 1, j, k + j1 + 1, 3)) {
treeType = TreeType.JUNGLE;
gen = new WorldGenMegaTree(false, 10 + random.nextInt(20), 3, 3);
flag = true;
break;
// CraftBukkit start
world.captureTreeGeneration = true;
// CraftBukkit end
this.grow(world, i, j, k, random);
// CraftBukkit start
world.captureTreeGeneration = false;
if (world.capturedBlockStates.size() > 0) {
TreeType treeType = BlockSapling.treeType;
BlockSapling.treeType = null;
Location location = new Location(world.getWorld(), i, j, k);
List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
world.capturedBlockStates.clear();
StructureGrowEvent event = null;
if (treeType != null) {
event = new StructureGrowEvent(location, treeType, false, null, blocks);
org.bukkit.Bukkit.getPluginManager().callEvent(event);
}
if (event == null || !event.isCancelled()) {
for (BlockState blockstate : blocks) {
blockstate.update(true);
}
}
}
if (gen != null) {
break;
}
// CraftBukkit end
}
}
}
if (gen == null) {
j1 = 0;
i1 = 0;
treeType = TreeType.SMALL_JUNGLE;
gen = new WorldGenTrees(false, 4 + random.nextInt(7), 3, 3, false);
}
public void grow(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k);
if ((l & 8) == 0) {
world.setData(i, j, k, l | 8, 4);
} else {
this.d(world, i, j, k, random);
}
}
public void d(World world, int i, int j, int k, Random random) {
int l = world.getData(i, j, k) & 7;
// CraftBukkit start - Turn ternary operator into if statement to set treeType
// Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true);
Object object;
if (random.nextInt(10) == 0) {
treeType = TreeType.BIG_TREE;
object = new WorldGenBigTree(true);
} else {
treeType = TreeType.TREE;
gen = new WorldGenTrees(false);
if (random.nextInt(10) == 0) {
treeType = TreeType.BIG_TREE;
gen = new WorldGenBigTree(false);
}
}
if (flag) {
world.setRawTypeId(i + i1, j, k + j1, 0);
world.setRawTypeId(i + i1 + 1, j, k + j1, 0);
world.setRawTypeId(i + i1, j, k + j1 + 1, 0);
world.setRawTypeId(i + i1 + 1, j, k + j1 + 1, 0);
} else {
world.setRawTypeId(i, j, k, 0);
}
grownTree = gen.generate(delegate, random, i + i1, j, k + j1);
if (grownTree) {
Location location = new Location(world.getWorld(), i, j, k);
StructureGrowEvent event = new StructureGrowEvent(location, treeType, bonemeal, player, delegate.getBlocks());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
grownTree = false;
} else {
for (BlockState state : event.getBlocks()) {
state.update(true);
}
if (event.isFromBonemeal() && itemstack != null) {
--itemstack.count;
}
}
}
if (!grownTree) {
if (flag) {
world.setRawTypeIdAndData(i + i1, j, k + j1, this.id, l);
world.setRawTypeIdAndData(i + i1 + 1, j, k + j1, this.id, l);
world.setRawTypeIdAndData(i + i1, j, k + j1 + 1, this.id, l);
world.setRawTypeIdAndData(i + i1 + 1, j, k + j1 + 1, this.id, l);
} else {
world.setRawTypeIdAndData(i, j, k, this.id, l);
}
object = new WorldGenTrees(true);
}
// CraftBukkit end
int i1 = 0;
int j1 = 0;
boolean flag = false;
switch (l) {
case 0:
default:
break;
case 1:
label78:
for (i1 = 0; i1 >= -1; --i1) {
for (j1 = 0; j1 >= -1; --j1) {
if (this.a(world, i + i1, j, k + j1, 1) && this.a(world, i + i1 + 1, j, k + j1, 1) && this.a(world, i + i1, j, k + j1 + 1, 1) && this.a(world, i + i1 + 1, j, k + j1 + 1, 1)) {
treeType = TreeType.MEGA_REDWOOD; // CraftBukkit
object = new WorldGenMegaTree(false, random.nextBoolean());
flag = true;
break label78;
}
}
}
if (!flag) {
j1 = 0;
i1 = 0;
treeType = TreeType.REDWOOD; // CraftBukkit
object = new WorldGenTaiga2(true);
}
break;
case 2:
treeType = TreeType.BIRCH; // CraftBukkit
object = new WorldGenForest(true, false);
break;
case 3:
label93:
for (i1 = 0; i1 >= -1; --i1) {
for (j1 = 0; j1 >= -1; --j1) {
if (this.a(world, i + i1, j, k + j1, 3) && this.a(world, i + i1 + 1, j, k + j1, 3) && this.a(world, i + i1, j, k + j1 + 1, 3) && this.a(world, i + i1 + 1, j, k + j1 + 1, 3)) {
treeType = TreeType.JUNGLE; // CraftBukkit
object = new WorldGenJungleTree(true, 10, 20, 3, 3);
flag = true;
break label93;
}
}
}
if (!flag) {
j1 = 0;
i1 = 0;
treeType = TreeType.SMALL_JUNGLE; // CraftBukkit
object = new WorldGenTrees(true, 4 + random.nextInt(7), 3, 3, false);
}
break;
case 4:
treeType = TreeType.ACACIA; // CraftBukkit
object = new WorldGenAcaciaTree(true);
break;
case 5:
label108:
for (i1 = 0; i1 >= -1; --i1) {
for (j1 = 0; j1 >= -1; --j1) {
if (this.a(world, i + i1, j, k + j1, 5) && this.a(world, i + i1 + 1, j, k + j1, 5) && this.a(world, i + i1, j, k + j1 + 1, 5) && this.a(world, i + i1 + 1, j, k + j1 + 1, 5)) {
object = new WorldGenForestTree(true);
treeType = TreeType.DARK_OAK; // CraftBukkit
flag = true;
break label108;
}
}
}
if (!flag) {
return;
}
}
Block block = Blocks.AIR;
if (flag) {
world.setTypeAndData(i + i1, j, k + j1, block, 0, 4);
world.setTypeAndData(i + i1 + 1, j, k + j1, block, 0, 4);
world.setTypeAndData(i + i1, j, k + j1 + 1, block, 0, 4);
world.setTypeAndData(i + i1 + 1, j, k + j1 + 1, block, 0, 4);
} else {
world.setTypeAndData(i, j, k, block, 0, 4);
}
if (!((WorldGenerator) object).generate(world, random, i + i1, j, k + j1)) {
if (flag) {
world.setTypeAndData(i + i1, j, k + j1, this, l, 4);
world.setTypeAndData(i + i1 + 1, j, k + j1, this, l, 4);
world.setTypeAndData(i + i1, j, k + j1 + 1, this, l, 4);
world.setTypeAndData(i + i1 + 1, j, k + j1 + 1, this, l, 4);
} else {
world.setTypeAndData(i, j, k, this, l, 4);
}
}
}
public boolean f(World world, int i, int j, int k, int l) {
return world.getTypeId(i, j, k) == this.id && (world.getData(i, j, k) & 3) == l;
public boolean a(World world, int i, int j, int k, int l) {
return world.getType(i, j, k) == this && (world.getData(i, j, k) & 7) == l;
}
protected int getDropData(int i) {
return i & 3;
public int getDropData(int i) {
return MathHelper.a(i & 7, 0, 5);
}
// CraftBukkit start
public interface TreeGenerator {
public boolean a(World world, Random random, int i, int j, int k);
public boolean generate(BlockChangeDelegate world, Random random, int i, int j, int k);
public boolean a(World world, int i, int j, int k, boolean flag) {
return true;
}
public boolean a(World world, Random random, int i, int j, int k) {
return (double) world.random.nextFloat() < 0.45D;
}
public void b(World world, Random random, int i, int j, int k) {
this.grow(world, i, j, k, random);
}
// CraftBukkit end
}

View File

@@ -9,10 +9,9 @@ public class BlockSign extends BlockContainer {
private Class a;
private boolean b;
protected BlockSign(int i, Class oclass, boolean flag) {
super(i, Material.WOOD);
protected BlockSign(Class oclass, boolean flag) {
super(Material.WOOD);
this.b = flag;
this.textureId = 4;
this.a = oclass;
float f = 0.25F;
float f1 = 1.0F;
@@ -20,7 +19,7 @@ public class BlockSign extends BlockContainer {
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
@@ -52,11 +51,11 @@ public class BlockSign extends BlockContainer {
}
}
public int c() {
public int b() {
return -1;
}
public boolean b() {
public boolean d() {
return false;
}
@@ -64,11 +63,11 @@ public class BlockSign extends BlockContainer {
return true;
}
public boolean a() {
public boolean c() {
return false;
}
public TileEntity a_() {
public TileEntity a(World world, int i) {
try {
return (TileEntity) this.a.newInstance();
} catch (Exception exception) {
@@ -76,51 +75,51 @@ public class BlockSign extends BlockContainer {
}
}
public int getDropType(int i, Random random, int j) {
return Item.SIGN.id;
public Item getDropType(int i, Random random, int j) {
return Items.SIGN;
}
public void doPhysics(World world, int i, int j, int k, int l) {
public void doPhysics(World world, int i, int j, int k, Block block) {
boolean flag = false;
if (this.b) {
if (!world.getMaterial(i, j - 1, k).isBuildable()) {
if (!world.getType(i, j - 1, k).getMaterial().isBuildable()) {
flag = true;
}
} else {
int i1 = world.getData(i, j, k);
int l = world.getData(i, j, k);
flag = true;
if (i1 == 2 && world.getMaterial(i, j, k + 1).isBuildable()) {
if (l == 2 && world.getType(i, j, k + 1).getMaterial().isBuildable()) {
flag = false;
}
if (i1 == 3 && world.getMaterial(i, j, k - 1).isBuildable()) {
if (l == 3 && world.getType(i, j, k - 1).getMaterial().isBuildable()) {
flag = false;
}
if (i1 == 4 && world.getMaterial(i + 1, j, k).isBuildable()) {
if (l == 4 && world.getType(i + 1, j, k).getMaterial().isBuildable()) {
flag = false;
}
if (i1 == 5 && world.getMaterial(i - 1, j, k).isBuildable()) {
if (l == 5 && world.getType(i - 1, j, k).getMaterial().isBuildable()) {
flag = false;
}
}
if (flag) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
}
super.doPhysics(world, i, j, k, l);
super.doPhysics(world, i, j, k, block);
// CraftBukkit start
if (net.minecraft.server.Block.byId[l] != null && net.minecraft.server.Block.byId[l].isPowerSource()) {
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
int power = block.getBlockPower();
if (block != null && block.isPowerSource()) {
org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i, j, k);
int power = bukkitBlock.getBlockPower();
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, power, power);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, power, power);
world.getServer().getPluginManager().callEvent(eventRedstone);
}
// CraftBukkit end

View File

@@ -0,0 +1,244 @@
package net.minecraft.server;
import java.util.Iterator;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.util.BlockStateListPopulator;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
// CraftBukkit end
public class BlockSkull extends BlockContainer {
protected BlockSkull() {
super(Material.ORIENTABLE);
this.a(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F);
}
public int b() {
return -1;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k) & 7;
switch (l) {
case 1:
default:
this.a(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F);
break;
case 2:
this.a(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F);
break;
case 3:
this.a(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F);
break;
case 4:
this.a(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F);
break;
case 5:
this.a(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F);
}
}
public AxisAlignedBB a(World world, int i, int j, int k) {
this.updateShape(world, i, j, k);
return super.a(world, i, j, k);
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 2.5D) & 3;
world.setData(i, j, k, l, 2);
}
public TileEntity a(World world, int i) {
return new TileEntitySkull();
}
public int getDropData(World world, int i, int j, int k) {
TileEntity tileentity = world.getTileEntity(i, j, k);
return tileentity != null && tileentity instanceof TileEntitySkull ? ((TileEntitySkull) tileentity).getSkullType() : super.getDropData(world, i, j, k);
}
public int getDropData(int i) {
return i;
}
// CraftBukkit start - Special case dropping so we can get info from the tile entity
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (world.random.nextFloat() < f) {
ItemStack itemstack = new ItemStack(Items.SKULL, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) {
itemstack.setTag(new NBTTagCompound());
NBTTagCompound nbttagcompound = new NBTTagCompound();
GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile());
itemstack.getTag().set("SkullOwner", nbttagcompound);
}
this.a(world, i, j, k, itemstack);
}
}
// CraftBukkit end
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (entityhuman.abilities.canInstantlyBuild) {
l |= 8;
world.setData(i, j, k, l, 4);
}
super.a(world, i, j, k, l, entityhuman);
}
public void remove(World world, int i, int j, int k, Block block, int l) {
if (!world.isStatic) {
// CraftBukkit start - Drop item in code above, not here
// if ((l & 8) == 0) {
if (false) {
// CraftBukkit end
ItemStack itemstack = new ItemStack(Items.SKULL, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) {
itemstack.setTag(new NBTTagCompound());
NBTTagCompound nbttagcompound = new NBTTagCompound();
GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile());
itemstack.getTag().set("SkullOwner", nbttagcompound);
}
this.a(world, i, j, k, itemstack);
}
super.remove(world, i, j, k, block, l);
}
}
public Item getDropType(int i, Random random, int j) {
return Items.SKULL;
}
public void a(World world, int i, int j, int k, TileEntitySkull tileentityskull) {
if (tileentityskull.getSkullType() == 1 && j >= 2 && world.difficulty != EnumDifficulty.PEACEFUL && !world.isStatic) {
int l;
EntityWither entitywither;
Iterator iterator;
EntityHuman entityhuman;
int i1;
for (l = -2; l <= 0; ++l) {
if (world.getType(i, j - 1, k + l) == Blocks.SOUL_SAND && world.getType(i, j - 1, k + l + 1) == Blocks.SOUL_SAND && world.getType(i, j - 2, k + l + 1) == Blocks.SOUL_SAND && world.getType(i, j - 1, k + l + 2) == Blocks.SOUL_SAND && this.a(world, i, j, k + l, 1) && this.a(world, i, j, k + l + 1, 1) && this.a(world, i, j, k + l + 2, 1)) {
// CraftBukkit start - Use BlockStateListPopulator
BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld());
world.setData(i, j, k + l, 8, 2);
world.setData(i, j, k + l + 1, 8, 2);
world.setData(i, j, k + l + 2, 8, 2);
blockList.setTypeAndData(i, j, k + l, getById(0), 0, 2);
blockList.setTypeAndData(i, j, k + l + 1, getById(0), 0, 2);
blockList.setTypeAndData(i, j, k + l + 2, getById(0), 0, 2);
blockList.setTypeAndData(i, j - 1, k + l, getById(0), 0, 2);
blockList.setTypeAndData(i, j - 1, k + l + 1, getById(0), 0, 2);
blockList.setTypeAndData(i, j - 1, k + l + 2, getById(0), 0, 2);
blockList.setTypeAndData(i, j - 2, k + l + 1, getById(0), 0, 2);
if (!world.isStatic) {
entitywither = new EntityWither(world);
entitywither.setPositionRotation((double) i + 0.5D, (double) j - 1.45D, (double) (k + l) + 1.5D, 90.0F, 0.0F);
entitywither.aM = 90.0F;
entitywither.bZ();
if (world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) {
if (!world.isStatic) {
iterator = world.a(EntityHuman.class, entitywither.boundingBox.grow(50.0D, 50.0D, 50.0D)).iterator();
while (iterator.hasNext()) {
entityhuman = (EntityHuman) iterator.next();
entityhuman.a((Statistic) AchievementList.I);
}
}
blockList.updateList();
}
}
for (i1 = 0; i1 < 120; ++i1) {
world.addParticle("snowballpoof", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 3.9D, (double) (k + l + 1) + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
}
// CraftBukkit end
return;
}
}
for (l = -2; l <= 0; ++l) {
if (world.getType(i + l, j - 1, k) == Blocks.SOUL_SAND && world.getType(i + l + 1, j - 1, k) == Blocks.SOUL_SAND && world.getType(i + l + 1, j - 2, k) == Blocks.SOUL_SAND && world.getType(i + l + 2, j - 1, k) == Blocks.SOUL_SAND && this.a(world, i + l, j, k, 1) && this.a(world, i + l + 1, j, k, 1) && this.a(world, i + l + 2, j, k, 1)) {
// CraftBukkit start - Use BlockStateListPopulator
BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld());
world.setData(i + l, j, k, 8, 2);
world.setData(i + l + 1, j, k, 8, 2);
world.setData(i + l + 2, j, k, 8, 2);
blockList.setTypeAndData(i + l, j, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l + 1, j, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l + 2, j, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l, j - 1, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l + 1, j - 1, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l + 2, j - 1, k, getById(0), 0, 2);
blockList.setTypeAndData(i + l + 1, j - 2, k, getById(0), 0, 2);
if (!world.isStatic) {
entitywither = new EntityWither(world);
entitywither.setPositionRotation((double) (i + l) + 1.5D, (double) j - 1.45D, (double) k + 0.5D, 0.0F, 0.0F);
entitywither.bZ();
if (world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) {
if (!world.isStatic) {
iterator = world.a(EntityHuman.class, entitywither.boundingBox.grow(50.0D, 50.0D, 50.0D)).iterator();
while (iterator.hasNext()) {
entityhuman = (EntityHuman) iterator.next();
entityhuman.a((Statistic) AchievementList.I);
}
}
blockList.updateList();
}
}
for (i1 = 0; i1 < 120; ++i1) {
world.addParticle("snowballpoof", (double) (i + l + 1) + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 3.9D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
}
// CraftBukkit end
return;
}
}
}
}
private boolean a(World world, int i, int j, int k, int l) {
if (world.getType(i, j, k) != this) {
return false;
} else {
TileEntity tileentity = world.getTileEntity(i, j, k);
return tileentity != null && tileentity instanceof TileEntitySkull ? ((TileEntitySkull) tileentity).getSkullType() == l : false;
}
}
}

View File

@@ -1,52 +1,61 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory;
public class BlockSnow extends Block {
protected BlockSnow(int i, int j) {
super(i, j, Material.SNOW_LAYER);
protected BlockSnow() {
super(Material.PACKED_ICE);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
this.a(true);
this.a(CreativeModeTab.c);
this.b(0);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
int l = world.getData(i, j, k) & 7;
float f = 0.125F;
return l >= 3 ? AxisAlignedBB.b((double) i + this.minX, (double) j + this.minY, (double) k + this.minZ, (double) i + this.maxX, (double) ((float) j + 0.5F), (double) k + this.maxZ) : null;
return AxisAlignedBB.a((double) i + this.minX, (double) j + this.minY, (double) k + this.minZ, (double) i + this.maxX, (double) ((float) j + (float) l * f), (double) k + this.maxZ);
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public void g() {
this.b(0);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k) & 7;
float f = (float) (2 * (1 + l)) / 16.0F;
this.b(iblockaccess.getData(i, j, k));
}
protected void b(int i) {
int j = i & 7;
float f = (float) (2 * (1 + j)) / 16.0F;
this.a(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
}
public boolean canPlace(World world, int i, int j, int k) {
int l = world.getTypeId(i, j - 1, k);
Block block = world.getType(i, j - 1, k);
return l != 0 && (l == Block.LEAVES.id || Block.byId[l].a()) ? world.getMaterial(i, j - 1, k).isSolid() : false;
return block != Blocks.ICE && block != Blocks.PACKED_ICE ? (block.getMaterial() == Material.LEAVES ? true : (block == this && (world.getData(i, j - 1, k) & 7) == 7 ? true : block.c() && block.material.isSolid())) : false;
}
public void doPhysics(World world, int i, int j, int k, int l) {
this.g(world, i, j, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
this.m(world, i, j, k);
}
private boolean g(World world, int i, int j, int k) {
private boolean m(World world, int i, int j, int k) {
if (!this.canPlace(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setRawTypeId(i, j, k, 0); // CraftBukkit
world.notify(i, j, k); // CraftBukkit - Notify clients of the reversion
world.setAir(i, j, k);
return false;
} else {
return true;
@@ -54,21 +63,15 @@ public class BlockSnow extends Block {
}
public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
int i1 = Item.SNOW_BALL.id;
float f = 0.7F;
double d0 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
double d1 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
double d2 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D;
EntityItem entityitem = new EntityItem(world, (double) i + d0, (double) j + d1, (double) k + d2, new ItemStack(i1, 1, 0));
int i1 = l & 7;
entityitem.pickupDelay = 10;
world.addEntity(entityitem);
world.setTypeId(i, j, k, 0);
entityhuman.a(StatisticList.C[this.id], 1);
this.a(world, i, j, k, new ItemStack(Items.SNOW_BALL, i1 + 1, 0));
world.setAir(i, j, k);
entityhuman.a(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)], 1);
}
public int getDropType(int i, Random random, int j) {
return Item.SNOW_BALL.id;
public Item getDropType(int i, Random random, int j) {
return Items.SNOW_BALL;
}
public int a(Random random) {
@@ -76,15 +79,15 @@ public class BlockSnow extends Block {
}
public void a(World world, int i, int j, int k, Random random) {
if (world.a(EnumSkyBlock.BLOCK, i, j, k) > 11) {
if (world.b(EnumSkyBlock.BLOCK, i, j, k) > 11) {
// CraftBukkit start
if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(i, j, k), 0).isCancelled()) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(i, j, k), Blocks.AIR).isCancelled()) {
return;
}
// CraftBukkit end
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setTypeId(i, j, k, 0);
world.setAir(i, j, k);
}
}
}

View File

@@ -3,53 +3,59 @@ package net.minecraft.server;
import java.util.Random;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.craftbukkit.event.CraftEventFactory;
// CraftBukkit end
public class BlockSoil extends Block {
protected BlockSoil(int i) {
super(i, Material.EARTH);
this.textureId = 87;
protected BlockSoil() {
super(Material.EARTH);
this.a(true);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F);
this.f(255);
this.g(255);
}
public AxisAlignedBB e(World world, int i, int j, int k) {
return AxisAlignedBB.b((double) (i + 0), (double) (j + 0), (double) (k + 0), (double) (i + 1), (double) (j + 1), (double) (k + 1));
public AxisAlignedBB a(World world, int i, int j, int k) {
return AxisAlignedBB.a((double) (i + 0), (double) (j + 0), (double) (k + 0), (double) (i + 1), (double) (j + 1), (double) (k + 1));
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public int a(int i, int j) {
return i == 1 && j > 0 ? this.textureId - 1 : (i == 1 ? this.textureId : 2);
}
public void a(World world, int i, int j, int k, Random random) {
if (!this.h(world, i, j, k) && !world.y(i, j + 1, k)) {
if (!this.m(world, i, j, k) && !world.isRainingAt(i, j + 1, k)) {
int l = world.getData(i, j, k);
if (l > 0) {
world.setData(i, j, k, l - 1);
} else if (!this.g(world, i, j, k)) {
world.setTypeId(i, j, k, Block.DIRT.id);
world.setData(i, j, k, l - 1, 2);
} else if (!this.e(world, i, j, k)) {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
if (CraftEventFactory.callBlockFadeEvent(block, Blocks.DIRT).isCancelled()) {
return;
}
// CraftBukkit end
world.setTypeUpdate(i, j, k, Blocks.DIRT);
}
} else {
world.setData(i, j, k, 7);
world.setData(i, j, k, 7, 2);
}
}
public void a(World world, int i, int j, int k, Entity entity, float f) {
if (world.random.nextFloat() < f - 0.5F) {
// CraftBukkit start - Interact Soil
if (!world.isStatic && world.random.nextFloat() < f - 0.5F) {
if (!(entity instanceof EntityHuman) && !world.getGameRules().getBoolean("mobGriefing")) {
return;
}
// CraftBukkit start - Interact soil
org.bukkit.event.Cancellable cancellable;
if (entity instanceof EntityHuman) {
cancellable = CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
@@ -61,20 +67,23 @@ public class BlockSoil extends Block {
if (cancellable.isCancelled()) {
return;
}
// CraftBukkit end
world.setTypeId(i, j, k, Block.DIRT.id);
if (CraftEventFactory.callEntityChangeBlockEvent(entity, i, j, k, Blocks.DIRT, 0).isCancelled()) {
return;
}
// CraftBukkit end
world.setTypeUpdate(i, j, k, Blocks.DIRT);
}
}
private boolean g(World world, int i, int j, int k) {
private boolean e(World world, int i, int j, int k) {
byte b0 = 0;
for (int l = i - b0; l <= i + b0; ++l) {
for (int i1 = k - b0; i1 <= k + b0; ++i1) {
int j1 = world.getTypeId(l, j + 1, i1);
Block block = world.getType(l, j + 1, i1);
if (j1 == Block.CROPS.id || j1 == Block.MELON_STEM.id || j1 == Block.PUMPKIN_STEM.id) {
if (block == Blocks.CROPS || block == Blocks.MELON_STEM || block == Blocks.PUMPKIN_STEM || block == Blocks.POTATOES || block == Blocks.CARROTS) {
return true;
}
}
@@ -83,11 +92,11 @@ public class BlockSoil extends Block {
return false;
}
private boolean h(World world, int i, int j, int k) {
private boolean m(World world, int i, int j, int k) {
for (int l = i - 4; l <= i + 4; ++l) {
for (int i1 = j; i1 <= j + 1; ++i1) {
for (int j1 = k - 4; j1 <= k + 4; ++j1) {
if (world.getMaterial(l, i1, j1) == Material.WATER) {
if (world.getType(l, i1, j1).getMaterial() == Material.WATER) {
return true;
}
}
@@ -97,16 +106,16 @@ public class BlockSoil extends Block {
return false;
}
public void doPhysics(World world, int i, int j, int k, int l) {
super.doPhysics(world, i, j, k, l);
Material material = world.getMaterial(i, j + 1, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
super.doPhysics(world, i, j, k, block);
Material material = world.getType(i, j + 1, k).getMaterial();
if (material.isBuildable()) {
world.setTypeId(i, j, k, Block.DIRT.id);
world.setTypeUpdate(i, j, k, Blocks.DIRT);
}
}
public int getDropType(int i, Random random, int j) {
return Block.DIRT.getDropType(0, random, j);
public Item getDropType(int i, Random random, int j) {
return Blocks.DIRT.getDropType(0, random, j);
}
}

View File

@@ -2,37 +2,30 @@ package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockIgniteEvent; // CraftBukkit
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockStationary extends BlockFluids {
protected BlockStationary(int i, Material material) {
super(i, material);
protected BlockStationary(Material material) {
super(material);
this.a(false);
if (material == Material.LAVA) {
this.a(true);
}
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
return this.material != Material.LAVA;
}
public void doPhysics(World world, int i, int j, int k, int l) {
super.doPhysics(world, i, j, k, l);
if (world.getTypeId(i, j, k) == this.id) {
this.i(world, i, j, k);
public void doPhysics(World world, int i, int j, int k, Block block) {
super.doPhysics(world, i, j, k, block);
if (world.getType(i, j, k) == this) {
this.n(world, i, j, k);
}
}
private void i(World world, int i, int j, int k) {
private void n(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
world.suppressPhysics = true;
world.setRawTypeIdAndData(i, j, k, this.id - 1, l);
world.b(i, j, k, i, j, k);
world.c(i, j, k, this.id - 1, this.d());
world.suppressPhysics = false;
world.setTypeAndData(i, j, k, Block.getById(Block.getId(this) - 1), l, 2);
world.a(i, j, k, Block.getById(Block.getId(this) - 1), this.a(world));
}
public void a(World world, int i, int j, int k, Random random) {
@@ -40,62 +33,61 @@ public class BlockStationary extends BlockFluids {
int l = random.nextInt(3);
int i1;
int j1;
// CraftBukkit start - prevent lava putting something on fire.
org.bukkit.World bworld = world.getWorld();
BlockIgniteEvent.IgniteCause igniteCause = BlockIgniteEvent.IgniteCause.LAVA;
// CraftBukkit start - Prevent lava putting something on fire, remember igniter block coords
int x = i;
int y = j;
int z = k;
// CraftBukkit end
for (i1 = 0; i1 < l; ++i1) {
i += random.nextInt(3) - 1;
++j;
k += random.nextInt(3) - 1;
j1 = world.getTypeId(i, j, k);
if (j1 == 0) {
if (this.j(world, i - 1, j, k) || this.j(world, i + 1, j, k) || this.j(world, i, j, k - 1) || this.j(world, i, j, k + 1) || this.j(world, i, j - 1, k) || this.j(world, i, j + 1, k)) {
// CraftBukkit start - prevent lava putting something on fire.
org.bukkit.block.Block block = bworld.getBlockAt(i, j, k);
if (block.getTypeId() != Block.FIRE.id) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEvent(new BlockIgniteEvent(block, igniteCause, null)).isCancelled()) {
Block block = world.getType(i, j, k);
if (block.material == Material.AIR) {
if (this.o(world, i - 1, j, k) || this.o(world, i + 1, j, k) || this.o(world, i, j, k - 1) || this.o(world, i, j, k + 1) || this.o(world, i, j - 1, k) || this.o(world, i, j + 1, k)) {
// CraftBukkit start - Prevent lava putting something on fire
if (world.getType(i, j, k) != Blocks.FIRE) {
if (CraftEventFactory.callBlockIgniteEvent(world, i, j, k, x, y, z).isCancelled()) {
continue;
}
}
// CraftBukkit end
world.setTypeId(i, j, k, Block.FIRE.id);
world.setTypeUpdate(i, j, k, Blocks.FIRE);
return;
}
} else if (Block.byId[j1].material.isSolid()) {
} else if (block.material.isSolid()) {
return;
}
}
if (l == 0) {
i1 = i;
j1 = k;
int j1 = k;
for (int k1 = 0; k1 < 3; ++k1) {
i = i1 + random.nextInt(3) - 1;
k = j1 + random.nextInt(3) - 1;
if (world.isEmpty(i, j + 1, k) && this.j(world, i, j, k)) {
// CraftBukkit start - prevent lava putting something on fire.
org.bukkit.block.Block block = bworld.getBlockAt(i, j + 1, k);
if (block.getTypeId() != Block.FIRE.id) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEvent(new BlockIgniteEvent(block, igniteCause, null)).isCancelled()) {
if (world.isEmpty(i, j + 1, k) && this.o(world, i, j, k)) {
// CraftBukkit start - Prevent lava putting something on fire
if (world.getType(i, j + 1, k) != Blocks.FIRE) {
if (CraftEventFactory.callBlockIgniteEvent(world, i, j + 1, k, x, y, z).isCancelled()) {
continue;
}
}
// CraftBukkit end
world.setTypeId(i, j + 1, k, Block.FIRE.id);
world.setTypeUpdate(i, j + 1, k, Blocks.FIRE);
}
}
}
}
}
private boolean j(World world, int i, int j, int k) {
return world.getMaterial(i, j, k).isBurnable();
private boolean o(World world, int i, int j, int k) {
return world.getType(i, j, k).getMaterial().isBurnable();
}
}

View File

@@ -2,48 +2,50 @@ package net.minecraft.server;
import java.util.Random;
public class BlockStem extends BlockFlower {
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
private Block blockFruit;
public class BlockStem extends BlockPlant implements IBlockFragilePlantElement {
protected BlockStem(int i, Block block) {
super(i, 111);
private final Block blockFruit;
protected BlockStem(Block block) {
this.blockFruit = block;
this.a(true);
float f = 0.125F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
this.a((CreativeModeTab) null);
}
protected boolean d(int i) {
return i == Block.SOIL.id;
protected boolean a(Block block) {
return block == Blocks.SOIL;
}
public void a(World world, int i, int j, int k, Random random) {
super.a(world, i, j, k, random);
if (world.getLightLevel(i, j + 1, k) >= 9) {
float f = this.i(world, i, j, k);
float f = this.n(world, i, j, k);
if (random.nextInt((int) (25.0F / f) + 1) == 0) {
int l = world.getData(i, j, k);
if (l < 7) {
++l;
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this.id, l); // CraftBukkit
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
} else {
if (world.getTypeId(i - 1, j, k) == this.blockFruit.id) {
if (world.getType(i - 1, j, k) == this.blockFruit) {
return;
}
if (world.getTypeId(i + 1, j, k) == this.blockFruit.id) {
if (world.getType(i + 1, j, k) == this.blockFruit) {
return;
}
if (world.getTypeId(i, j, k - 1) == this.blockFruit.id) {
if (world.getType(i, j, k - 1) == this.blockFruit) {
return;
}
if (world.getTypeId(i, j, k + 1) == this.blockFruit.id) {
if (world.getType(i, j, k + 1) == this.blockFruit) {
return;
}
@@ -67,47 +69,53 @@ public class BlockStem extends BlockFlower {
++k1;
}
int l1 = world.getTypeId(j1, j - 1, k1);
Block block = world.getType(j1, j - 1, k1);
if (world.getTypeId(j1, j, k1) == 0 && (l1 == Block.SOIL.id || l1 == Block.DIRT.id || l1 == Block.GRASS.id)) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, j1, j, k1, this.blockFruit.id, 0); // CraftBukkit
if (world.getType(j1, j, k1).material == Material.AIR && (block == Blocks.SOIL || block == Blocks.DIRT || block == Blocks.GRASS)) {
CraftEventFactory.handleBlockGrowEvent(world, j1, j, k1, this.blockFruit, 0); // CraftBukkit
}
}
}
}
}
public void g(World world, int i, int j, int k) {
world.setData(i, j, k, 7);
public void m(World world, int i, int j, int k) {
int l = world.getData(i, j, k) + MathHelper.nextInt(world.random, 2, 5);
if (l > 7) {
l = 7;
}
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
}
private float i(World world, int i, int j, int k) {
private float n(World world, int i, int j, int k) {
float f = 1.0F;
int l = world.getTypeId(i, j, k - 1);
int i1 = world.getTypeId(i, j, k + 1);
int j1 = world.getTypeId(i - 1, j, k);
int k1 = world.getTypeId(i + 1, j, k);
int l1 = world.getTypeId(i - 1, j, k - 1);
int i2 = world.getTypeId(i + 1, j, k - 1);
int j2 = world.getTypeId(i + 1, j, k + 1);
int k2 = world.getTypeId(i - 1, j, k + 1);
boolean flag = j1 == this.id || k1 == this.id;
boolean flag1 = l == this.id || i1 == this.id;
boolean flag2 = l1 == this.id || i2 == this.id || j2 == this.id || k2 == this.id;
Block block = world.getType(i, j, k - 1);
Block block1 = world.getType(i, j, k + 1);
Block block2 = world.getType(i - 1, j, k);
Block block3 = world.getType(i + 1, j, k);
Block block4 = world.getType(i - 1, j, k - 1);
Block block5 = world.getType(i + 1, j, k - 1);
Block block6 = world.getType(i + 1, j, k + 1);
Block block7 = world.getType(i - 1, j, k + 1);
boolean flag = block2 == this || block3 == this;
boolean flag1 = block == this || block1 == this;
boolean flag2 = block4 == this || block5 == this || block6 == this || block7 == this;
for (int l2 = i - 1; l2 <= i + 1; ++l2) {
for (int i3 = k - 1; i3 <= k + 1; ++i3) {
int j3 = world.getTypeId(l2, j - 1, i3);
for (int l = i - 1; l <= i + 1; ++l) {
for (int i1 = k - 1; i1 <= k + 1; ++i1) {
Block block8 = world.getType(l, j - 1, i1);
float f1 = 0.0F;
if (j3 == Block.SOIL.id) {
if (block8 == Blocks.SOIL) {
f1 = 1.0F;
if (world.getData(l2, j - 1, i3) > 0) {
if (world.getData(l, j - 1, i1) > 0) {
f1 = 3.0F;
}
}
if (l2 != i || i3 != k) {
if (l != i || i1 != k) {
f1 /= 4.0F;
}
@@ -122,11 +130,7 @@ public class BlockStem extends BlockFlower {
return f;
}
public int a(int i, int j) {
return this.textureId;
}
public void f() {
public void g() {
float f = 0.125F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
@@ -139,7 +143,7 @@ public class BlockStem extends BlockFlower {
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, (float) this.maxY, 0.5F + f);
}
public int c() {
public int b() {
return 19;
}
@@ -148,38 +152,39 @@ public class BlockStem extends BlockFlower {
if (!world.isStatic) {
Item item = null;
if (this.blockFruit == Block.PUMPKIN) {
item = Item.PUMPKIN_SEEDS;
if (this.blockFruit == Blocks.PUMPKIN) {
item = Items.PUMPKIN_SEEDS;
}
if (this.blockFruit == Block.MELON) {
item = Item.MELON_SEEDS;
if (this.blockFruit == Blocks.MELON) {
item = Items.MELON_SEEDS;
}
for (int j1 = 0; j1 < 3; ++j1) {
if (world.random.nextInt(15) <= l) {
float f1 = 0.7F;
float f2 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
float f3 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
float f4 = world.random.nextFloat() * f1 + (1.0F - f1) * 0.5F;
EntityItem entityitem = new EntityItem(world, (double) ((float) i + f2), (double) ((float) j + f3), (double) ((float) k + f4), new ItemStack(item));
entityitem.pickupDelay = 10;
world.addEntity(entityitem);
this.a(world, i, j, k, new ItemStack(item));
}
}
}
}
public int getDropType(int i, Random random, int j) {
if (i == 7) {
;
}
return -1;
public Item getDropType(int i, Random random, int j) {
return null;
}
public int a(Random random) {
return 1;
}
public boolean a(World world, int i, int j, int k, boolean flag) {
return world.getData(i, j, k) != 7;
}
public boolean a(World world, Random random, int i, int j, int k) {
return true;
}
public void b(World world, Random random, int i, int j, int k) {
this.m(world, i, j, k);
}
}

View File

@@ -1,73 +0,0 @@
package net.minecraft.server;
import java.util.Random;
public class BlockTNT extends Block {
public BlockTNT(int i, int j) {
super(i, j, Material.TNT);
}
public int a(int i) {
return i == 0 ? this.textureId + 2 : (i == 1 ? this.textureId + 1 : this.textureId);
}
public void onPlace(World world, int i, int j, int k) {
super.onPlace(world, i, j, k);
if (!world.suppressPhysics && world.isBlockIndirectlyPowered(i, j, k)) { // CraftBukkit
this.postBreak(world, i, j, k, 1);
world.setTypeId(i, j, k, 0);
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
if (l > 0 && Block.byId[l].isPowerSource() && world.isBlockIndirectlyPowered(i, j, k)) {
this.postBreak(world, i, j, k, 1);
world.setTypeId(i, j, k, 0);
}
}
public int a(Random random) {
return 0;
}
public void wasExploded(World world, int i, int j, int k) {
if (!world.isStatic) {
EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F));
entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
world.addEntity(entitytntprimed);
}
}
public void postBreak(World world, int i, int j, int k, int l) {
if (!world.isStatic) {
if ((l & 1) == 0) {
this.a(world, i, j, k, new ItemStack(Block.TNT.id, 1, 0));
} else {
EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F));
world.addEntity(entitytntprimed);
world.makeSound(entitytntprimed, "random.fuse", 1.0F, 1.0F);
}
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
super.attack(world, i, j, k, entityhuman);
}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
if (entityhuman.U() != null && entityhuman.U().id == Item.FLINT_AND_STEEL.id) {
this.postBreak(world, i, j, k, 1);
world.setTypeId(i, j, k, 0);
return true;
} else {
return super.interact(world, i, j, k, entityhuman);
}
}
protected ItemStack a_(int i) {
return null;
}
}

View File

@@ -0,0 +1,160 @@
package net.minecraft.server;
import java.util.Random;
public class BlockTallPlant extends BlockPlant implements IBlockFragilePlantElement {
public static final String[] a = new String[] { "sunflower", "syringa", "grass", "fern", "rose", "paeonia"};
public BlockTallPlant() {
super(Material.PLANT);
this.c(0.0F);
this.a(h);
this.c("doublePlant");
}
public int b() {
return 40;
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public int e(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
return !c(l) ? l & 7 : iblockaccess.getData(i, j - 1, k) & 7;
}
public boolean canPlace(World world, int i, int j, int k) {
return super.canPlace(world, i, j, k) && world.isEmpty(i, j + 1, k);
}
protected void e(World world, int i, int j, int k) {
if (!this.j(world, i, j, k)) {
int l = world.getData(i, j, k);
if (!c(l)) {
this.b(world, i, j, k, l, 0);
if (world.getType(i, j + 1, k) == this) {
world.setTypeAndData(i, j + 1, k, Blocks.AIR, 0, 2);
}
}
world.setTypeAndData(i, j, k, Blocks.AIR, 0, 2);
}
}
public boolean j(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
return c(l) ? world.getType(i, j - 1, k) == this : world.getType(i, j + 1, k) == this && super.j(world, i, j, k);
}
public Item getDropType(int i, Random random, int j) {
if (c(i)) {
return null;
} else {
int k = d(i);
return k != 3 && k != 2 ? Item.getItemOf(this) : null;
}
}
public int getDropData(int i) {
return c(i) ? 0 : i & 7;
}
public static boolean c(int i) {
return (i & 8) != 0;
}
public static int d(int i) {
return i & 7;
}
public void c(World world, int i, int j, int k, int l, int i1) {
world.setTypeAndData(i, j, k, this, l, i1);
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 8); // CraftBukkit
}
public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
int l = ((MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) % 4;
world.setTypeAndData(i, j + 1, k, this, 8 | l, 2);
}
public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
if (world.isStatic || entityhuman.bF() == null || entityhuman.bF().getItem() != Items.SHEARS || c(l) || !this.b(world, i, j, k, l, entityhuman)) {
super.a(world, entityhuman, i, j, k, l);
}
}
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (c(l)) {
if (world.getType(i, j - 1, k) == this) {
if (!entityhuman.abilities.canInstantlyBuild) {
int i1 = world.getData(i, j - 1, k);
int j1 = d(i1);
if (j1 != 3 && j1 != 2) {
world.setAir(i, j - 1, k, true);
} else {
if (!world.isStatic && entityhuman.bF() != null && entityhuman.bF().getItem() == Items.SHEARS) {
this.b(world, i, j, k, i1, entityhuman);
}
world.setAir(i, j - 1, k);
}
} else {
world.setAir(i, j - 1, k);
}
}
} else if (entityhuman.abilities.canInstantlyBuild && world.getType(i, j + 1, k) == this) {
world.setTypeAndData(i, j + 1, k, Blocks.AIR, 0, 2);
}
super.a(world, i, j, k, l, entityhuman);
}
private boolean b(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
int i1 = d(l);
if (i1 != 3 && i1 != 2) {
return false;
} else {
entityhuman.a(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)], 1);
byte b0 = 1;
if (i1 == 3) {
b0 = 2;
}
this.a(world, i, j, k, new ItemStack(Blocks.LONG_GRASS, 2, b0));
return true;
}
}
public int getDropData(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
return c(l) ? d(world.getData(i, j - 1, k)) : d(l);
}
public boolean a(World world, int i, int j, int k, boolean flag) {
int l = this.e((IBlockAccess) world, i, j, k);
return l != 2 && l != 3;
}
public boolean a(World world, Random random, int i, int j, int k) {
return true;
}
public void b(World world, Random random, int i, int j, int k) {
int l = this.e((IBlockAccess) world, i, j, k);
this.a(world, i, j, k, new ItemStack(this, 1, l));
}
}

View File

@@ -4,55 +4,56 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockTrapdoor extends Block {
protected BlockTrapdoor(int i, Material material) {
super(i, material);
this.textureId = 84;
if (material == Material.ORE) {
++this.textureId;
}
protected BlockTrapdoor(Material material) {
super(material);
float f = 0.5F;
float f1 = 1.0F;
this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
this.a(CreativeModeTab.d);
}
public boolean a() {
public boolean c() {
return false;
}
public boolean b() {
public boolean d() {
return false;
}
public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
return !e(iblockaccess.getData(i, j, k));
return !d(iblockaccess.getData(i, j, k));
}
public int c() {
public int b() {
return 0;
}
public AxisAlignedBB e(World world, int i, int j, int k) {
public AxisAlignedBB a(World world, int i, int j, int k) {
this.updateShape(world, i, j, k);
return super.e(world, i, j, k);
return super.a(world, i, j, k);
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
this.d(iblockaccess.getData(i, j, k));
this.b(iblockaccess.getData(i, j, k));
}
public void f() {
public void g() {
float f = 0.1875F;
this.a(0.0F, 0.5F - f / 2.0F, 0.0F, 1.0F, 0.5F + f / 2.0F, 1.0F);
}
public void d(int i) {
public void b(int i) {
float f = 0.1875F;
this.a(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
if (e(i)) {
if ((i & 8) != 0) {
this.a(0.0F, 1.0F - f, 0.0F, 1.0F, 1.0F, 1.0F);
} else {
this.a(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
}
if (d(i)) {
if ((i & 3) == 0) {
this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
}
@@ -71,17 +72,15 @@ public class BlockTrapdoor extends Block {
}
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
this.interact(world, i, j, k, entityhuman);
}
public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {}
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman) {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (this.material == Material.ORE) {
return true;
} else {
int l = world.getData(i, j, k);
int i1 = world.getData(i, j, k);
world.setData(i, j, k, l ^ 4);
world.setData(i, j, k, i1 ^ 4, 2);
world.a(entityhuman, 1003, i, j, k, 0);
return true;
}
@@ -92,53 +91,56 @@ public class BlockTrapdoor extends Block {
boolean flag1 = (l & 4) > 0;
if (flag1 != flag) {
world.setData(i, j, k, l ^ 4);
world.setData(i, j, k, l ^ 4, 2);
world.a((EntityHuman) null, 1003, i, j, k, 0);
}
}
public void doPhysics(World world, int i, int j, int k, int l) {
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic) {
int i1 = world.getData(i, j, k);
int j1 = i;
int k1 = k;
int l = world.getData(i, j, k);
int i1 = i;
int j1 = k;
if ((i1 & 3) == 0) {
k1 = k + 1;
if ((l & 3) == 0) {
j1 = k + 1;
}
if ((i1 & 3) == 1) {
--k1;
}
if ((i1 & 3) == 2) {
j1 = i + 1;
}
if ((i1 & 3) == 3) {
if ((l & 3) == 1) {
--j1;
}
if (!h(world.getTypeId(j1, j, k1))) {
world.setTypeId(i, j, k, 0);
this.b(world, i, j, k, i1, 0);
if ((l & 3) == 2) {
i1 = i + 1;
}
// CraftBukkit start
if (l == 0 || l > 0 && Block.byId[l] != null && Block.byId[l].isPowerSource()) {
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.Block block = bworld.getBlockAt(i, j, k);
if ((l & 3) == 3) {
--i1;
}
int power = block.getBlockPower();
if (!a(world.getType(i1, j, j1))) {
world.setAir(i, j, k);
this.b(world, i, j, k, l, 0);
}
boolean flag = world.isBlockIndirectlyPowered(i, j, k);
if (flag || block.isPowerSource()) {
// CraftBukkit start
org.bukkit.World bworld = world.getWorld();
org.bukkit.block.Block bblock = bworld.getBlockAt(i, j, k);
int power = bblock.getBlockPower();
int oldPower = (world.getData(i, j, k) & 4) > 0 ? 15 : 0;
if (oldPower == 0 ^ power == 0 || (Block.byId[l] != null && Block.byId[l].isPowerSource())) {
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, oldPower, power);
if (oldPower == 0 ^ power == 0 || block.isPowerSource()) {
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power);
world.getServer().getPluginManager().callEvent(eventRedstone);
this.setOpen(world, i, j, k, eventRedstone.getNewCurrent() > 0);
flag = eventRedstone.getNewCurrent() > 0;
}
// CraftBukkit end
this.setOpen(world, i, j, k, flag);
}
}
}
@@ -148,27 +150,30 @@ public class BlockTrapdoor extends Block {
return super.a(world, i, j, k, vec3d, vec3d1);
}
public void postPlace(World world, int i, int j, int k, int l) {
byte b0 = 0;
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
int j1 = 0;
if (l == 2) {
b0 = 0;
j1 = 0;
}
if (l == 3) {
b0 = 1;
j1 = 1;
}
if (l == 4) {
b0 = 2;
j1 = 2;
}
if (l == 5) {
b0 = 3;
j1 = 3;
}
world.setData(i, j, k, b0);
doPhysics(world, i, j, k, Block.REDSTONE_WIRE.id); // CraftBukkit
if (l != 1 && l != 0 && f1 > 0.5F) {
j1 |= 8;
}
return j1;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
@@ -193,21 +198,15 @@ public class BlockTrapdoor extends Block {
--i;
}
return h(world.getTypeId(i, j, k));
return a(world.getType(i, j, k));
}
}
public static boolean e(int i) {
public static boolean d(int i) {
return (i & 4) != 0;
}
private static boolean h(int i) {
if (i <= 0) {
return false;
} else {
Block block = Block.byId[i];
return block != null && block.material.j() && block.b() || block == Block.GLOWSTONE;
}
private static boolean a(Block block) {
return block.material.k() && block.d() || block == Blocks.GLOWSTONE || block instanceof BlockStepAbstract || block instanceof BlockStairs;
}
}

View File

@@ -0,0 +1,201 @@
package net.minecraft.server;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit
public class BlockTripwire extends Block {
public BlockTripwire() {
super(Material.ORIENTABLE);
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F);
this.a(true);
}
public int a(World world) {
return 10;
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public int b() {
return 30;
}
public Item getDropType(int i, Random random, int j) {
return Items.STRING;
}
public void doPhysics(World world, int i, int j, int k, Block block) {
int l = world.getData(i, j, k);
boolean flag = (l & 2) == 2;
boolean flag1 = !World.a((IBlockAccess) world, i, j - 1, k);
if (flag != flag1) {
this.b(world, i, j, k, l, 0);
world.setAir(i, j, k);
}
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k);
boolean flag = (l & 4) == 4;
boolean flag1 = (l & 2) == 2;
if (!flag1) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.09375F, 1.0F);
} else if (!flag) {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
} else {
this.a(0.0F, 0.0625F, 0.0F, 1.0F, 0.15625F, 1.0F);
}
}
public void onPlace(World world, int i, int j, int k) {
int l = World.a((IBlockAccess) world, i, j - 1, k) ? 0 : 2;
world.setData(i, j, k, l, 3);
this.a(world, i, j, k, l);
}
public void remove(World world, int i, int j, int k, Block block, int l) {
this.a(world, i, j, k, l | 1);
}
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (!world.isStatic) {
if (entityhuman.bF() != null && entityhuman.bF().getItem() == Items.SHEARS) {
world.setData(i, j, k, l | 8, 4);
}
}
}
private void a(World world, int i, int j, int k, int l) {
int i1 = 0;
while (i1 < 2) {
int j1 = 1;
while (true) {
if (j1 < 42) {
int k1 = i + Direction.a[i1] * j1;
int l1 = k + Direction.b[i1] * j1;
Block block = world.getType(k1, j, l1);
if (block == Blocks.TRIPWIRE_SOURCE) {
int i2 = world.getData(k1, j, l1) & 3;
if (i2 == Direction.f[i1]) {
Blocks.TRIPWIRE_SOURCE.a(world, k1, j, l1, false, world.getData(k1, j, l1), true, j1, l);
}
} else if (block == Blocks.TRIPWIRE) {
++j1;
continue;
}
}
++i1;
break;
}
}
}
public void a(World world, int i, int j, int k, Entity entity) {
if (!world.isStatic) {
if ((world.getData(i, j, k) & 1) != 1) {
this.e(world, i, j, k);
}
}
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
if ((world.getData(i, j, k) & 1) == 1) {
this.e(world, i, j, k);
}
}
}
private void e(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
boolean flag = (l & 1) == 1;
boolean flag1 = false;
List list = world.getEntities((Entity) null, AxisAlignedBB.a((double) i + this.minX, (double) j + this.minY, (double) k + this.minZ, (double) i + this.maxX, (double) j + this.maxY, (double) k + this.maxZ));
if (!list.isEmpty()) {
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
if (!entity.az()) {
flag1 = true;
break;
}
}
}
// CraftBukkit start - Call interact even when triggering connected tripwire
if (flag != flag1 && flag1 && (world.getData(i, j, k) & 4) == 4) {
org.bukkit.World bworld = world.getWorld();
org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager();
org.bukkit.block.Block block = bworld.getBlockAt(i, j, k);
boolean allowed = false;
// If all of the events are cancelled block the tripwire trigger, else allow
for (Object object : list) {
if (object != null) {
org.bukkit.event.Cancellable cancellable;
if (object instanceof EntityHuman) {
cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) object, org.bukkit.event.block.Action.PHYSICAL, i, j, k, -1, null);
} else if (object instanceof Entity) {
cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block);
manager.callEvent((EntityInteractEvent) cancellable);
} else {
continue;
}
if (!cancellable.isCancelled()) {
allowed = true;
break;
}
}
}
if (!allowed) {
return;
}
}
// CraftBukkit end
if (flag1 && !flag) {
l |= 1;
}
if (!flag1 && flag) {
l &= -2;
}
if (flag1 != flag) {
world.setData(i, j, k, l, 3);
this.a(world, i, j, k, l);
}
if (flag1) {
world.a(i, j, k, this, this.a(world));
}
}
}

View File

@@ -0,0 +1,300 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockTripwireHook extends Block {
public BlockTripwireHook() {
super(Material.ORIENTABLE);
this.a(CreativeModeTab.d);
this.a(true);
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public int b() {
return 29;
}
public int a(World world) {
return 10;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
return l == 2 && world.getType(i, j, k + 1).r() ? true : (l == 3 && world.getType(i, j, k - 1).r() ? true : (l == 4 && world.getType(i + 1, j, k).r() ? true : l == 5 && world.getType(i - 1, j, k).r()));
}
public boolean canPlace(World world, int i, int j, int k) {
return world.getType(i - 1, j, k).r() ? true : (world.getType(i + 1, j, k).r() ? true : (world.getType(i, j, k - 1).r() ? true : world.getType(i, j, k + 1).r()));
}
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
byte b0 = 0;
if (l == 2 && world.c(i, j, k + 1, true)) {
b0 = 2;
}
if (l == 3 && world.c(i, j, k - 1, true)) {
b0 = 0;
}
if (l == 4 && world.c(i + 1, j, k, true)) {
b0 = 1;
}
if (l == 5 && world.c(i - 1, j, k, true)) {
b0 = 3;
}
return b0;
}
public void postPlace(World world, int i, int j, int k, int l) {
this.a(world, i, j, k, false, l, false, -1, 0);
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (block != this) {
if (this.e(world, i, j, k)) {
int l = world.getData(i, j, k);
int i1 = l & 3;
boolean flag = false;
if (!world.getType(i - 1, j, k).r() && i1 == 3) {
flag = true;
}
if (!world.getType(i + 1, j, k).r() && i1 == 1) {
flag = true;
}
if (!world.getType(i, j, k - 1).r() && i1 == 0) {
flag = true;
}
if (!world.getType(i, j, k + 1).r() && i1 == 2) {
flag = true;
}
if (flag) {
this.b(world, i, j, k, l, 0);
world.setAir(i, j, k);
}
}
}
}
public void a(World world, int i, int j, int k, boolean flag, int l, boolean flag1, int i1, int j1) {
int k1 = l & 3;
boolean flag2 = (l & 4) == 4;
boolean flag3 = (l & 8) == 8;
boolean flag4 = !flag;
boolean flag5 = false;
boolean flag6 = !World.a((IBlockAccess) world, i, j - 1, k);
int l1 = Direction.a[k1];
int i2 = Direction.b[k1];
int j2 = 0;
int[] aint = new int[42];
int k2;
int l2;
int i3;
int j3;
for (l2 = 1; l2 < 42; ++l2) {
k2 = i + l1 * l2;
i3 = k + i2 * l2;
Block block = world.getType(k2, j, i3);
if (block == Blocks.TRIPWIRE_SOURCE) {
j3 = world.getData(k2, j, i3);
if ((j3 & 3) == Direction.f[k1]) {
j2 = l2;
}
break;
}
if (block != Blocks.TRIPWIRE && l2 != i1) {
aint[l2] = -1;
flag4 = false;
} else {
j3 = l2 == i1 ? j1 : world.getData(k2, j, i3);
boolean flag7 = (j3 & 8) != 8;
boolean flag8 = (j3 & 1) == 1;
boolean flag9 = (j3 & 2) == 2;
flag4 &= flag9 == flag6;
flag5 |= flag7 && flag8;
aint[l2] = j3;
if (l2 == i1) {
world.a(i, j, k, this, this.a(world));
flag4 &= flag7;
}
}
}
flag4 &= j2 > 1;
flag5 &= flag4;
l2 = (flag4 ? 4 : 0) | (flag5 ? 8 : 0);
l = k1 | l2;
int k3;
if (j2 > 0) {
k2 = i + l1 * j2;
i3 = k + i2 * j2;
k3 = Direction.f[k1];
world.setData(k2, j, i3, k3 | l2, 3);
this.a(world, k2, j, i3, k3);
this.a(world, k2, j, i3, flag4, flag5, flag2, flag3);
}
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0);
world.getServer().getPluginManager().callEvent(eventRedstone);
if (eventRedstone.getNewCurrent() > 0) {
return;
}
// CraftBukkit end
this.a(world, i, j, k, flag4, flag5, flag2, flag3);
if (!flag) {
world.setData(i, j, k, l, 3);
if (flag1) {
this.a(world, i, j, k, k1);
}
}
if (flag2 != flag4) {
for (k2 = 1; k2 < j2; ++k2) {
i3 = i + l1 * k2;
k3 = k + i2 * k2;
j3 = aint[k2];
if (j3 >= 0) {
if (flag4) {
j3 |= 4;
} else {
j3 &= -5;
}
world.setData(i3, j, k3, j3, 3);
}
}
}
}
public void a(World world, int i, int j, int k, Random random) {
this.a(world, i, j, k, false, world.getData(i, j, k), true, -1, 0);
}
private void a(World world, int i, int j, int k, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
if (flag1 && !flag3) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.4F, 0.6F);
} else if (!flag1 && flag3) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.4F, 0.5F);
} else if (flag && !flag2) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.click", 0.4F, 0.7F);
} else if (!flag && flag2) {
world.makeSound((double) i + 0.5D, (double) j + 0.1D, (double) k + 0.5D, "random.bowhit", 0.4F, 1.2F / (world.random.nextFloat() * 0.2F + 0.9F));
}
}
private void a(World world, int i, int j, int k, int l) {
world.applyPhysics(i, j, k, this);
if (l == 3) {
world.applyPhysics(i - 1, j, k, this);
} else if (l == 1) {
world.applyPhysics(i + 1, j, k, this);
} else if (l == 0) {
world.applyPhysics(i, j, k - 1, this);
} else if (l == 2) {
world.applyPhysics(i, j, k + 1, this);
}
}
private boolean e(World world, int i, int j, int k) {
if (!this.canPlace(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
return false;
} else {
return true;
}
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
int l = iblockaccess.getData(i, j, k) & 3;
float f = 0.1875F;
if (l == 3) {
this.a(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f);
} else if (l == 1) {
this.a(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f);
} else if (l == 0) {
this.a(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F);
} else if (l == 2) {
this.a(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F);
}
}
public void remove(World world, int i, int j, int k, Block block, int l) {
boolean flag = (l & 4) == 4;
boolean flag1 = (l & 8) == 8;
if (flag || flag1) {
this.a(world, i, j, k, true, l, false, -1, 0);
}
if (flag1) {
world.applyPhysics(i, j, k, this);
int i1 = l & 3;
if (i1 == 3) {
world.applyPhysics(i - 1, j, k, this);
} else if (i1 == 1) {
world.applyPhysics(i + 1, j, k, this);
} else if (i1 == 0) {
world.applyPhysics(i, j, k - 1, this);
} else if (i1 == 2) {
world.applyPhysics(i, j, k + 1, this);
}
}
super.remove(world, i, j, k, block, l);
}
public int b(IBlockAccess iblockaccess, int i, int j, int k, int l) {
return (iblockaccess.getData(i, j, k) & 8) == 8 ? 15 : 0;
}
public int c(IBlockAccess iblockaccess, int i, int j, int k, int l) {
int i1 = iblockaccess.getData(i, j, k);
if ((i1 & 8) != 8) {
return 0;
} else {
int j1 = i1 & 3;
return j1 == 2 && l == 2 ? 15 : (j1 == 0 && l == 3 ? 15 : (j1 == 1 && l == 4 ? 15 : (j1 == 3 && l == 5 ? 15 : 0)));
}
}
public boolean isPowerSource() {
return true;
}
}

View File

@@ -0,0 +1,304 @@
package net.minecraft.server;
import java.util.Random;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class BlockVine extends Block {
public BlockVine() {
super(Material.REPLACEABLE_PLANT);
this.a(true);
this.a(CreativeModeTab.c);
}
public void g() {
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
public int b() {
return 20;
}
public boolean c() {
return false;
}
public boolean d() {
return false;
}
public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
float f = 0.0625F;
int l = iblockaccess.getData(i, j, k);
float f1 = 1.0F;
float f2 = 1.0F;
float f3 = 1.0F;
float f4 = 0.0F;
float f5 = 0.0F;
float f6 = 0.0F;
boolean flag = l > 0;
if ((l & 2) != 0) {
f4 = Math.max(f4, 0.0625F);
f1 = 0.0F;
f2 = 0.0F;
f5 = 1.0F;
f3 = 0.0F;
f6 = 1.0F;
flag = true;
}
if ((l & 8) != 0) {
f1 = Math.min(f1, 0.9375F);
f4 = 1.0F;
f2 = 0.0F;
f5 = 1.0F;
f3 = 0.0F;
f6 = 1.0F;
flag = true;
}
if ((l & 4) != 0) {
f6 = Math.max(f6, 0.0625F);
f3 = 0.0F;
f1 = 0.0F;
f4 = 1.0F;
f2 = 0.0F;
f5 = 1.0F;
flag = true;
}
if ((l & 1) != 0) {
f3 = Math.min(f3, 0.9375F);
f6 = 1.0F;
f1 = 0.0F;
f4 = 1.0F;
f2 = 0.0F;
f5 = 1.0F;
flag = true;
}
if (!flag && this.a(iblockaccess.getType(i, j + 1, k))) {
f2 = Math.min(f2, 0.9375F);
f5 = 1.0F;
f1 = 0.0F;
f4 = 1.0F;
f3 = 0.0F;
f6 = 1.0F;
}
this.a(f1, f2, f3, f4, f5, f6);
}
public AxisAlignedBB a(World world, int i, int j, int k) {
return null;
}
public boolean canPlace(World world, int i, int j, int k, int l) {
switch (l) {
case 1:
return this.a(world.getType(i, j + 1, k));
case 2:
return this.a(world.getType(i, j, k + 1));
case 3:
return this.a(world.getType(i, j, k - 1));
case 4:
return this.a(world.getType(i + 1, j, k));
case 5:
return this.a(world.getType(i - 1, j, k));
default:
return false;
}
}
private boolean a(Block block) {
return block.d() && block.material.isSolid();
}
private boolean e(World world, int i, int j, int k) {
int l = world.getData(i, j, k);
int i1 = l;
if (l > 0) {
for (int j1 = 0; j1 <= 3; ++j1) {
int k1 = 1 << j1;
if ((l & k1) != 0 && !this.a(world.getType(i + Direction.a[j1], j, k + Direction.b[j1])) && (world.getType(i, j + 1, k) != this || (world.getData(i, j + 1, k) & k1) == 0)) {
i1 &= ~k1;
}
}
}
if (i1 == 0 && !this.a(world.getType(i, j + 1, k))) {
return false;
} else {
if (i1 != l) {
world.setData(i, j, k, i1, 2);
}
return true;
}
}
public void doPhysics(World world, int i, int j, int k, Block block) {
if (!world.isStatic && !this.e(world, i, j, k)) {
this.b(world, i, j, k, world.getData(i, j, k), 0);
world.setAir(i, j, k);
}
}
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic && world.random.nextInt(4) == 0) {
byte b0 = 4;
int l = 5;
boolean flag = false;
int i1;
int j1;
int k1;
label134:
for (i1 = i - b0; i1 <= i + b0; ++i1) {
for (j1 = k - b0; j1 <= k + b0; ++j1) {
for (k1 = j - 1; k1 <= j + 1; ++k1) {
if (world.getType(i1, k1, j1) == this) {
--l;
if (l <= 0) {
flag = true;
break label134;
}
}
}
}
}
i1 = world.getData(i, j, k);
j1 = world.random.nextInt(6);
k1 = Direction.e[j1];
int l1;
if (j1 == 1 && j < 255 && world.isEmpty(i, j + 1, k)) {
if (flag) {
return;
}
int i2 = world.random.nextInt(16) & i1;
if (i2 > 0) {
for (l1 = 0; l1 <= 3; ++l1) {
if (!this.a(world.getType(i + Direction.a[l1], j + 1, k + Direction.b[l1]))) {
i2 &= ~(1 << l1);
}
}
if (i2 > 0) {
// CraftBukkit start - Call BlockSpreadEvent
org.bukkit.block.Block source = world.getWorld().getBlockAt(i, j, k);
org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j + 1, k);
CraftEventFactory.handleBlockSpreadEvent(block, source, this, l1);
// CraftBukkit end
}
}
} else {
Block block;
int j2;
if (j1 >= 2 && j1 <= 5 && (i1 & 1 << k1) == 0) {
if (flag) {
return;
}
block = world.getType(i + Direction.a[k1], j, k + Direction.b[k1]);
if (block.material == Material.AIR) {
l1 = k1 + 1 & 3;
j2 = k1 + 3 & 3;
// CraftBukkit start - Call BlockSpreadEvent
org.bukkit.block.Block source = world.getWorld().getBlockAt(i, j, k);
org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i + Direction.a[k1], j, k + Direction.b[k1]);
if ((i1 & 1 << l1) != 0 && this.a(world.getType(i + Direction.a[k1] + Direction.a[l1], j, k + Direction.b[k1] + Direction.b[l1]))) {
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << l1);
} else if ((i1 & 1 << j2) != 0 && this.a(world.getType(i + Direction.a[k1] + Direction.a[j2], j, k + Direction.b[k1] + Direction.b[j2]))) {
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << j2);
} else if ((i1 & 1 << l1) != 0 && world.isEmpty(i + Direction.a[k1] + Direction.a[l1], j, k + Direction.b[k1] + Direction.b[l1]) && this.a(world.getType(i + Direction.a[l1], j, k + Direction.b[l1]))) {
bukkitBlock = world.getWorld().getBlockAt(i + Direction.a[k1] + Direction.a[l1], j, k + Direction.b[k1] + Direction.b[l1]);
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << (k1 + 2 & 3));
} else if ((i1 & 1 << j2) != 0 && world.isEmpty(i + Direction.a[k1] + Direction.a[j2], j, k + Direction.b[k1] + Direction.b[j2]) && this.a(world.getType(i + Direction.a[j2], j, k + Direction.b[j2]))) {
bukkitBlock = world.getWorld().getBlockAt(i + Direction.a[k1] + Direction.a[j2], j, k + Direction.b[k1] + Direction.b[j2]);
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << (k1 + 2 & 3));
} else if (this.a(world.getType(i + Direction.a[k1], j + 1, k + Direction.b[k1]))) {
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 0);
}
// CraftBukkit end
} else if (block.material.k() && block.d()) {
world.setData(i, j, k, i1 | 1 << k1, 2);
}
} else if (j > 1) {
block = world.getType(i, j - 1, k);
if (block.material == Material.AIR) {
l1 = world.random.nextInt(16) & i1;
if (l1 > 0) {
// CraftBukkit start - Call BlockSpreadEvent
org.bukkit.block.Block source = world.getWorld().getBlockAt(i, j, k);
org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i, j - 1, k);
CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, l1);
// CraftBukkit end
}
} else if (block == this) {
l1 = world.random.nextInt(16) & i1;
j2 = world.getData(i, j - 1, k);
if (j2 != (j2 | l1)) {
world.setData(i, j - 1, k, j2 | l1, 2);
}
}
}
}
}
}
public int getPlacedData(World world, int i, int j, int k, int l, float f, float f1, float f2, int i1) {
byte b0 = 0;
switch (l) {
case 2:
b0 = 1;
break;
case 3:
b0 = 4;
break;
case 4:
b0 = 8;
break;
case 5:
b0 = 2;
}
return b0 != 0 ? b0 : i1;
}
public Item getDropType(int i, Random random, int j) {
return null;
}
public int a(Random random) {
return 0;
}
public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
if (!world.isStatic && entityhuman.bF() != null && entityhuman.bF().getItem() == Items.SHEARS) {
entityhuman.a(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)], 1);
this.a(world, i, j, k, new ItemStack(Blocks.VINE, 1, 0));
} else {
super.a(world, entityhuman, i, j, k, l);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,77 +2,139 @@ package net.minecraft.server;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.util.com.google.common.collect.Lists;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// CraftBukkit start
import java.util.Random;
import org.bukkit.craftbukkit.CraftChunk;
import org.bukkit.craftbukkit.util.LongHashset;
import org.bukkit.craftbukkit.util.LongHashtable;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkPopulateEvent;
import org.bukkit.Server;
import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
import org.bukkit.craftbukkit.util.LongHash;
import org.bukkit.craftbukkit.util.LongHashSet;
import org.bukkit.craftbukkit.util.LongObjectHashMap;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.generator.BlockPopulator;
// CraftBukkit end
public class ChunkProviderServer implements IChunkProvider {
// CraftBukkit start
public LongHashset unloadQueue = new LongHashset();
private static final Logger b = LogManager.getLogger();
// CraftBukkit start - private -> public
public LongHashSet unloadQueue = new LongHashSet(); // LongHashSet
public Chunk emptyChunk;
public IChunkProvider chunkProvider; // CraftBukkit
private IChunkLoader e;
public boolean forceChunkLoad = false;
public LongHashtable<Chunk> chunks = new LongHashtable<Chunk>();
public List chunkList = new ArrayList();
public IChunkProvider chunkProvider;
private IChunkLoader f;
public boolean forceChunkLoad = false; // true -> false
public LongObjectHashMap<Chunk> chunks = new LongObjectHashMap<Chunk>();
public WorldServer world;
// CraftBukkit end
public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) {
this.emptyChunk = new EmptyChunk(worldserver, 0, 0);
this.world = worldserver;
this.e = ichunkloader;
this.f = ichunkloader;
this.chunkProvider = ichunkprovider;
}
public boolean isChunkLoaded(int i, int j) {
return this.chunks.containsKey(i, j); // CraftBukkit
return this.chunks.containsKey(LongHash.toLong(i, j)); // CraftBukkit
}
// CraftBukkit start - Change return type to Collection and return the values of our chunk map
public java.util.Collection a() {
// return this.chunkList;
return this.chunks.values();
// CraftBukkit end
}
public void queueUnload(int i, int j) {
if (this.world.worldProvider.c()) {
if (this.world.worldProvider.e()) {
ChunkCoordinates chunkcoordinates = this.world.getSpawn();
int k = i * 16 + 8 - chunkcoordinates.x;
int l = j * 16 + 8 - chunkcoordinates.z;
short short1 = 128;
if (k < -short1 || k > short1 || l < -short1 || l > short1 || !(this.world.keepSpawnInMemory)) { // CraftBukkit - added 'this.world.keepSpawnInMemory'
this.unloadQueue.add(i, j); // CraftBukkit
// CraftBukkit start
if (k < -short1 || k > short1 || l < -short1 || l > short1 || !(this.world.keepSpawnInMemory)) { // Added 'this.world.keepSpawnInMemory'
this.unloadQueue.add(i, j);
Chunk c = this.chunks.get(LongHash.toLong(i, j));
if (c != null) {
c.mustSave = true;
}
}
// CraftBukkit end
} else {
this.unloadQueue.add(i, j); // CraftBukkit
// CraftBukkit start
this.unloadQueue.add(i, j);
Chunk c = this.chunks.get(LongHash.toLong(i, j));
if (c != null) {
c.mustSave = true;
}
// CraftBukkit end
}
}
public void c() {
Iterator iterator = this.chunkList.iterator();
public void b() {
Iterator iterator = this.chunks.values().iterator(); // CraftBukkit
while (iterator.hasNext()) {
Chunk chunk = (Chunk) iterator.next();
this.queueUnload(chunk.x, chunk.z);
this.queueUnload(chunk.locX, chunk.locZ);
}
}
// CraftBukkit start - Add async variant, provide compatibility
public Chunk getChunkIfLoaded(int x, int z) {
return this.chunks.get(LongHash.toLong(x, z));
}
public Chunk getChunkAt(int i, int j) {
// CraftBukkit start
return getChunkAt(i, j, null);
}
public Chunk getChunkAt(int i, int j, Runnable runnable) {
this.unloadQueue.remove(i, j);
Chunk chunk = (Chunk) this.chunks.get(i, j);
Chunk chunk = this.chunks.get(LongHash.toLong(i, j));
ChunkRegionLoader loader = null;
if (this.f instanceof ChunkRegionLoader) {
loader = (ChunkRegionLoader) this.f;
}
// We can only use the queue for already generated chunks
if (chunk == null && loader != null && loader.chunkExists(this.world, i, j)) {
if (runnable != null) {
ChunkIOExecutor.queueChunkLoad(this.world, loader, this, i, j, runnable);
return null;
} else {
chunk = ChunkIOExecutor.syncChunkLoad(this.world, loader, this, i, j);
}
} else if (chunk == null) {
chunk = this.originalGetChunkAt(i, j);
}
// If we didn't load the chunk async and have a callback run it now
if (runnable != null) {
runnable.run();
}
return chunk;
}
public Chunk originalGetChunkAt(int i, int j) {
this.unloadQueue.remove(i, j);
Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j));
boolean newChunk = false;
// CraftBukkit end
if (chunk == null) {
chunk = this.loadChunk(i, j);
@@ -80,31 +142,51 @@ public class ChunkProviderServer implements IChunkProvider {
if (this.chunkProvider == null) {
chunk = this.emptyChunk;
} else {
chunk = this.chunkProvider.getOrCreateChunk(i, j);
try {
chunk = this.chunkProvider.getOrCreateChunk(i, j);
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Exception generating new chunk");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Chunk to be generated");
crashreportsystemdetails.a("Location", String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)}));
crashreportsystemdetails.a("Position hash", Long.valueOf(LongHash.toLong(i, j))); // CraftBukkit - Use LongHash
crashreportsystemdetails.a("Generator", this.chunkProvider.getName());
throw new ReportedException(crashreport);
}
}
newChunk = true; // CraftBukkit
}
this.chunks.put(i, j, chunk); // CraftBukkit
this.chunkList.add(chunk);
if (chunk != null) {
chunk.loadNOP();
chunk.addEntities();
}
this.chunks.put(LongHash.toLong(i, j), chunk); // CraftBukkit
chunk.addEntities();
// CraftBukkit start
org.bukkit.Server server = this.world.getServer();
Server server = this.world.getServer();
if (server != null) {
/*
* If it's a new world, the first few chunks are generated inside
* the World constructor. We can't reliably alter that, so we have
* no way of creating a CraftWorld/CraftServer at that point.
*/
server.getPluginManager().callEvent(new ChunkLoadEvent(chunk.bukkitChunk, newChunk));
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk));
}
// Update neighbor counts
for (int x = -2; x < 3; x++) {
for (int z = -2; z < 3; z++) {
if (x == 0 && z == 0) {
continue;
}
Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z);
if (neighbor != null) {
neighbor.setNeighborLoaded(-x, -z);
chunk.setNeighborLoaded(x, z);
}
}
}
// CraftBukkit end
chunk.a(this, this, i, j);
chunk.loadNearby(this, this, i, j);
}
return chunk;
@@ -112,13 +194,13 @@ public class ChunkProviderServer implements IChunkProvider {
public Chunk getOrCreateChunk(int i, int j) {
// CraftBukkit start
Chunk chunk = (Chunk) this.chunks.get(i, j);
Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j));
chunk = chunk == null ? (!this.world.isLoading && !this.forceChunkLoad ? this.emptyChunk : this.getChunkAt(i, j)) : chunk;
if (chunk == this.emptyChunk) return chunk;
if (i != chunk.x || j != chunk.z) {
MinecraftServer.log.severe("Chunk (" + chunk.x + ", " + chunk.z + ") stored at (" + i + ", " + j + ") in world '" + world.getWorld().getName() + "'");
MinecraftServer.log.severe(chunk.getClass().getName());
if (i != chunk.locX || j != chunk.locZ) {
b.error("Chunk (" + chunk.locX + ", " + chunk.locZ + ") stored at (" + i + ", " + j + ") in world '" + world.getWorld().getName() + "'");
b.error(chunk.getClass().getName());
Throwable ex = new Throwable();
ex.fillInStackTrace();
ex.printStackTrace();
@@ -128,41 +210,49 @@ public class ChunkProviderServer implements IChunkProvider {
}
public Chunk loadChunk(int i, int j) { // CraftBukkit - private -> public
if (this.e == null) {
if (this.f == null) {
return null;
} else {
try {
Chunk chunk = this.e.a(this.world, i, j);
Chunk chunk = this.f.a(this.world, i, j);
if (chunk != null) {
chunk.n = this.world.getTime();
chunk.lastSaved = this.world.getTime();
if (this.chunkProvider != null) {
this.chunkProvider.recreateStructures(i, j);
}
}
return chunk;
} catch (Exception exception) {
exception.printStackTrace();
b.error("Couldn\'t load chunk", exception);
return null;
}
}
}
public void saveChunkNOP(Chunk chunk) { // CraftBukkit - private -> public
if (this.e != null) {
if (this.f != null) {
try {
this.e.b(this.world, chunk);
this.f.b(this.world, chunk);
} catch (Exception exception) {
exception.printStackTrace();
b.error("Couldn\'t save entities", exception);
}
}
}
public void saveChunk(Chunk chunk) { // CraftBukkit - private -> public
if (this.e != null) {
if (this.f != null) {
try {
chunk.n = this.world.getTime();
this.e.a(this.world, chunk);
} catch (Exception ioexception) { // CraftBukkit - IOException -> Exception
ioexception.printStackTrace();
chunk.lastSaved = this.world.getTime();
this.f.a(this.world, chunk);
// CraftBukkit start - IOException to Exception
} catch (Exception ioexception) {
b.error("Couldn\'t save chunk", ioexception);
/* Remove extra exception
} catch (ExceptionWorldConflict exceptionworldconflict) {
b.error("Couldn\'t save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
// CraftBukkit end */
}
}
}
@@ -171,7 +261,7 @@ public class ChunkProviderServer implements IChunkProvider {
Chunk chunk = this.getOrCreateChunk(i, j);
if (!chunk.done) {
chunk.done = true;
chunk.p();
if (this.chunkProvider != null) {
this.chunkProvider.getChunkAt(ichunkprovider, i, j);
@@ -185,12 +275,17 @@ public class ChunkProviderServer implements IChunkProvider {
org.bukkit.World world = this.world.getWorld();
if (world != null) {
for (BlockPopulator populator : world.getPopulators()) {
populator.populate(world, random, chunk.bukkitChunk);
this.world.populating = true;
try {
for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) {
populator.populate(world, random, chunk.bukkitChunk);
}
} finally {
this.world.populating = false;
}
}
BlockSand.instaFall = false;
this.world.getServer().getPluginManager().callEvent(new ChunkPopulateEvent(chunk.bukkitChunk));
this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk));
// CraftBukkit end
chunk.e();
@@ -200,9 +295,12 @@ public class ChunkProviderServer implements IChunkProvider {
public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) {
int i = 0;
// CraftBukkit start
Iterator iterator = this.chunks.values().iterator();
for (int j = 0; j < this.chunkList.size(); ++j) {
Chunk chunk = (Chunk) this.chunkList.get(j);
while (iterator.hasNext()) {
Chunk chunk = (Chunk) iterator.next();
// CraftBukkit end
if (flag) {
this.saveChunkNOP(chunk);
@@ -210,7 +308,7 @@ public class ChunkProviderServer implements IChunkProvider {
if (chunk.a(flag)) {
this.saveChunk(chunk);
chunk.l = false;
chunk.n = false;
++i;
if (i == 24 && !flag) {
return false;
@@ -218,22 +316,20 @@ public class ChunkProviderServer implements IChunkProvider {
}
}
if (flag) {
if (this.e == null) {
return true;
}
this.e.b();
}
return true;
}
public void c() {
if (this.f != null) {
this.f.b();
}
}
public boolean unloadChunks() {
if (!this.world.savingDisabled) {
// CraftBukkit start
org.bukkit.Server server = this.world.getServer();
for (int i = 0; i < 50 && !this.unloadQueue.isEmpty(); i++) {
Server server = this.world.getServer();
for (int i = 0; i < 100 && !this.unloadQueue.isEmpty(); i++) {
long chunkcoordinates = this.unloadQueue.popFirst();
Chunk chunk = this.chunks.get(chunkcoordinates);
if (chunk == null) continue;
@@ -241,18 +337,36 @@ public class ChunkProviderServer implements IChunkProvider {
ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk);
server.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
chunk.removeEntities();
this.saveChunk(chunk);
this.saveChunkNOP(chunk);
// this.unloadQueue.remove(integer);
this.chunks.remove(chunkcoordinates); // CraftBukkit
this.chunkList.remove(chunk);
if (chunk != null) {
chunk.removeEntities();
this.saveChunk(chunk);
this.saveChunkNOP(chunk);
this.chunks.remove(chunkcoordinates); // CraftBukkit
}
// this.unloadQueue.remove(olong);
// this.chunks.remove(olong.longValue());
// Update neighbor counts
for (int x = -2; x < 3; x++) {
for (int z = -2; z < 3; z++) {
if (x == 0 && z == 0) {
continue;
}
Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z);
if (neighbor != null) {
neighbor.setNeighborUnloaded(-x, -z);
chunk.setNeighborUnloaded(x, z);
}
}
}
}
}
// CraftBukkit end
if (this.e != null) {
this.e.a();
if (this.f != null) {
this.f.a();
}
}
@@ -263,8 +377,9 @@ public class ChunkProviderServer implements IChunkProvider {
return !this.world.savingDisabled;
}
public String d() {
return "ServerChunkCache: " + this.chunks.values().size() + " Drop: " + this.unloadQueue.size(); // CraftBukkit
public String getName() {
// CraftBukkit - this.chunks.count() -> .values().size()
return "ServerChunkCache: " + this.chunks.values().size() + " Drop: " + this.unloadQueue.size();
}
public List getMobsFor(EnumCreatureType enumcreaturetype, int i, int j, int k) {
@@ -274,4 +389,11 @@ public class ChunkProviderServer implements IChunkProvider {
public ChunkPosition findNearestMapFeature(World world, String s, int i, int j, int k) {
return this.chunkProvider.findNearestMapFeature(world, s, i, j, k);
}
public int getLoadedChunks() {
// CraftBukkit - this.chunks.count() -> this.chunks.size()
return this.chunks.size();
}
public void recreateStructures(int i, int j) {}
}

View File

@@ -1,38 +1,72 @@
package net.minecraft.server;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException; // CraftBukkit
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
private List a = new ArrayList();
private Set b = new HashSet();
private Object c = new Object();
private final File d;
private static final Logger a = LogManager.getLogger();
private List b = new ArrayList();
private Set c = new HashSet();
private Object d = new Object();
private final File e;
public ChunkRegionLoader(File file1) {
this.d = file1;
this.e = file1;
}
// CraftBukkit start
public boolean chunkExists(World world, int i, int j) {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
synchronized (this.d) {
if (this.c.contains(chunkcoordintpair)) {
for (int k = 0; k < this.b.size(); ++k) {
if (((PendingChunkToSave) this.b.get(k)).a.equals(chunkcoordintpair)) {
return true;
}
}
}
}
return RegionFileCache.a(this.e, i, j).chunkExists(i & 31, j & 31);
}
// CraftBukkit end
// CraftBukkit start - Add async variant, provide compatibility
public Chunk a(World world, int i, int j) {
Object[] data = this.loadChunk(world, i, j);
if (data != null) {
Chunk chunk = (Chunk) data[0];
NBTTagCompound nbttagcompound = (NBTTagCompound) data[1];
this.loadEntities(chunk, nbttagcompound.getCompound("Level"), world);
return chunk;
}
return null;
}
public Object[] loadChunk(World world, int i, int j) {
// CraftBukkit end
NBTTagCompound nbttagcompound = null;
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
Object object = this.c;
Object object = this.d;
synchronized (this.c) {
if (this.b.contains(chunkcoordintpair)) {
for (int k = 0; k < this.a.size(); ++k) {
if (((PendingChunkToSave) this.a.get(k)).a.equals(chunkcoordintpair)) {
nbttagcompound = ((PendingChunkToSave) this.a.get(k)).b;
synchronized (this.d) {
if (this.c.contains(chunkcoordintpair)) {
for (int k = 0; k < this.b.size(); ++k) {
if (((PendingChunkToSave) this.b.get(k)).a.equals(chunkcoordintpair)) {
nbttagcompound = ((PendingChunkToSave) this.b.get(k)).b;
break;
}
}
@@ -40,42 +74,65 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
if (nbttagcompound == null) {
DataInputStream datainputstream = RegionFileCache.b(this.d, i, j);
DataInputStream datainputstream = RegionFileCache.c(this.e, i, j);
if (datainputstream == null) {
return null;
}
nbttagcompound = NBTCompressedStreamTools.a((DataInput) datainputstream);
nbttagcompound = NBTCompressedStreamTools.a(datainputstream);
}
return this.a(world, i, j, nbttagcompound);
}
protected Chunk a(World world, int i, int j, NBTTagCompound nbttagcompound) {
if (!nbttagcompound.hasKey("Level")) {
System.out.println("Chunk file at " + i + "," + j + " is missing level data, skipping");
protected Object[] a(World world, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[]
if (!nbttagcompound.hasKeyOfType("Level", 10)) {
a.error("Chunk file at " + i + "," + j + " is missing level data, skipping");
return null;
} else if (!nbttagcompound.getCompound("Level").hasKey("Sections")) {
System.out.println("Chunk file at " + i + "," + j + " is missing block data, skipping");
} else if (!nbttagcompound.getCompound("Level").hasKeyOfType("Sections", 9)) {
a.error("Chunk file at " + i + "," + j + " is missing block data, skipping");
return null;
} else {
Chunk chunk = this.a(world, nbttagcompound.getCompound("Level"));
if (!chunk.a(i, j)) {
System.out.println("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.x + ", " + chunk.z + ")");
a.error("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.locX + ", " + chunk.locZ + ")");
nbttagcompound.getCompound("Level").setInt("xPos", i); // CraftBukkit - .getCompound("Level")
nbttagcompound.getCompound("Level").setInt("zPos", j); // CraftBukkit - .getCompound("Level")
// CraftBukkit start - Have to move tile entities since we don't load them at this stage
NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10);
if (tileEntities != null) {
for (int te = 0; te < tileEntities.size(); te++) {
NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te);
int x = tileEntity.getInt("x") - chunk.locX * 16;
int z = tileEntity.getInt("z") - chunk.locZ * 16;
tileEntity.setInt("x", i * 16 + x);
tileEntity.setInt("z", j * 16 + z);
}
}
// CraftBukkit end
chunk = this.a(world, nbttagcompound.getCompound("Level"));
}
chunk.i();
return chunk;
// CraftBukkit start
Object[] data = new Object[2];
data[0] = chunk;
data[1] = nbttagcompound;
return data;
// CraftBukkit end
}
}
public void a(World world, Chunk chunk) {
world.m();
// CraftBukkit start - "handle" exception
try {
world.G();
} catch (ExceptionWorldConflict ex) {
ex.printStackTrace();
}
// CraftBukkit end
try {
NBTTagCompound nbttagcompound = new NBTTagCompound();
@@ -83,42 +140,42 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
nbttagcompound.set("Level", nbttagcompound1);
this.a(chunk, world, nbttagcompound1);
this.a(chunk.k(), nbttagcompound);
this.a(chunk.l(), nbttagcompound);
} catch (Exception exception) {
exception.printStackTrace();
}
}
protected void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
Object object = this.c;
Object object = this.d;
synchronized (this.c) {
if (this.b.contains(chunkcoordintpair)) {
for (int i = 0; i < this.a.size(); ++i) {
if (((PendingChunkToSave) this.a.get(i)).a.equals(chunkcoordintpair)) {
this.a.set(i, new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
synchronized (this.d) {
if (this.c.contains(chunkcoordintpair)) {
for (int i = 0; i < this.b.size(); ++i) {
if (((PendingChunkToSave) this.b.get(i)).a.equals(chunkcoordintpair)) {
this.b.set(i, new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
return;
}
}
}
this.a.add(new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
this.b.add(chunkcoordintpair);
this.b.add(new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
this.c.add(chunkcoordintpair);
FileIOThread.a.a(this);
}
}
public boolean c() {
PendingChunkToSave pendingchunktosave = null;
Object object = this.c;
Object object = this.d;
synchronized (this.c) {
if (this.a.size() <= 0) {
synchronized (this.d) {
if (this.b.isEmpty()) {
return false;
}
pendingchunktosave = (PendingChunkToSave) this.a.remove(0);
this.b.remove(pendingchunktosave.a);
pendingchunktosave = (PendingChunkToSave) this.b.remove(0);
this.c.remove(pendingchunktosave.a);
}
if (pendingchunktosave != null) {
@@ -132,8 +189,8 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
return true;
}
public void a(PendingChunkToSave pendingchunktosave) throws IOException { // CraftBukkit - Added throws
DataOutputStream dataoutputstream = RegionFileCache.c(this.d, pendingchunktosave.a.x, pendingchunktosave.a.z);
public void a(PendingChunkToSave pendingchunktosave) throws java.io.IOException { // CraftBukkit - public -> private, added throws
DataOutputStream dataoutputstream = RegionFileCache.d(this.e, pendingchunktosave.a.x, pendingchunktosave.a.z);
NBTCompressedStreamTools.a(pendingchunktosave.b, (DataOutput) dataoutputstream);
dataoutputstream.close();
@@ -143,17 +200,24 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
public void a() {}
public void b() {}
public void b() {
while (this.c()) {
;
}
}
private void a(Chunk chunk, World world, NBTTagCompound nbttagcompound) {
world.m();
nbttagcompound.setInt("xPos", chunk.x);
nbttagcompound.setInt("zPos", chunk.z);
nbttagcompound.setByte("V", (byte) 1);
nbttagcompound.setInt("xPos", chunk.locX);
nbttagcompound.setInt("zPos", chunk.locZ);
nbttagcompound.setLong("LastUpdate", world.getTime());
nbttagcompound.setIntArray("HeightMap", chunk.heightMap);
nbttagcompound.setBoolean("TerrainPopulated", chunk.done);
ChunkSection[] achunksection = chunk.h();
NBTTagList nbttaglist = new NBTTagList("Sections");
nbttagcompound.setBoolean("LightPopulated", chunk.lit);
nbttagcompound.setLong("InhabitedTime", chunk.s);
ChunkSection[] achunksection = chunk.getSections();
NBTTagList nbttaglist = new NBTTagList();
boolean flag = !world.worldProvider.g;
ChunkSection[] achunksection1 = achunksection;
int i = achunksection.length;
@@ -162,24 +226,29 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
for (int j = 0; j < i; ++j) {
ChunkSection chunksection = achunksection1[j];
if (chunksection != null && chunksection.f() != 0) {
if (chunksection != null) {
nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Y", (byte) (chunksection.c() >> 4 & 255));
nbttagcompound1.setByteArray("Blocks", chunksection.g());
if (chunksection.h() != null) {
nbttagcompound1.setByteArray("Add", chunksection.h().a);
nbttagcompound1.setByte("Y", (byte) (chunksection.getYPosition() >> 4 & 255));
nbttagcompound1.setByteArray("Blocks", chunksection.getIdArray());
if (chunksection.getExtendedIdArray() != null) {
nbttagcompound1.setByteArray("Add", chunksection.getExtendedIdArray().a);
}
nbttagcompound1.setByteArray("Data", chunksection.getDataArray().a);
nbttagcompound1.setByteArray("BlockLight", chunksection.getEmittedLightArray().a);
if (flag) {
nbttagcompound1.setByteArray("SkyLight", chunksection.getSkyLightArray().a);
} else {
nbttagcompound1.setByteArray("SkyLight", new byte[chunksection.getEmittedLightArray().a.length]);
}
nbttagcompound1.setByteArray("Data", chunksection.i().a);
nbttagcompound1.setByteArray("SkyLight", chunksection.k().a);
nbttagcompound1.setByteArray("BlockLight", chunksection.j().a);
nbttaglist.add(nbttagcompound1);
}
}
nbttagcompound.set("Sections", nbttaglist);
nbttagcompound.setByteArray("Biomes", chunk.l());
chunk.m = false;
nbttagcompound.setByteArray("Biomes", chunk.m());
chunk.o = false;
NBTTagList nbttaglist1 = new NBTTagList();
Iterator iterator;
@@ -190,9 +259,9 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
chunk.m = true;
nbttagcompound1 = new NBTTagCompound();
if (entity.c(nbttagcompound1)) {
if (entity.d(nbttagcompound1)) {
chunk.o = true;
nbttaglist1.add(nbttagcompound1);
}
}
@@ -223,11 +292,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
NextTickListEntry nextticklistentry = (NextTickListEntry) iterator1.next();
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
nbttagcompound2.setInt("i", nextticklistentry.d);
nbttagcompound2.setInt("i", Block.getId(nextticklistentry.a()));
nbttagcompound2.setInt("x", nextticklistentry.a);
nbttagcompound2.setInt("y", nextticklistentry.b);
nbttagcompound2.setInt("z", nextticklistentry.c);
nbttagcompound2.setInt("t", (int) (nextticklistentry.e - k));
nbttagcompound2.setInt("t", (int) (nextticklistentry.d - k));
nbttagcompound2.setInt("p", nextticklistentry.e);
nbttaglist3.add(nbttagcompound2);
}
@@ -242,52 +312,76 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
chunk.heightMap = nbttagcompound.getIntArray("HeightMap");
chunk.done = nbttagcompound.getBoolean("TerrainPopulated");
NBTTagList nbttaglist = nbttagcompound.getList("Sections");
chunk.lit = nbttagcompound.getBoolean("LightPopulated");
chunk.s = nbttagcompound.getLong("InhabitedTime");
NBTTagList nbttaglist = nbttagcompound.getList("Sections", 10);
byte b0 = 16;
ChunkSection[] achunksection = new ChunkSection[b0];
boolean flag = !world.worldProvider.g;
for (int k = 0; k < nbttaglist.size(); ++k) {
NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.get(k);
NBTTagCompound nbttagcompound1 = nbttaglist.get(k);
byte b1 = nbttagcompound1.getByte("Y");
ChunkSection chunksection = new ChunkSection(b1 << 4);
ChunkSection chunksection = new ChunkSection(b1 << 4, flag);
chunksection.a(nbttagcompound1.getByteArray("Blocks"));
if (nbttagcompound1.hasKey("Add")) {
chunksection.a(new NibbleArray(nbttagcompound1.getByteArray("Add"), 4));
chunksection.setIdArray(nbttagcompound1.getByteArray("Blocks"));
if (nbttagcompound1.hasKeyOfType("Add", 7)) {
chunksection.setExtendedIdArray(new NibbleArray(nbttagcompound1.getByteArray("Add"), 4));
}
chunksection.b(new NibbleArray(nbttagcompound1.getByteArray("Data"), 4));
chunksection.d(new NibbleArray(nbttagcompound1.getByteArray("SkyLight"), 4));
chunksection.c(new NibbleArray(nbttagcompound1.getByteArray("BlockLight"), 4));
chunksection.d();
chunksection.setDataArray(new NibbleArray(nbttagcompound1.getByteArray("Data"), 4));
chunksection.setEmittedLightArray(new NibbleArray(nbttagcompound1.getByteArray("BlockLight"), 4));
if (flag) {
chunksection.setSkyLightArray(new NibbleArray(nbttagcompound1.getByteArray("SkyLight"), 4));
}
chunksection.recalcBlockCounts();
achunksection[b1] = chunksection;
}
chunk.a(achunksection);
if (nbttagcompound.hasKey("Biomes")) {
if (nbttagcompound.hasKeyOfType("Biomes", 7)) {
chunk.a(nbttagcompound.getByteArray("Biomes"));
}
NBTTagList nbttaglist1 = nbttagcompound.getList("Entities");
// CraftBukkit start - End this method here and split off entity loading to another method
return chunk;
}
public void loadEntities(Chunk chunk, NBTTagCompound nbttagcompound, World world) {
// CraftBukkit end
NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10);
if (nbttaglist1 != null) {
for (int l = 0; l < nbttaglist1.size(); ++l) {
NBTTagCompound nbttagcompound2 = (NBTTagCompound) nbttaglist1.get(l);
NBTTagCompound nbttagcompound2 = nbttaglist1.get(l);
Entity entity = EntityTypes.a(nbttagcompound2, world);
chunk.m = true;
chunk.o = true;
if (entity != null) {
chunk.a(entity);
Entity entity1 = entity;
for (NBTTagCompound nbttagcompound3 = nbttagcompound2; nbttagcompound3.hasKeyOfType("Riding", 10); nbttagcompound3 = nbttagcompound3.getCompound("Riding")) {
Entity entity2 = EntityTypes.a(nbttagcompound3.getCompound("Riding"), world);
if (entity2 != null) {
chunk.a(entity2);
entity1.mount(entity2);
}
entity1 = entity2;
}
}
}
}
NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities");
NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities", 10);
if (nbttaglist2 != null) {
for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) {
NBTTagCompound nbttagcompound3 = (NBTTagCompound) nbttaglist2.get(i1);
TileEntity tileentity = TileEntity.c(nbttagcompound3);
NBTTagCompound nbttagcompound4 = nbttaglist2.get(i1);
TileEntity tileentity = TileEntity.c(nbttagcompound4);
if (tileentity != null) {
chunk.a(tileentity);
@@ -295,18 +389,18 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
if (nbttagcompound.hasKey("TileTicks")) {
NBTTagList nbttaglist3 = nbttagcompound.getList("TileTicks");
if (nbttagcompound.hasKeyOfType("TileTicks", 9)) {
NBTTagList nbttaglist3 = nbttagcompound.getList("TileTicks", 10);
if (nbttaglist3 != null) {
for (int j1 = 0; j1 < nbttaglist3.size(); ++j1) {
NBTTagCompound nbttagcompound4 = (NBTTagCompound) nbttaglist3.get(j1);
NBTTagCompound nbttagcompound5 = nbttaglist3.get(j1);
world.d(nbttagcompound4.getInt("x"), nbttagcompound4.getInt("y"), nbttagcompound4.getInt("z"), nbttagcompound4.getInt("i"), nbttagcompound4.getInt("t"));
world.b(nbttagcompound5.getInt("x"), nbttagcompound5.getInt("y"), nbttagcompound5.getInt("z"), Block.getById(nbttagcompound5.getInt("i")), nbttagcompound5.getInt("t"), nbttagcompound5.getInt("p"));
}
}
}
return chunk;
// return chunk; // CraftBukkit
}
}

View File

@@ -1,135 +1,345 @@
package net.minecraft.server;
import java.util.Arrays; // CraftBukkit
public class ChunkSection {
private int a;
private int b;
private int c;
private byte[] d;
private NibbleArray e;
private NibbleArray f;
private NibbleArray g;
private NibbleArray h;
private int yPos;
private int nonEmptyBlockCount;
private int tickingBlockCount;
private byte[] blockIds;
private NibbleArray extBlockIds;
private NibbleArray blockData;
private NibbleArray emittedLight;
private NibbleArray skyLight;
// CraftBukkit start - Compact storage
private int compactId;
private byte compactExtId;
private byte compactData;
private byte compactEmitted;
private byte compactSky;
public ChunkSection(int i) {
this.a = i;
this.d = new byte[4096];
this.f = new NibbleArray(this.d.length, 4);
this.h = new NibbleArray(this.d.length, 4);
this.g = new NibbleArray(this.d.length, 4);
// Pre-generated (read-only!) NibbleArrays for every possible value, used for chunk saving
private static NibbleArray[] compactPregen = new NibbleArray[16];
static {
for (int i = 0; i < 16; i++) {
compactPregen[i] = expandCompactNibble((byte) i);
}
}
// CraftBukkit start
public ChunkSection(int y, byte[] blkData, byte[] extBlkData) {
this.a = y;
this.d = blkData;
if (extBlkData != null) {
this.e = new NibbleArray(extBlkData, 4);
private static NibbleArray expandCompactNibble(byte value) {
byte[] data = new byte[2048];
Arrays.fill(data, (byte) (value | (value << 4)));
return new NibbleArray(data, 4);
}
private boolean canBeCompact(byte[] array) {
byte value = array[0];
for (int i = 1; i < array.length; i++) {
if (value != array[i]) {
return false;
}
}
this.f = new NibbleArray(this.d.length, 4);
this.h = new NibbleArray(this.d.length, 4);
this.g = new NibbleArray(this.d.length, 4);
this.d();
return true;
}
// CraftBukkit end
public int a(int i, int j, int k) {
int l = this.d[j << 8 | k << 4 | i] & 255;
return this.e != null ? this.e.a(i, j, k) << 8 | l : l;
public ChunkSection(int i, boolean flag) {
this.yPos = i;
/* CraftBukkit - Start as null, using compact storage
this.blockIds = new byte[4096];
this.blockData = new NibbleArray(this.blockIds.length, 4);
this.emittedLight = new NibbleArray(this.blockIds.length, 4);
if (flag) {
this.skyLight = new NibbleArray(this.blockIds.length, 4);
}
*/
if (!flag) {
this.compactSky = -1;
}
// CraftBukkit end
}
public void a(int i, int j, int k, int l) {
int i1 = this.d[j << 8 | k << 4 | i] & 255;
// CraftBukkit start
public ChunkSection(int y, boolean flag, byte[] blkIds, byte[] extBlkIds) {
this.yPos = y;
this.setIdArray(blkIds);
if (extBlkIds != null) {
this.setExtendedIdArray(new NibbleArray(extBlkIds, 4));
}
if (!flag) {
this.compactSky = -1;
}
this.recalcBlockCounts();
}
// CraftBukkit end
if (this.e != null) {
i1 |= this.e.a(i, j, k) << 8;
public Block getTypeId(int i, int j, int k) {
// CraftBukkit start - Compact storage
if (this.blockIds == null) {
int id = this.compactId;
if (this.extBlockIds == null) {
id |= this.compactExtId << 8;
} else {
id |= this.extBlockIds.a(i, j, k) << 8;
}
return Block.getById(id);
}
// CraftBukkit end
int l = this.blockIds[j << 8 | k << 4 | i] & 255;
if (this.extBlockIds != null) {
l |= this.extBlockIds.a(i, j, k) << 8;
}
if (i1 == 0 && l != 0) {
++this.b;
if (Block.byId[l] != null && Block.byId[l].n()) {
++this.c;
return Block.getById(l);
}
public void setTypeId(int i, int j, int k, Block block) {
// CraftBukkit start - Compact storage
Block block1 = this.getTypeId(i, j, k);
if (block == block1) {
return;
}
// CraftBukkit end
if (block1 != Blocks.AIR) {
--this.nonEmptyBlockCount;
if (block1.isTicking()) {
--this.tickingBlockCount;
}
} else if (i1 != 0 && l == 0) {
--this.b;
if (Block.byId[i1] != null && Block.byId[i1].n()) {
--this.c;
}
} else if (Block.byId[i1] != null && Block.byId[i1].n() && (Block.byId[l] == null || !Block.byId[l].n())) {
--this.c;
} else if ((Block.byId[i1] == null || !Block.byId[i1].n()) && Block.byId[l] != null && Block.byId[l].n()) {
++this.c;
}
this.d[j << 8 | k << 4 | i] = (byte) (l & 255);
if (l > 255) {
if (this.e == null) {
this.e = new NibbleArray(this.d.length, 4);
if (block != Blocks.AIR) {
++this.nonEmptyBlockCount;
if (block.isTicking()) {
++this.tickingBlockCount;
}
}
int i1 = Block.getId(block);
// CraftBukkit start - Compact storage
if (this.blockIds == null) {
this.blockIds = new byte[4096];
Arrays.fill(this.blockIds, (byte) (this.compactId & 255));
}
// CraftBukkit end
this.blockIds[j << 8 | k << 4 | i] = (byte) (i1 & 255);
if (i1 > 255) {
if (this.extBlockIds == null) {
this.extBlockIds = expandCompactNibble(this.compactExtId); // CraftBukkit - Compact storage
}
this.e.a(i, j, k, (l & 3840) >> 8);
} else if (this.e != null) {
this.e.a(i, j, k, 0);
this.extBlockIds.a(i, j, k, (i1 & 3840) >> 8);
} else if (this.extBlockIds != null) {
this.extBlockIds.a(i, j, k, 0);
}
}
public int b(int i, int j, int k) {
return this.f.a(i, j, k);
public int getData(int i, int j, int k) {
// CraftBukkit start - Compact storage
if (this.blockData == null) {
return this.compactData;
}
// CraftBukkit end
return this.blockData.a(i, j, k);
}
public void b(int i, int j, int k, int l) {
this.f.a(i, j, k, l);
public void setData(int i, int j, int k, int l) {
// CraftBukkit start - Compact storage
if (this.blockData == null) {
if (this.compactData == l) {
return;
}
this.blockData = expandCompactNibble(this.compactData);
}
// CraftBukkit end
this.blockData.a(i, j, k, l);
}
public boolean a() {
return this.b == 0;
public boolean isEmpty() {
return this.nonEmptyBlockCount == 0;
}
public boolean b() {
return this.c > 0;
public boolean shouldTick() {
return this.tickingBlockCount > 0;
}
public int c() {
return this.a;
public int getYPosition() {
return this.yPos;
}
public void c(int i, int j, int k, int l) {
this.h.a(i, j, k, l);
public void setSkyLight(int i, int j, int k, int l) {
// CraftBukkit start - Compact storage
if (this.skyLight == null) {
if (this.compactSky == l) {
return;
}
this.skyLight = expandCompactNibble(this.compactSky);
}
// CraftBukkit end
this.skyLight.a(i, j, k, l);
}
public int c(int i, int j, int k) {
return this.h.a(i, j, k);
public int getSkyLight(int i, int j, int k) {
// CraftBukkit start - Compact storage
if (this.skyLight == null) {
return this.compactSky;
}
// CraftBukkit end
return this.skyLight.a(i, j, k);
}
public void d(int i, int j, int k, int l) {
this.g.a(i, j, k, l);
public void setEmittedLight(int i, int j, int k, int l) {
// CraftBukkit start - Compact storage
if (this.emittedLight == null) {
if (this.compactEmitted == l) {
return;
}
this.emittedLight = expandCompactNibble(this.compactEmitted);
}
// CraftBukkit end
this.emittedLight.a(i, j, k, l);
}
public int d(int i, int j, int k) {
return this.g.a(i, j, k);
public int getEmittedLight(int i, int j, int k) {
// CraftBukkit start - Compact storage
if (this.emittedLight == null) {
return this.compactEmitted;
}
// CraftBukkit end
return this.emittedLight.a(i, j, k);
}
public void d() {
this.b = 0;
this.c = 0;
public void recalcBlockCounts() {
// CraftBukkit start - Optimize for speed
int cntNonEmpty = 0;
int cntTicking = 0;
if (this.blockIds == null) {
int id = this.compactId;
if (this.extBlockIds == null) {
id |= this.compactExtId << 8;
if (id > 0) {
Block block = Block.getById(id);
if (block == null) {
this.compactId = 0;
this.compactExtId = 0;
} else {
cntNonEmpty = 4096;
if (block.isTicking()) {
cntTicking = 4096;
}
}
}
} else {
byte[] ext = this.extBlockIds.a;
for (int off = 0, off2 = 0; off < 4096;) {
byte extid = ext[off2];
int l = (id & 0xFF) | ((extid & 0xF) << 8); // Even data
if (l > 0) {
Block block = Block.getById(l);
if (block == null) {
this.compactId = 0;
ext[off2] &= 0xF0;
} else {
++cntNonEmpty;
if (block.isTicking()) {
++cntTicking;
}
}
}
off++;
l = (id & 0xFF) | ((extid & 0xF0) << 4); // Odd data
if (l > 0) {
Block block = Block.getById(l);
if (block == null) {
this.compactId = 0;
ext[off2] &= 0x0F;
} else {
++cntNonEmpty;
if (block.isTicking()) {
++cntTicking;
}
}
}
off++;
off2++;
}
}
} else {
byte[] blkIds = this.blockIds;
if (this.extBlockIds == null) { // No extended block IDs? Don't waste time messing with them
for (int off = 0; off < blkIds.length; off++) {
int l = blkIds[off] & 0xFF;
if (l > 0) {
if (Block.getById(l) == null) {
blkIds[off] = 0;
} else {
++cntNonEmpty;
if (Block.getById(l).isTicking()) {
++cntTicking;
}
}
}
}
} else {
byte[] ext = this.extBlockIds.a;
for (int off = 0, off2 = 0; off < blkIds.length;) {
byte extid = ext[off2];
int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data
if (l > 0) {
if (Block.getById(l) == null) {
blkIds[off] = 0;
ext[off2] &= 0xF0;
} else {
++cntNonEmpty;
if (Block.getById(l).isTicking()) {
++cntTicking;
}
}
}
off++;
l = (blkIds[off] & 0xFF) | ((extid & 0xF0) << 4); // Odd data
if (l > 0) {
if (Block.getById(l) == null) {
blkIds[off] = 0;
ext[off2] &= 0x0F;
} else {
++cntNonEmpty;
if (Block.getById(l).isTicking()) {
++cntTicking;
}
}
}
off++;
off2++;
}
}
}
this.nonEmptyBlockCount = cntNonEmpty;
this.tickingBlockCount = cntTicking;
}
public void old_recalcBlockCounts() {
// CraftBukkit end
this.nonEmptyBlockCount = 0;
this.tickingBlockCount = 0;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 16; ++j) {
for (int k = 0; k < 16; ++k) {
int l = this.a(i, j, k);
Block block = this.getTypeId(i, j, k);
if (l > 0) {
if (Block.byId[l] == null) {
this.d[j << 8 | k << 4 | i] = 0;
if (this.e != null) {
this.e.a(i, j, k, 0);
}
} else {
++this.b;
if (Block.byId[l].n()) {
++this.c;
}
if (block != Blocks.AIR) {
++this.nonEmptyBlockCount;
if (block.isTicking()) {
++this.tickingBlockCount;
}
}
}
@@ -137,49 +347,142 @@ public class ChunkSection {
}
}
public void e() {}
public int f() {
return this.b;
public byte[] getIdArray() {
// CraftBukkit start - Compact storage
if (this.blockIds == null) {
byte[] ids = new byte[4096];
Arrays.fill(ids, (byte) (this.compactId & 255));
return ids;
}
// CraftBukkit end
return this.blockIds;
}
public byte[] g() {
return this.d;
public NibbleArray getExtendedIdArray() {
// CraftBukkit start - Compact storage
if (this.extBlockIds == null && this.compactExtId != 0) {
return compactPregen[this.compactExtId];
}
// CraftBukkit end
return this.extBlockIds;
}
public NibbleArray h() {
return this.e;
public NibbleArray getDataArray() {
// CraftBukkit start - Compact storage
if (this.blockData == null) {
return compactPregen[this.compactData];
}
// CraftBukkit end
return this.blockData;
}
public NibbleArray i() {
return this.f;
public NibbleArray getEmittedLightArray() {
// CraftBukkit start - Compact storage
if (this.emittedLight == null) {
return compactPregen[this.compactEmitted];
}
// CraftBukkit end
return this.emittedLight;
}
public NibbleArray j() {
return this.g;
public NibbleArray getSkyLightArray() {
// CraftBukkit start - Compact storage
if (this.skyLight == null && this.compactSky != -1) {
return compactPregen[this.compactSky];
}
// CraftBukkit end
return this.skyLight;
}
public NibbleArray k() {
return this.h;
public void setIdArray(byte[] abyte) {
// CraftBukkit start - Compact storage
if (abyte == null) {
this.compactId = 0;
this.blockIds = null;
return;
} else if (canBeCompact(abyte)) {
this.compactId = abyte[0] & 255;
return;
}
// CraftBukkit end
this.blockIds = this.validateByteArray(abyte); // CraftBukkit - Validate data
}
public void a(byte[] abyte) {
this.d = abyte;
public void setExtendedIdArray(NibbleArray nibblearray) {
// CraftBukkit start - Compact storage
if (nibblearray == null) {
this.compactExtId = 0;
this.extBlockIds = null;
return;
} else if (canBeCompact(nibblearray.a)) {
this.compactExtId = (byte) (nibblearray.a(0, 0, 0) & 0xF);
return;
}
// CraftBukkit end
this.extBlockIds = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
}
public void a(NibbleArray nibblearray) {
this.e = nibblearray;
public void setDataArray(NibbleArray nibblearray) {
// CraftBukkit start - Compact storage
if (nibblearray == null) {
this.compactData = 0;
this.blockData = null;
return;
} else if (canBeCompact(nibblearray.a)) {
this.compactData = (byte) (nibblearray.a(0, 0, 0) & 0xF);
return;
}
// CraftBukkit end
this.blockData = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
}
public void b(NibbleArray nibblearray) {
this.f = nibblearray;
public void setEmittedLightArray(NibbleArray nibblearray) {
// CraftBukkit start - Compact storage
if (nibblearray == null) {
this.compactEmitted = 0;
this.emittedLight = null;
return;
} else if (canBeCompact(nibblearray.a)) {
this.compactEmitted = (byte) (nibblearray.a(0, 0, 0) & 0xF);
return;
}
// CraftBukkit end
this.emittedLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
}
public void c(NibbleArray nibblearray) {
this.g = nibblearray;
public void setSkyLightArray(NibbleArray nibblearray) {
// CraftBukkit start - Compact storage
if (nibblearray == null) {
this.compactSky = -1;
this.skyLight = null;
return;
} else if (canBeCompact(nibblearray.a)) {
this.compactSky = (byte) (nibblearray.a(0, 0, 0) & 0xF);
return;
}
// CraftBukkit end
this.skyLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
}
public void d(NibbleArray nibblearray) {
this.h = nibblearray;
// CraftBukkit start - Validate array lengths
private NibbleArray validateNibbleArray(NibbleArray nibbleArray) {
if (nibbleArray != null && nibbleArray.a.length < 2048) {
byte[] newArray = new byte[2048];
System.arraycopy(nibbleArray.a, 0, newArray, 0, nibbleArray.a.length);
nibbleArray = new NibbleArray(newArray, 4);
}
return nibbleArray;
}
private byte[] validateByteArray(byte[] byteArray) {
if (byteArray != null && byteArray.length < 4096) {
byte[] newArray = new byte[4096];
System.arraycopy(byteArray, 0, newArray, 0, byteArray.length);
byteArray = newArray;
}
return byteArray;
}
// CraftBukkit end
}

View File

@@ -0,0 +1,27 @@
package net.minecraft.server;
// CraftBukkit - import package private class
class ClientCommandOrdinalWrapper {
static final int[] a = new int[EnumClientCommand.values().length];
static {
try {
a[EnumClientCommand.PERFORM_RESPAWN.ordinal()] = 1;
} catch (NoSuchFieldError nosuchfielderror) {
;
}
try {
a[EnumClientCommand.REQUEST_STATS.ordinal()] = 2;
} catch (NoSuchFieldError nosuchfielderror1) {
;
}
try {
a[EnumClientCommand.OPEN_INVENTORY_ACHIEVEMENT.ordinal()] = 3;
} catch (NoSuchFieldError nosuchfielderror2) {
;
}
}
}

View File

@@ -0,0 +1,230 @@
package net.minecraft.server;
import java.text.SimpleDateFormat;
import java.util.Date;
// CraftBukkit start
import java.util.ArrayList;
import org.apache.logging.log4j.Level;
import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
import com.google.common.base.Joiner;
// CraftBukkit end
public abstract class CommandBlockListenerAbstract implements ICommandListener {
private static final SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss");
private int b;
private boolean c = true;
private IChatBaseComponent d = null;
public String e = ""; // CraftBukkit - private -> public
private String f = "@";
protected org.bukkit.command.CommandSender sender; // CraftBukkit - add sender;
public CommandBlockListenerAbstract() {}
public int g() {
return this.b;
}
public IChatBaseComponent h() {
return this.d;
}
public void a(NBTTagCompound nbttagcompound) {
nbttagcompound.setString("Command", this.e);
nbttagcompound.setInt("SuccessCount", this.b);
nbttagcompound.setString("CustomName", this.f);
if (this.d != null) {
nbttagcompound.setString("LastOutput", ChatSerializer.a(this.d));
}
nbttagcompound.setBoolean("TrackOutput", this.c);
}
public void b(NBTTagCompound nbttagcompound) {
this.e = nbttagcompound.getString("Command");
this.b = nbttagcompound.getInt("SuccessCount");
if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
this.f = nbttagcompound.getString("CustomName");
}
if (nbttagcompound.hasKeyOfType("LastOutput", 8)) {
this.d = ChatSerializer.a(nbttagcompound.getString("LastOutput"));
}
if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) {
this.c = nbttagcompound.getBoolean("TrackOutput");
}
}
public boolean a(int i, String s) {
return i <= 2;
}
public void setCommand(String s) {
this.e = s;
}
public String getCommand() {
return this.e;
}
public void a(World world) {
if (world.isStatic) {
this.b = 0;
}
MinecraftServer minecraftserver = MinecraftServer.getServer();
if (minecraftserver != null && minecraftserver.getEnableCommandBlock()) {
// CraftBukkit start - Handle command block commands using Bukkit dispatcher
org.bukkit.command.SimpleCommandMap commandMap = minecraftserver.server.getCommandMap();
Joiner joiner = Joiner.on(" ");
String command = this.e;
if (this.e.startsWith("/")) {
command = this.e.substring(1);
}
String[] args = command.split(" ");
ArrayList<String[]> commands = new ArrayList<String[]>();
// Block disallowed commands
if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("kick") || args[0].equalsIgnoreCase("op") ||
args[0].equalsIgnoreCase("deop") || args[0].equalsIgnoreCase("ban") || args[0].equalsIgnoreCase("ban-ip") ||
args[0].equalsIgnoreCase("pardon") || args[0].equalsIgnoreCase("pardon-ip") || args[0].equalsIgnoreCase("reload")) {
this.b = 0;
return;
}
// If the world has no players don't run
if (this.getWorld().players.isEmpty()) {
this.b = 0;
return;
}
// Handle vanilla commands;
if (minecraftserver.server.getCommandBlockOverride(args[0])) {
org.bukkit.command.Command commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]);
if (commandBlockCommand instanceof VanillaCommandWrapper) {
this.b = ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommandBlock(this, this.e);
return;
}
}
// Make sure this is a valid command
if (commandMap.getCommand(args[0]) == null) {
this.b = 0;
return;
}
// testfor command requires special handling
if (args[0].equalsIgnoreCase("testfor")) {
if (args.length < 2) {
this.b = 0;
return;
}
EntityPlayer[] players = PlayerSelector.getPlayers(this, args[1]);
if (players != null && players.length > 0) {
this.b = players.length;
return;
} else {
EntityPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(args[1]);
if (player == null) {
this.b = 0;
return;
} else {
this.b = 1;
return;
}
}
}
commands.add(args);
// Find positions of command block syntax, if any
ArrayList<String[]> newCommands = new ArrayList<String[]>();
for (int i = 0; i < args.length; i++) {
if (PlayerSelector.isPattern(args[i])) {
for (int j = 0; j < commands.size(); j++) {
newCommands.addAll(this.buildCommands(commands.get(j), i));
}
ArrayList<String[]> temp = commands;
commands = newCommands;
newCommands = temp;
newCommands.clear();
}
}
int completed = 0;
// Now dispatch all of the commands we ended up with
for (int i = 0; i < commands.size(); i++) {
try {
if (commandMap.dispatch(sender, joiner.join(java.util.Arrays.asList(commands.get(i))))) {
completed++;
}
} catch (Throwable exception) {
if(this instanceof TileEntityCommandListener) {
TileEntityCommandListener listener = (TileEntityCommandListener) this;
MinecraftServer.getLogger().log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().x, listener.getChunkCoordinates().y, listener.getChunkCoordinates().z), exception);
} else if (this instanceof EntityMinecartCommandBlockListener) {
EntityMinecartCommandBlockListener listener = (EntityMinecartCommandBlockListener) this;
MinecraftServer.getLogger().log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().x, listener.getChunkCoordinates().y, listener.getChunkCoordinates().z), exception);
} else {
MinecraftServer.getLogger().log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), exception);
}
}
}
this.b = completed;
// CraftBukkit end
} else {
this.b = 0;
}
}
// CraftBukkit start
private ArrayList<String[]> buildCommands(String[] args, int pos) {
ArrayList<String[]> commands = new ArrayList<String[]>();
EntityPlayer[] players = PlayerSelector.getPlayers(this, args[pos]);
if (players != null) {
for (EntityPlayer player : players) {
if (player.world != this.getWorld()) {
continue;
}
String[] command = args.clone();
command[pos] = player.getName();
commands.add(command);
}
}
return commands;
}
// CraftBukkit end
public String getName() {
return this.f;
}
public IChatBaseComponent getScoreboardDisplayName() {
return new ChatComponentText(this.getName());
}
public void setName(String s) {
this.f = s;
}
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
if (this.c && this.getWorld() != null && !this.getWorld().isStatic) {
this.d = (new ChatComponentText("[" + a.format(new Date()) + "] ")).addSibling(ichatbasecomponent);
this.e();
}
}
public abstract void e();
public void b(IChatBaseComponent ichatbasecomponent) {
this.d = ichatbasecomponent;
}
}

View File

@@ -1,63 +0,0 @@
package net.minecraft.server;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
final class ConsoleLogFormatter extends Formatter {
private SimpleDateFormat a = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// CraftBukkit start - add color stripping, change constructor to take it
private java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
private boolean strip = false;
ConsoleLogFormatter(boolean strip) {
this.strip = strip;
}
// CraftBukkit end
public String format(LogRecord logrecord) {
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append(this.a.format(Long.valueOf(logrecord.getMillis())));
Level level = logrecord.getLevel();
if (level == Level.FINEST) {
stringbuilder.append(" [FINEST] ");
} else if (level == Level.FINER) {
stringbuilder.append(" [FINER] ");
} else if (level == Level.FINE) {
stringbuilder.append(" [FINE] ");
} else if (level == Level.INFO) {
stringbuilder.append(" [INFO] ");
} else if (level == Level.WARNING) {
stringbuilder.append(" [WARNING] ");
} else if (level == Level.SEVERE) {
stringbuilder.append(" [SEVERE] ");
} else if (level == Level.SEVERE) {
stringbuilder.append(" [" + level.getLocalizedName() + "] ");
}
stringbuilder.append(logrecord.getMessage());
stringbuilder.append('\n');
Throwable throwable = logrecord.getThrown();
if (throwable != null) {
StringWriter stringwriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(stringwriter));
stringbuilder.append(stringwriter.toString());
}
// CraftBukkit start - handle stripping color
if (this.strip) {
return this.pattern.matcher(stringbuilder.toString()).replaceAll("");
} else {
return stringbuilder.toString();
}
// CraftBukkit end
}
}

View File

@@ -1,57 +0,0 @@
package net.minecraft.server;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
// CraftBukkit start
import java.util.logging.Handler;
import org.bukkit.craftbukkit.util.ShortConsoleLogFormatter;
import org.bukkit.craftbukkit.util.TerminalConsoleHandler;
// CraftBukkit end
public class ConsoleLogManager {
public static Logger a = Logger.getLogger("Minecraft");
public static Logger global = Logger.getLogger(""); // CraftBukkit
public ConsoleLogManager() {
}
// CraftBukkit - change of method signature!
public static void init(MinecraftServer server) {
ConsoleLogFormatter consolelogformatter = new ConsoleLogFormatter(server.options.has("log-strip-color")); // CraftBukkit - pass strip color option
a.setUseParentHandlers(false);
// CraftBukkit start
ConsoleHandler consolehandler = new TerminalConsoleHandler(server.reader);
for (Handler handler : global.getHandlers()) {
global.removeHandler(handler);
}
consolehandler.setFormatter(new ShortConsoleLogFormatter(server));
global.addHandler(consolehandler);
// CraftBukkit end
a.addHandler(consolehandler);
try {
// CraftBukkit start
String pattern = (String) server.options.valueOf("log-pattern");
int limit = ((Integer) server.options.valueOf("log-limit")).intValue();
int count = ((Integer) server.options.valueOf("log-count")).intValue();
boolean append = ((Boolean) server.options.valueOf("log-append")).booleanValue();
FileHandler filehandler = new FileHandler(pattern, limit, count, append);
// CraftBukkit end
filehandler.setFormatter(consolelogformatter);
a.addHandler(filehandler);
global.addHandler(filehandler); // CraftBukkit
} catch (Exception exception) {
a.log(Level.WARNING, "Failed to log to server.log", exception);
}
}
}

View File

@@ -2,28 +2,36 @@ package net.minecraft.server;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
// CraftBukkit start
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
public abstract class Container {
public List d = new ArrayList();
public List e = new ArrayList();
public int windowId = 0;
private short a = 0;
public List b = new ArrayList();
public List c = new ArrayList();
public int windowId;
private int dragType = -1;
public int g; // CraftBukkit - private -> public
private final Set h = new HashSet();
protected List listeners = new ArrayList();
private Set b = new HashSet();
private Set i = new HashSet();
// CraftBukkit start
public boolean checkReachable = true;
public abstract InventoryView getBukkitView();
public void transferTo(Container other, CraftHumanEntity player) {
public void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player) {
InventoryView source = this.getBukkitView(), destination = other.getBukkitView();
((CraftInventory) source.getTopInventory()).getInventory().onClose(player);
((CraftInventory) source.getBottomInventory()).getInventory().onClose(player);
@@ -34,10 +42,11 @@ public abstract class Container {
public Container() {}
protected void a(Slot slot) {
slot.c = this.e.size();
this.e.add(slot);
this.d.add(null);
protected Slot a(Slot slot) {
slot.rawSlotIndex = this.c.size();
this.c.add(slot);
this.b.add(null);
return slot;
}
public void addSlotListener(ICrafting icrafting) {
@@ -45,29 +54,29 @@ public abstract class Container {
throw new IllegalArgumentException("Listener already listening");
} else {
this.listeners.add(icrafting);
icrafting.a(this, this.b());
this.a();
icrafting.a(this, this.a());
this.b();
}
}
public List b() {
public List a() {
ArrayList arraylist = new ArrayList();
for (int i = 0; i < this.e.size(); ++i) {
arraylist.add(((Slot) this.e.get(i)).getItem());
for (int i = 0; i < this.c.size(); ++i) {
arraylist.add(((Slot) this.c.get(i)).getItem());
}
return arraylist;
}
public void a() {
for (int i = 0; i < this.e.size(); ++i) {
ItemStack itemstack = ((Slot) this.e.get(i)).getItem();
ItemStack itemstack1 = (ItemStack) this.d.get(i);
public void b() {
for (int i = 0; i < this.c.size(); ++i) {
ItemStack itemstack = ((Slot) this.c.get(i)).getItem();
ItemStack itemstack1 = (ItemStack) this.b.get(i);
if (!ItemStack.matches(itemstack1, itemstack)) {
itemstack1 = itemstack == null ? null : itemstack.cloneItemStack();
this.d.set(i, itemstack1);
this.b.set(i, itemstack1);
for (int j = 0; j < this.listeners.size(); ++j) {
((ICrafting) this.listeners.get(j)).a(this, i, itemstack1);
@@ -80,9 +89,9 @@ public abstract class Container {
return false;
}
public Slot a(IInventory iinventory, int i) {
for (int j = 0; j < this.e.size(); ++j) {
Slot slot = (Slot) this.e.get(j);
public Slot getSlot(IInventory iinventory, int i) {
for (int j = 0; j < this.c.size(); ++j) {
Slot slot = (Slot) this.c.get(j);
if (slot.a(iinventory, i)) {
return slot;
@@ -93,49 +102,158 @@ public abstract class Container {
}
public Slot getSlot(int i) {
return (Slot) this.e.get(i);
return (Slot) this.c.get(i);
}
public ItemStack a(int i) {
Slot slot = (Slot) this.e.get(i);
public ItemStack b(EntityHuman entityhuman, int i) {
Slot slot = (Slot) this.c.get(i);
return slot != null ? slot.getItem() : null;
}
public ItemStack clickItem(int i, int j, boolean flag, EntityHuman entityhuman) {
public ItemStack clickItem(int i, int j, int k, EntityHuman entityhuman) {
ItemStack itemstack = null;
PlayerInventory playerinventory = entityhuman.inventory;
int l;
ItemStack itemstack1;
if (j > 1) {
return null;
if (k == 5) {
int i1 = this.g;
this.g = c(j);
if ((i1 != 1 || this.g != 2) && i1 != this.g) {
this.d();
} else if (playerinventory.getCarried() == null) {
this.d();
} else if (this.g == 0) {
this.dragType = b(j);
if (d(this.dragType)) {
this.g = 1;
this.h.clear();
} else {
this.d();
}
} else if (this.g == 1) {
Slot slot = (Slot) this.c.get(i);
if (slot != null && a(slot, playerinventory.getCarried(), true) && slot.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count > this.h.size() && this.b(slot)) {
this.h.add(slot);
}
} else if (this.g == 2) {
if (!this.h.isEmpty()) {
itemstack1 = playerinventory.getCarried().cloneItemStack();
l = playerinventory.getCarried().count;
Iterator iterator = this.h.iterator();
Map<Integer, ItemStack> draggedSlots = new HashMap<Integer, ItemStack>(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack)
while (iterator.hasNext()) {
Slot slot1 = (Slot) iterator.next();
if (slot1 != null && a(slot1, playerinventory.getCarried(), true) && slot1.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count >= this.h.size() && this.b(slot1)) {
ItemStack itemstack2 = itemstack1.cloneItemStack();
int j1 = slot1.hasItem() ? slot1.getItem().count : 0;
a(this.h, this.dragType, itemstack2, j1);
if (itemstack2.count > itemstack2.getMaxStackSize()) {
itemstack2.count = itemstack2.getMaxStackSize();
}
if (itemstack2.count > slot1.getMaxStackSize()) {
itemstack2.count = slot1.getMaxStackSize();
}
l -= itemstack2.count - j1;
draggedSlots.put(slot1.rawSlotIndex, itemstack2); // CraftBukkit - Put in map instead of setting
}
}
// CraftBukkit start - InventoryDragEvent
InventoryView view = getBukkitView();
org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack1);
newcursor.setAmount(l);
Map<Integer, org.bukkit.inventory.ItemStack> eventmap = new HashMap<Integer, org.bukkit.inventory.ItemStack>();
for (Map.Entry<Integer, ItemStack> ditem : draggedSlots.entrySet()) {
eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue()));
}
// It's essential that we set the cursor to the new value here to prevent item duplication if a plugin closes the inventory.
ItemStack oldCursor = playerinventory.getCarried();
playerinventory.setCarried(CraftItemStack.asNMSCopy(newcursor));
InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.dragType == 1, eventmap);
entityhuman.world.getServer().getPluginManager().callEvent(event);
// Whether or not a change was made to the inventory that requires an update.
boolean needsUpdate = event.getResult() != Result.DEFAULT;
if (event.getResult() != Result.DENY) {
for (Map.Entry<Integer, ItemStack> dslot : draggedSlots.entrySet()) {
view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue()));
}
// The only time the carried item will be set to null is if the inventory is closed by the server.
// If the inventory is closed by the server, then the cursor items are dropped. This is why we change the cursor early.
if (playerinventory.getCarried() != null) {
playerinventory.setCarried(CraftItemStack.asNMSCopy(event.getCursor()));
needsUpdate = true;
}
} else {
playerinventory.setCarried(oldCursor);
}
if (needsUpdate && entityhuman instanceof EntityPlayer) {
((EntityPlayer) entityhuman).updateInventory(this);
}
// CraftBukkit end
}
this.d();
} else {
this.d();
}
} else if (this.g != 0) {
this.d();
} else {
if (j == 0 || j == 1) {
PlayerInventory playerinventory = entityhuman.inventory;
Slot slot2;
int k1;
ItemStack itemstack3;
if ((k == 0 || k == 1) && (j == 0 || j == 1)) {
if (i == -999) {
if (playerinventory.getCarried() != null && i == -999) {
if (j == 0) {
entityhuman.drop(playerinventory.getCarried());
entityhuman.drop(playerinventory.getCarried(), true);
playerinventory.setCarried((ItemStack) null);
}
if (j == 1) {
entityhuman.drop(playerinventory.getCarried().a(1));
if (playerinventory.getCarried().count == 0) {
// CraftBukkit start - Store a reference
ItemStack itemstack4 = playerinventory.getCarried();
if (itemstack4.count > 0) {
entityhuman.drop(itemstack4.a(1), true);
}
if (itemstack4.count == 0) {
// CraftBukkit end
playerinventory.setCarried((ItemStack) null);
}
}
}
} else if (flag) {
ItemStack itemstack1 = this.a(i);
} else if (k == 1) {
if (i < 0) {
return null;
}
if (itemstack1 != null) {
int k = itemstack1.id;
slot2 = (Slot) this.c.get(i);
if (slot2 != null && slot2.isAllowed(entityhuman)) {
itemstack1 = this.b(entityhuman, i);
if (itemstack1 != null) {
Item item = itemstack1.getItem();
itemstack = itemstack1.cloneItemStack();
Slot slot = (Slot) this.e.get(i);
if (slot != null && slot.getItem() != null && slot.getItem().id == k) {
this.b(i, j, flag, entityhuman);
itemstack = itemstack1.cloneItemStack();
if (slot2.getItem() != null && slot2.getItem().getItem() == item) {
this.a(i, j, true, entityhuman);
}
}
}
} else {
@@ -143,97 +261,200 @@ public abstract class Container {
return null;
}
Slot slot1 = (Slot) this.e.get(i);
slot2 = (Slot) this.c.get(i);
if (slot2 != null) {
itemstack1 = slot2.getItem();
ItemStack itemstack4 = playerinventory.getCarried();
if (slot1 != null) {
slot1.d();
ItemStack itemstack2 = slot1.getItem();
ItemStack itemstack3 = playerinventory.getCarried();
if (itemstack2 != null) {
itemstack = itemstack2.cloneItemStack();
if (itemstack1 != null) {
itemstack = itemstack1.cloneItemStack();
}
int l;
if (itemstack2 == null) {
if (itemstack3 != null && slot1.isAllowed(itemstack3)) {
l = j == 0 ? itemstack3.count : 1;
if (l > slot1.a()) {
l = slot1.a();
if (itemstack1 == null) {
if (itemstack4 != null && slot2.isAllowed(itemstack4)) {
k1 = j == 0 ? itemstack4.count : 1;
if (k1 > slot2.getMaxStackSize()) {
k1 = slot2.getMaxStackSize();
}
slot1.set(itemstack3.a(l));
if (itemstack3.count == 0) {
if (itemstack4.count >= k1) {
slot2.set(itemstack4.a(k1));
}
if (itemstack4.count == 0) {
playerinventory.setCarried((ItemStack) null);
// CraftBukkit start - Update client cursor if we didn't empty it
} else if (entityhuman instanceof EntityPlayer) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried()));
}
// CraftBukkit end
}
} else if (itemstack3 == null) {
l = j == 0 ? itemstack2.count : (itemstack2.count + 1) / 2;
ItemStack itemstack4 = slot1.a(l);
} else if (slot2.isAllowed(entityhuman)) {
if (itemstack4 == null) {
k1 = j == 0 ? itemstack1.count : (itemstack1.count + 1) / 2;
itemstack3 = slot2.a(k1);
playerinventory.setCarried(itemstack3);
if (itemstack1.count == 0) {
slot2.set((ItemStack) null);
}
playerinventory.setCarried(itemstack4);
if (itemstack2.count == 0) {
slot1.set((ItemStack) null);
slot2.a(entityhuman, playerinventory.getCarried());
} else if (slot2.isAllowed(itemstack4)) {
if (itemstack1.getItem() == itemstack4.getItem() && itemstack1.getData() == itemstack4.getData() && ItemStack.equals(itemstack1, itemstack4)) {
k1 = j == 0 ? itemstack4.count : 1;
if (k1 > slot2.getMaxStackSize() - itemstack1.count) {
k1 = slot2.getMaxStackSize() - itemstack1.count;
}
if (k1 > itemstack4.getMaxStackSize() - itemstack1.count) {
k1 = itemstack4.getMaxStackSize() - itemstack1.count;
}
itemstack4.a(k1);
if (itemstack4.count == 0) {
playerinventory.setCarried((ItemStack) null);
// CraftBukkit start - Update client cursor if we didn't empty it
} else if (entityhuman instanceof EntityPlayer) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried()));
}
// CraftBukkit end
itemstack1.count += k1;
} else if (itemstack4.count <= slot2.getMaxStackSize()) {
slot2.set(itemstack4);
playerinventory.setCarried(itemstack1);
}
} else if (itemstack1.getItem() == itemstack4.getItem() && itemstack4.getMaxStackSize() > 1 && (!itemstack1.usesData() || itemstack1.getData() == itemstack4.getData()) && ItemStack.equals(itemstack1, itemstack4)) {
k1 = itemstack1.count;
// CraftBukkit start - itemstack4.getMaxStackSize() -> maxStack
int maxStack = Math.min(itemstack4.getMaxStackSize(), slot2.getMaxStackSize());
if (k1 > 0 && k1 + itemstack4.count <= maxStack) {
// CraftBukkit end
itemstack4.count += k1;
itemstack1 = slot2.a(k1);
if (itemstack1.count == 0) {
slot2.set((ItemStack) null);
}
slot2.a(entityhuman, playerinventory.getCarried());
// CraftBukkit start - Update client cursor if we didn't empty it
} else if (entityhuman instanceof EntityPlayer) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried()));
}
// CraftBukkit end
}
}
slot1.c(playerinventory.getCarried());
} else if (slot1.isAllowed(itemstack3)) {
if (itemstack2.id == itemstack3.id && (!itemstack2.usesData() || itemstack2.getData() == itemstack3.getData()) && ItemStack.equals(itemstack2, itemstack3)) {
l = j == 0 ? itemstack3.count : 1;
if (l > slot1.a() - itemstack2.count) {
l = slot1.a() - itemstack2.count;
}
if (l > itemstack3.getMaxStackSize() - itemstack2.count) {
l = itemstack3.getMaxStackSize() - itemstack2.count;
}
itemstack3.a(l);
if (itemstack3.count == 0) {
playerinventory.setCarried((ItemStack) null);
}
itemstack2.count += l;
} else if (itemstack3.count <= slot1.a()) {
slot1.set(itemstack3);
playerinventory.setCarried(itemstack2);
slot2.f();
// CraftBukkit start - Make sure the client has the right slot contents
if (entityhuman instanceof EntityPlayer && slot2.getMaxStackSize() != 64) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem()));
// Updating a crafting inventory makes the client reset the result slot, have to send it again
if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem()));
}
} else if (itemstack2.id == itemstack3.id && itemstack3.getMaxStackSize() > 1 && (!itemstack2.usesData() || itemstack2.getData() == itemstack3.getData()) && ItemStack.equals(itemstack2, itemstack3)) {
l = itemstack2.count;
if (l > 0 && l + itemstack3.count <= itemstack3.getMaxStackSize()) {
itemstack3.count += l;
itemstack2 = slot1.a(l);
if (itemstack2.count == 0) {
slot1.set((ItemStack) null);
}
// CraftBukkit end
}
}
} else if (k == 2 && j >= 0 && j < 9) {
slot2 = (Slot) this.c.get(i);
if (slot2.isAllowed(entityhuman)) {
itemstack1 = playerinventory.getItem(j);
boolean flag = itemstack1 == null || slot2.inventory == playerinventory && slot2.isAllowed(itemstack1);
k1 = -1;
if (!flag) {
k1 = playerinventory.getFirstEmptySlotIndex();
flag |= k1 > -1;
}
if (slot2.hasItem() && flag) {
itemstack3 = slot2.getItem();
playerinventory.setItem(j, itemstack3.cloneItemStack());
if ((slot2.inventory != playerinventory || !slot2.isAllowed(itemstack1)) && itemstack1 != null) {
if (k1 > -1) {
playerinventory.pickup(itemstack1);
slot2.a(itemstack3.count);
slot2.set((ItemStack) null);
slot2.a(entityhuman, itemstack3);
}
} else {
slot2.a(itemstack3.count);
slot2.set(itemstack1);
slot2.a(entityhuman, itemstack3);
}
} else if (!slot2.hasItem() && itemstack1 != null && slot2.isAllowed(itemstack1)) {
playerinventory.setItem(j, (ItemStack) null);
slot2.set(itemstack1);
}
}
} else if (k == 3 && entityhuman.abilities.canInstantlyBuild && playerinventory.getCarried() == null && i >= 0) {
slot2 = (Slot) this.c.get(i);
if (slot2 != null && slot2.hasItem()) {
itemstack1 = slot2.getItem().cloneItemStack();
itemstack1.count = itemstack1.getMaxStackSize();
playerinventory.setCarried(itemstack1);
}
} else if (k == 4 && playerinventory.getCarried() == null && i >= 0) {
slot2 = (Slot) this.c.get(i);
if (slot2 != null && slot2.hasItem() && slot2.isAllowed(entityhuman)) {
itemstack1 = slot2.a(j == 0 ? 1 : slot2.getItem().count);
slot2.a(entityhuman, itemstack1);
entityhuman.drop(itemstack1, true);
}
} else if (k == 6 && i >= 0) {
slot2 = (Slot) this.c.get(i);
itemstack1 = playerinventory.getCarried();
if (itemstack1 != null && (slot2 == null || !slot2.hasItem() || !slot2.isAllowed(entityhuman))) {
l = j == 0 ? 0 : this.c.size() - 1;
k1 = j == 0 ? 1 : -1;
for (int l1 = 0; l1 < 2; ++l1) {
for (int i2 = l; i2 >= 0 && i2 < this.c.size() && itemstack1.count < itemstack1.getMaxStackSize(); i2 += k1) {
Slot slot3 = (Slot) this.c.get(i2);
if (slot3.hasItem() && a(slot3, itemstack1, true) && slot3.isAllowed(entityhuman) && this.a(itemstack1, slot3) && (l1 != 0 || slot3.getItem().count != slot3.getItem().getMaxStackSize())) {
int j2 = Math.min(itemstack1.getMaxStackSize() - itemstack1.count, slot3.getItem().count);
ItemStack itemstack5 = slot3.a(j2);
itemstack1.count += j2;
if (itemstack5.count <= 0) {
slot3.set((ItemStack) null);
}
slot1.c(playerinventory.getCarried());
slot3.a(entityhuman, itemstack5);
}
}
}
}
this.b();
}
return itemstack;
}
return itemstack;
}
protected void b(int i, int j, boolean flag, EntityHuman entityhuman) {
this.clickItem(i, j, flag, entityhuman);
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
public void a(EntityHuman entityhuman) {
protected void a(int i, int j, boolean flag, EntityHuman entityhuman) {
this.clickItem(i, j, 1, entityhuman);
}
public void b(EntityHuman entityhuman) {
PlayerInventory playerinventory = entityhuman.inventory;
if (playerinventory.getCarried() != null) {
entityhuman.drop(playerinventory.getCarried());
entityhuman.drop(playerinventory.getCarried(), false);
playerinventory.setCarried((ItemStack) null);
}
}
public void a(IInventory iinventory) {
this.a();
this.b();
}
public void setItem(int i, ItemStack itemstack) {
@@ -241,18 +462,18 @@ public abstract class Container {
}
public boolean c(EntityHuman entityhuman) {
return !this.b.contains(entityhuman);
return !this.i.contains(entityhuman);
}
public void a(EntityHuman entityhuman, boolean flag) {
if (flag) {
this.b.remove(entityhuman);
this.i.remove(entityhuman);
} else {
this.b.add(entityhuman);
this.i.add(entityhuman);
}
}
public abstract boolean b(EntityHuman entityhuman);
public abstract boolean a(EntityHuman entityhuman);
protected boolean a(ItemStack itemstack, int i, int j, boolean flag) {
boolean flag1 = false;
@@ -267,22 +488,25 @@ public abstract class Container {
if (itemstack.isStackable()) {
while (itemstack.count > 0 && (!flag && k < j || flag && k >= i)) {
slot = (Slot) this.e.get(k);
slot = (Slot) this.c.get(k);
itemstack1 = slot.getItem();
if (itemstack1 != null && itemstack1.id == itemstack.id && (!itemstack.usesData() || itemstack.getData() == itemstack1.getData()) && ItemStack.equals(itemstack, itemstack1)) {
if (itemstack1 != null && itemstack1.getItem() == itemstack.getItem() && (!itemstack.usesData() || itemstack.getData() == itemstack1.getData()) && ItemStack.equals(itemstack, itemstack1)) {
int l = itemstack1.count + itemstack.count;
if (l <= itemstack.getMaxStackSize()) {
// CraftBukkit start - itemstack.getMaxStackSize() -> maxStack
int maxStack = Math.min(itemstack.getMaxStackSize(), slot.getMaxStackSize());
if (l <= maxStack) {
itemstack.count = 0;
itemstack1.count = l;
slot.d();
slot.f();
flag1 = true;
} else if (itemstack1.count < itemstack.getMaxStackSize()) {
itemstack.count -= itemstack.getMaxStackSize() - itemstack1.count;
itemstack1.count = itemstack.getMaxStackSize();
slot.d();
} else if (itemstack1.count < maxStack) {
itemstack.count -= maxStack - itemstack1.count;
itemstack1.count = maxStack;
slot.f();
flag1 = true;
}
// CraftBukkit end
}
if (flag) {
@@ -301,11 +525,11 @@ public abstract class Container {
}
while (!flag && k < j || flag && k >= i) {
slot = (Slot) this.e.get(k);
slot = (Slot) this.c.get(k);
itemstack1 = slot.getItem();
if (itemstack1 == null) {
slot.set(itemstack.cloneItemStack());
slot.d();
slot.f();
itemstack.count = 0;
flag1 = true;
break;
@@ -321,4 +545,71 @@ public abstract class Container {
return flag1;
}
public static int b(int i) {
return i >> 2 & 3;
}
public static int c(int i) {
return i & 3;
}
public static boolean d(int i) {
return i == 0 || i == 1;
}
protected void d() {
this.g = 0;
this.h.clear();
}
public static boolean a(Slot slot, ItemStack itemstack, boolean flag) {
boolean flag1 = slot == null || !slot.hasItem();
if (slot != null && slot.hasItem() && itemstack != null && itemstack.doMaterialsMatch(slot.getItem()) && ItemStack.equals(slot.getItem(), itemstack)) {
int i = flag ? 0 : itemstack.count;
flag1 |= slot.getItem().count + i <= itemstack.getMaxStackSize();
}
return flag1;
}
public static void a(Set set, int i, ItemStack itemstack, int j) {
switch (i) {
case 0:
itemstack.count = MathHelper.d((float) itemstack.count / (float) set.size());
break;
case 1:
itemstack.count = 1;
}
itemstack.count += j;
}
public boolean b(Slot slot) {
return true;
}
public static int b(IInventory iinventory) {
if (iinventory == null) {
return 0;
} else {
int i = 0;
float f = 0.0F;
for (int j = 0; j < iinventory.getSize(); ++j) {
ItemStack itemstack = iinventory.getItem(j);
if (itemstack != null) {
f += (float) itemstack.count / (float) Math.min(iinventory.getMaxStackSize(), itemstack.getMaxStackSize());
++i;
}
}
f /= (float) iinventory.getSize();
return MathHelper.d(f * 14.0F) + (i > 0 ? 1 : 0);
}
}
}

View File

@@ -0,0 +1,400 @@
package net.minecraft.server;
import java.util.Iterator;
import java.util.Map;
import net.minecraft.util.org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit
public class ContainerAnvil extends Container {
private static final Logger f = LogManager.getLogger();
private IInventory g = new InventoryCraftResult();
private IInventory h = new ContainerAnvilInventory(this, "Repair", true, 2);
private World i;
private int j;
private int k;
private int l;
public int a;
private int m;
private String n;
private final EntityHuman o;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
// CraftBukkit end
public ContainerAnvil(PlayerInventory playerinventory, World world, int i, int j, int k, EntityHuman entityhuman) {
this.player = playerinventory; // CraftBukkit
this.i = world;
this.j = i;
this.k = j;
this.l = k;
this.o = entityhuman;
this.a(new Slot(this.h, 0, 27, 47));
this.a(new Slot(this.h, 1, 76, 47));
this.a((Slot) (new SlotAnvilResult(this, this.g, 2, 134, 47, world, i, j, k)));
int l;
for (l = 0; l < 3; ++l) {
for (int i1 = 0; i1 < 9; ++i1) {
this.a(new Slot(playerinventory, i1 + l * 9 + 9, 8 + i1 * 18, 84 + l * 18));
}
}
for (l = 0; l < 9; ++l) {
this.a(new Slot(playerinventory, l, 8 + l * 18, 142));
}
}
public void a(IInventory iinventory) {
super.a(iinventory);
if (iinventory == this.h) {
this.e();
}
}
public void e() {
ItemStack itemstack = this.h.getItem(0);
this.a = 0;
int i = 0;
byte b0 = 0;
int j = 0;
if (itemstack == null) {
this.g.setItem(0, (ItemStack) null);
this.a = 0;
} else {
ItemStack itemstack1 = itemstack.cloneItemStack();
ItemStack itemstack2 = this.h.getItem(1);
Map map = EnchantmentManager.a(itemstack1);
boolean flag = false;
int k = b0 + itemstack.getRepairCost() + (itemstack2 == null ? 0 : itemstack2.getRepairCost());
this.m = 0;
int l;
int i1;
int j1;
int k1;
int l1;
Iterator iterator;
Enchantment enchantment;
if (itemstack2 != null) {
flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && Items.ENCHANTED_BOOK.g(itemstack2).size() > 0;
if (itemstack1.g() && itemstack1.getItem().a(itemstack, itemstack2)) {
l = Math.min(itemstack1.j(), itemstack1.l() / 4);
if (l <= 0) {
this.g.setItem(0, (ItemStack) null);
this.a = 0;
return;
}
for (i1 = 0; l > 0 && i1 < itemstack2.count; ++i1) {
j1 = itemstack1.j() - l;
itemstack1.setData(j1);
i += Math.max(1, l / 100) + map.size();
l = Math.min(itemstack1.j(), itemstack1.l() / 4);
}
this.m = i1;
} else {
if (!flag && (itemstack1.getItem() != itemstack2.getItem() || !itemstack1.g())) {
this.g.setItem(0, (ItemStack) null);
this.a = 0;
return;
}
if (itemstack1.g() && !flag) {
l = itemstack.l() - itemstack.j();
i1 = itemstack2.l() - itemstack2.j();
j1 = i1 + itemstack1.l() * 12 / 100;
int i2 = l + j1;
k1 = itemstack1.l() - i2;
if (k1 < 0) {
k1 = 0;
}
if (k1 < itemstack1.getData()) {
itemstack1.setData(k1);
i += Math.max(1, j1 / 100);
}
}
Map map1 = EnchantmentManager.a(itemstack2);
iterator = map1.keySet().iterator();
while (iterator.hasNext()) {
j1 = ((Integer) iterator.next()).intValue();
enchantment = Enchantment.byId[j1];
k1 = map.containsKey(Integer.valueOf(j1)) ? ((Integer) map.get(Integer.valueOf(j1))).intValue() : 0;
l1 = ((Integer) map1.get(Integer.valueOf(j1))).intValue();
int j2;
if (k1 == l1) {
++l1;
j2 = l1;
} else {
j2 = Math.max(l1, k1);
}
l1 = j2;
int k2 = l1 - k1;
boolean flag1 = enchantment.canEnchant(itemstack);
if (this.o.abilities.canInstantlyBuild || itemstack.getItem() == Items.ENCHANTED_BOOK) {
flag1 = true;
}
Iterator iterator1 = map.keySet().iterator();
while (iterator1.hasNext()) {
int l2 = ((Integer) iterator1.next()).intValue();
if (l2 != j1 && !enchantment.a(Enchantment.byId[l2])) {
flag1 = false;
i += k2;
}
}
if (flag1) {
if (l1 > enchantment.getMaxLevel()) {
l1 = enchantment.getMaxLevel();
}
map.put(Integer.valueOf(j1), Integer.valueOf(l1));
int i3 = 0;
switch (enchantment.getRandomWeight()) {
case 1:
i3 = 8;
break;
case 2:
i3 = 4;
case 3:
case 4:
case 6:
case 7:
case 8:
case 9:
default:
break;
case 5:
i3 = 2;
break;
case 10:
i3 = 1;
}
if (flag) {
i3 = Math.max(1, i3 / 2);
}
i += i3 * k2;
}
}
}
}
if (StringUtils.isBlank(this.n)) {
if (itemstack.hasName()) {
j = itemstack.g() ? 7 : itemstack.count * 5;
i += j;
itemstack1.t();
}
} else if (!this.n.equals(itemstack.getName())) {
j = itemstack.g() ? 7 : itemstack.count * 5;
i += j;
if (itemstack.hasName()) {
k += j / 2;
}
itemstack1.c(this.n);
}
l = 0;
for (iterator = map.keySet().iterator(); iterator.hasNext(); k += l + k1 * l1) {
j1 = ((Integer) iterator.next()).intValue();
enchantment = Enchantment.byId[j1];
k1 = ((Integer) map.get(Integer.valueOf(j1))).intValue();
l1 = 0;
++l;
switch (enchantment.getRandomWeight()) {
case 1:
l1 = 8;
break;
case 2:
l1 = 4;
case 3:
case 4:
case 6:
case 7:
case 8:
case 9:
default:
break;
case 5:
l1 = 2;
break;
case 10:
l1 = 1;
}
if (flag) {
l1 = Math.max(1, l1 / 2);
}
}
if (flag) {
k = Math.max(1, k / 2);
}
this.a = k + i;
if (i <= 0) {
itemstack1 = null;
}
if (j == i && j > 0 && this.a >= 40) {
this.a = 39;
}
if (this.a >= 40 && !this.o.abilities.canInstantlyBuild) {
itemstack1 = null;
}
if (itemstack1 != null) {
i1 = itemstack1.getRepairCost();
if (itemstack2 != null && i1 < itemstack2.getRepairCost()) {
i1 = itemstack2.getRepairCost();
}
if (itemstack1.hasName()) {
i1 -= 9;
}
if (i1 < 0) {
i1 = 0;
}
i1 += 2;
itemstack1.setRepairCost(i1);
EnchantmentManager.a(map, itemstack1);
}
this.g.setItem(0, itemstack1);
this.b();
}
}
public void addSlotListener(ICrafting icrafting) {
super.addSlotListener(icrafting);
icrafting.setContainerData(this, 0, this.a);
}
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
if (!this.i.isStatic) {
for (int i = 0; i < this.h.getSize(); ++i) {
ItemStack itemstack = this.h.splitWithoutUpdate(i);
if (itemstack != null) {
entityhuman.drop(itemstack, false);
}
}
}
}
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.i.getType(this.j, this.k, this.l) != Blocks.ANVIL ? false : entityhuman.e((double) this.j + 0.5D, (double) this.k + 0.5D, (double) this.l + 0.5D) <= 64.0D;
}
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i == 2) {
if (!this.a(itemstack1, 3, 39, true)) {
return null;
}
slot.a(itemstack1, itemstack);
} else if (i != 0 && i != 1) {
if (i >= 3 && i < 39 && !this.a(itemstack1, 0, 2, false)) {
return null;
}
} else if (!this.a(itemstack1, 3, 39, false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.a(entityhuman, itemstack1);
}
return itemstack;
}
public void a(String s) {
this.n = s;
if (this.getSlot(2).hasItem()) {
ItemStack itemstack = this.getSlot(2).getItem();
if (StringUtils.isBlank(s)) {
itemstack.t();
} else {
itemstack.c(this.n);
}
}
this.e();
}
static IInventory a(ContainerAnvil containeranvil) {
return containeranvil.h;
}
static int b(ContainerAnvil containeranvil) {
return containeranvil.m;
}
// CraftBukkit start
public CraftInventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil(this.h, this.g);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;
}
// CraftBukkit end
}

View File

@@ -0,0 +1,58 @@
package net.minecraft.server;
// CraftBukkit start
import java.util.List;
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import org.bukkit.entity.HumanEntity;
// CraftBukkit end
public class ContainerAnvilInventory extends InventorySubcontainer { // CraftBukkit - public
final ContainerAnvil a;
// CraftBukkit start
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
public org.bukkit.entity.Player player;
private int maxStack = MAX_STACK;
public ItemStack[] getContents() {
return this.items;
}
public void onOpen(CraftHumanEntity who) {
transaction.add(who);
}
public void onClose(CraftHumanEntity who) {
transaction.remove(who);
}
public List<HumanEntity> getViewers() {
return transaction;
}
public org.bukkit.inventory.InventoryHolder getOwner() {
return this.player;
}
public void setMaxStackSize(int size) {
maxStack = size;
}
// CraftBukkit end
ContainerAnvilInventory(ContainerAnvil containeranvil, String s, boolean flag, int i) {
super(s, flag, i);
this.a = containeranvil;
}
// CraftBukkit start - override inherited maxStack from InventorySubcontainer
public int getMaxStackSize() {
return maxStack;
}
// CraftBukkit end
public void update() {
super.update();
this.a.a((IInventory) this);
}
}

View File

@@ -0,0 +1,114 @@
package net.minecraft.server;
import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit
public class ContainerBeacon extends Container {
private TileEntityBeacon a;
private final SlotBeacon f;
private int g;
private int h;
private int i;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
// CraftBukkit end
public ContainerBeacon(PlayerInventory playerinventory, TileEntityBeacon tileentitybeacon) {
player = playerinventory; // CraftBukkit
this.a = tileentitybeacon;
this.a(this.f = new SlotBeacon(this, tileentitybeacon, 0, 136, 110));
byte b0 = 36;
short short1 = 137;
int i;
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.a(new Slot(playerinventory, j + i * 9 + 9, b0 + j * 18, short1 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.a(new Slot(playerinventory, i, b0 + i * 18, 58 + short1));
}
this.g = tileentitybeacon.l();
this.h = tileentitybeacon.j();
this.i = tileentitybeacon.k();
}
public void addSlotListener(ICrafting icrafting) {
super.addSlotListener(icrafting);
icrafting.setContainerData(this, 0, this.g);
icrafting.setContainerData(this, 1, this.h);
icrafting.setContainerData(this, 2, this.i);
}
public TileEntityBeacon e() {
return this.a;
}
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.a.a(entityhuman);
}
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i == 0) {
if (!this.a(itemstack1, 1, 37, true)) {
return null;
}
slot.a(itemstack1, itemstack);
} else if (!this.f.hasItem() && this.f.isAllowed(itemstack1) && itemstack1.count == 1) {
if (!this.a(itemstack1, 0, 1, false)) {
return null;
}
} else if (i >= 1 && i < 28) {
if (!this.a(itemstack1, 28, 37, false)) {
return null;
}
} else if (i >= 28 && i < 37) {
if (!this.a(itemstack1, 1, 28, false)) {
return null;
}
} else if (!this.a(itemstack1, 1, 37, false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.a(entityhuman, itemstack1);
}
return itemstack;
}
// CraftBukkit start
public CraftInventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon(this.a);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;
}
// CraftBukkit end
}

View File

@@ -1,14 +1,15 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
// CraftBukkit end
public class ContainerBrewingStand extends Container {
private TileEntityBrewingStand brewingStand;
private int b = 0;
private final Slot f;
private int g;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
@@ -17,10 +18,10 @@ public class ContainerBrewingStand extends Container {
public ContainerBrewingStand(PlayerInventory playerinventory, TileEntityBrewingStand tileentitybrewingstand) {
player = playerinventory; // CraftBukkit
this.brewingStand = tileentitybrewingstand;
this.a(new SlotPotionBottle(this, playerinventory.player, tileentitybrewingstand, 0, 56, 46));
this.a(new SlotPotionBottle(this, playerinventory.player, tileentitybrewingstand, 1, 79, 53));
this.a(new SlotPotionBottle(this, playerinventory.player, tileentitybrewingstand, 2, 102, 46));
this.a(new SlotBrewing(this, tileentitybrewingstand, 3, 79, 17));
this.a(new SlotPotionBottle(playerinventory.player, tileentitybrewingstand, 0, 56, 46));
this.a(new SlotPotionBottle(playerinventory.player, tileentitybrewingstand, 1, 79, 53));
this.a(new SlotPotionBottle(playerinventory.player, tileentitybrewingstand, 2, 102, 46));
this.f = this.a(new SlotBrewing(this, tileentitybrewingstand, 3, 79, 17));
int i;
@@ -40,35 +41,43 @@ public class ContainerBrewingStand extends Container {
icrafting.setContainerData(this, 0, this.brewingStand.i());
}
public void a() {
super.a();
public void b() {
super.b();
for (int i = 0; i < this.listeners.size(); ++i) {
ICrafting icrafting = (ICrafting) this.listeners.get(i);
if (this.b != this.brewingStand.i()) {
if (this.g != this.brewingStand.i()) {
icrafting.setContainerData(this, 0, this.brewingStand.i());
}
}
this.b = this.brewingStand.i();
this.g = this.brewingStand.i();
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.brewingStand.a(entityhuman);
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if ((i < 0 || i > 2) && i != 3) {
if (i >= 4 && i < 31) {
if (!this.f.hasItem() && this.f.isAllowed(itemstack1)) {
if (!this.a(itemstack1, 3, 4, false)) {
return null;
}
} else if (SlotPotionBottle.b_(itemstack)) {
if (!this.a(itemstack1, 0, 3, false)) {
return null;
}
} else if (i >= 4 && i < 31) {
if (!this.a(itemstack1, 31, 40, false)) {
return null;
}
@@ -90,14 +99,14 @@ public class ContainerBrewingStand extends Container {
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;
@@ -108,7 +117,8 @@ public class ContainerBrewingStand extends Container {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventory inventory = new CraftInventory(this.brewingStand);
CraftInventoryBrewer inventory = new CraftInventoryBrewer(this.brewingStand);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;
}

View File

@@ -2,15 +2,13 @@ package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest;
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
// CraftBukkit end
public class ContainerChest extends Container {
public IInventory container; // CraftBukkit - private->public
private int b;
private int f;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
@@ -19,14 +17,16 @@ public class ContainerChest extends Container {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventory inventory;
if (this.container instanceof PlayerInventory) {
inventory = new CraftInventoryPlayer((PlayerInventory) this.container);
inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryPlayer((PlayerInventory) this.container);
} else if (this.container instanceof InventoryLargeChest) {
inventory = new CraftInventoryDoubleChest((InventoryLargeChest) this.container);
inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) this.container);
} else {
inventory = new CraftInventory(this.container);
}
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;
}
@@ -34,18 +34,18 @@ public class ContainerChest extends Container {
public ContainerChest(IInventory iinventory, IInventory iinventory1) {
this.container = iinventory1;
this.b = iinventory1.getSize() / 9;
iinventory1.f();
int i = (this.b - 4) * 18;
// CraftBukkit start - save player
this.f = iinventory1.getSize() / 9;
iinventory1.startOpen();
int i = (this.f - 4) * 18;
// CraftBukkit start - Save player
// TODO: Should we check to make sure it really is an InventoryPlayer?
this.player = (PlayerInventory)iinventory;
this.player = (PlayerInventory) iinventory;
// CraftBukkit end
int j;
int k;
for (j = 0; j < this.b; ++j) {
for (j = 0; j < this.f; ++j) {
for (k = 0; k < 9; ++k) {
this.a(new Slot(iinventory1, k + j * 9, 8 + k * 18, 18 + j * 18));
}
@@ -62,39 +62,43 @@ public class ContainerChest extends Container {
}
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.container.a(entityhuman);
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i < this.b * 9) {
if (!this.a(itemstack1, this.b * 9, this.e.size(), true)) {
if (i < this.f * 9) {
if (!this.a(itemstack1, this.f * 9, this.c.size(), true)) {
return null;
}
} else if (!this.a(itemstack1, 0, this.b * 9, false)) {
} else if (!this.a(itemstack1, 0, this.f * 9, false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
}
return itemstack;
}
public void a(EntityHuman entityhuman) {
super.a(entityhuman);
this.container.g();
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
this.container.closeContainer();
}
public IInventory e() {
return this.container;
}
}

View File

@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView;
public class ContainerDispenser extends Container {
public TileEntityDispenser items; // CraftBukkit - Private -> Public
public TileEntityDispenser items; // CraftBukkit - private -> public
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
@@ -15,7 +15,7 @@ public class ContainerDispenser extends Container {
public ContainerDispenser(IInventory iinventory, TileEntityDispenser tileentitydispenser) {
this.items = tileentitydispenser;
// CraftBukkit start - save player
// CraftBukkit start - Save player
// TODO: Should we check to make sure it really is an InventoryPlayer?
this.player = (PlayerInventory)iinventory;
// CraftBukkit end
@@ -40,16 +40,16 @@ public class ContainerDispenser extends Container {
}
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.items.a(entityhuman);
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
@@ -64,14 +64,14 @@ public class ContainerDispenser extends Container {
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;
@@ -82,6 +82,7 @@ public class ContainerDispenser extends Container {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventory inventory = new CraftInventory(this.items);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;

View File

@@ -1,12 +1,10 @@
package net.minecraft.server;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
// CraftBukkit start
import java.util.Map;
import java.util.HashMap;
import org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
@@ -19,13 +17,13 @@ import org.bukkit.entity.Player;
public class ContainerEnchantTable extends Container {
// CraftBukkit - make type specific (changed from IInventory)
public ContainerEnchantTableInventory enchantSlots = new ContainerEnchantTableInventory(this, "Enchant", 1);
public ContainerEnchantTableInventory enchantSlots = new ContainerEnchantTableInventory(this, "Enchant", true, 1);
private World world;
private int x;
private int y;
private int z;
private Random l = new Random();
public long b;
public long f;
public int[] costs = new int[3];
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
@@ -50,8 +48,9 @@ public class ContainerEnchantTable extends Container {
for (l = 0; l < 9; ++l) {
this.a(new Slot(playerinventory, l, 8 + l * 18, 142));
}
// CraftBukkit start
player = (Player) playerinventory.player.bukkitEntity;
player = (Player) playerinventory.player.getBukkitEntity();
enchantSlots.player = player;
// CraftBukkit end
}
@@ -63,8 +62,8 @@ public class ContainerEnchantTable extends Container {
icrafting.setContainerData(this, 2, this.costs[2]);
}
public void a() {
super.a();
public void b() {
super.b();
for (int i = 0; i < this.listeners.size(); ++i) {
ICrafting icrafting = (ICrafting) this.listeners.get(i);
@@ -80,8 +79,8 @@ public class ContainerEnchantTable extends Container {
ItemStack itemstack = iinventory.getItem(0);
int i;
if (itemstack != null && itemstack.q()) {
this.b = this.l.nextLong();
if (itemstack != null) { // CraftBukkit - relax condition
this.f = this.l.nextLong();
if (!this.world.isStatic) {
i = 0;
@@ -90,28 +89,28 @@ public class ContainerEnchantTable extends Container {
for (j = -1; j <= 1; ++j) {
for (int k = -1; k <= 1; ++k) {
if ((j != 0 || k != 0) && this.world.isEmpty(this.x + k, this.y, this.z + j) && this.world.isEmpty(this.x + k, this.y + 1, this.z + j)) {
if (this.world.getTypeId(this.x + k * 2, this.y, this.z + j * 2) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k * 2, this.y, this.z + j * 2) == Blocks.BOOKSHELF) {
++i;
}
if (this.world.getTypeId(this.x + k * 2, this.y + 1, this.z + j * 2) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k * 2, this.y + 1, this.z + j * 2) == Blocks.BOOKSHELF) {
++i;
}
if (k != 0 && j != 0) {
if (this.world.getTypeId(this.x + k * 2, this.y, this.z + j) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k * 2, this.y, this.z + j) == Blocks.BOOKSHELF) {
++i;
}
if (this.world.getTypeId(this.x + k * 2, this.y + 1, this.z + j) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k * 2, this.y + 1, this.z + j) == Blocks.BOOKSHELF) {
++i;
}
if (this.world.getTypeId(this.x + k, this.y, this.z + j * 2) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k, this.y, this.z + j * 2) == Blocks.BOOKSHELF) {
++i;
}
if (this.world.getTypeId(this.x + k, this.y + 1, this.z + j * 2) == Block.BOOKSHELF.id) {
if (this.world.getType(this.x + k, this.y + 1, this.z + j * 2) == Blocks.BOOKSHELF) {
++i;
}
}
@@ -124,8 +123,9 @@ public class ContainerEnchantTable extends Container {
}
// CraftBukkit start
CraftItemStack item = new CraftItemStack(itemstack);
CraftItemStack item = CraftItemStack.asCraftMirror(itemstack);
PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), this.world.getWorld().getBlockAt(this.x, this.y, this.z), item, this.costs, i);
event.setCancelled(!itemstack.x());
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
@@ -135,7 +135,8 @@ public class ContainerEnchantTable extends Container {
return;
}
// CraftBukkit end
this.a();
this.b();
}
} else {
for (i = 0; i < 3; ++i) {
@@ -151,33 +152,56 @@ public class ContainerEnchantTable extends Container {
if (this.costs[i] > 0 && itemstack != null && (entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) {
if (!this.world.isStatic) {
List list = EnchantmentManager.b(this.l, itemstack, this.costs[i]);
// CraftBukkit start - Provide an empty enchantment list
if (list == null) {
list = new java.util.ArrayList<EnchantmentInstance>();
}
// CraftBukkit end
boolean flag = itemstack.getItem() == Items.BOOK;
if (list != null) {
// CraftBukkit start
Map<org.bukkit.enchantments.Enchantment, Integer> enchants = new HashMap<org.bukkit.enchantments.Enchantment, Integer>();
Map<org.bukkit.enchantments.Enchantment, Integer> enchants = new java.util.HashMap<org.bukkit.enchantments.Enchantment, Integer>();
for (Object obj : list) {
EnchantmentInstance instance = (EnchantmentInstance) obj;
enchants.put(org.bukkit.enchantments.Enchantment.getById(instance.enchantment.id), instance.level);
}
CraftItemStack item = new CraftItemStack(itemstack);
CraftItemStack item = CraftItemStack.asCraftMirror(itemstack);
EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.bukkitEntity, this.getBukkitView(), this.world.getWorld().getBlockAt(this.x, this.y, this.z), item, this.costs[i], enchants, i);
EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), this.world.getWorld().getBlockAt(this.x, this.y, this.z), item, this.costs[i], enchants, i);
this.world.getServer().getPluginManager().callEvent(event);
int level = event.getExpLevelCost();
if (event.isCancelled() || (level > entityhuman.expLevel && !entityhuman.abilities.canInstantlyBuild) || enchants.isEmpty()) {
if (event.isCancelled() || (level > entityhuman.expLevel && !entityhuman.abilities.canInstantlyBuild) || event.getEnchantsToAdd().isEmpty()) {
return false;
}
entityhuman.levelDown(level);
if (flag) {
itemstack.setItem(Items.ENCHANTED_BOOK);
}
for (Map.Entry<org.bukkit.enchantments.Enchantment, Integer> entry : event.getEnchantsToAdd().entrySet()) {
try {
item.addEnchantment(entry.getKey(), entry.getValue());
if (flag) {
int enchantId = entry.getKey().getId();
if (Enchantment.byId[enchantId] == null) {
continue;
}
EnchantmentInstance enchantment = new EnchantmentInstance(enchantId, entry.getValue());
Items.ENCHANTED_BOOK.a(itemstack, enchantment);
} else {
item.addUnsafeEnchantment(entry.getKey(), entry.getValue());
}
} catch (IllegalArgumentException e) {
/* Just swallow invalid enchantments */
}
// CraftBukkit end
}
entityhuman.levelDown(-level);
// CraftBukkit end
this.a(this.enchantSlots);
}
}
@@ -188,49 +212,59 @@ public class ContainerEnchantTable extends Container {
}
}
public void a(EntityHuman entityhuman) {
super.a(entityhuman);
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
if (!this.world.isStatic) {
ItemStack itemstack = this.enchantSlots.splitWithoutUpdate(0);
if (itemstack != null) {
entityhuman.drop(itemstack);
entityhuman.drop(itemstack, false);
}
}
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.world.getTypeId(this.x, this.y, this.z) != Block.ENCHANTMENT_TABLE.id ? false : entityhuman.e((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64.0D;
return this.world.getType(this.x, this.y, this.z) != Blocks.ENCHANTMENT_TABLE ? false : entityhuman.e((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64.0D;
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i != 0) {
return null;
}
if (i == 0) {
if (!this.a(itemstack1, 1, 37, true)) {
return null;
}
} else {
if (((Slot) this.c.get(0)).hasItem() || !((Slot) this.c.get(0)).isAllowed(itemstack1)) {
return null;
}
if (!this.a(itemstack1, 1, 37, true)) {
return null;
if (itemstack1.hasTag() && itemstack1.count == 1) {
((Slot) this.c.get(0)).set(itemstack1.cloneItemStack());
itemstack1.count = 0;
} else if (itemstack1.count >= 1) {
((Slot) this.c.get(0)).set(new ItemStack(itemstack1.getItem(), 1, itemstack1.getData()));
--itemstack1.count;
}
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;
@@ -241,6 +275,7 @@ public class ContainerEnchantTable extends Container {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventoryEnchanting inventory = new CraftInventoryEnchanting(this.enchantSlots);
bukkitEntity = new CraftInventoryView(this.player, inventory, this);
return bukkitEntity;

View File

@@ -1,17 +1,53 @@
package net.minecraft.server;
public class ContainerEnchantTableInventory extends ContainerEnchantTableSubcontainer { // CraftBukkit -> public
// CraftBukkit start
import java.util.List;
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import org.bukkit.entity.HumanEntity;
// CraftBukkit end
public final ContainerEnchantTable enchantTable; // CraftBukkit -> public
public class ContainerEnchantTableInventory extends InventorySubcontainer { // CraftBukkit -> public
ContainerEnchantTableInventory(ContainerEnchantTable containerenchanttable, String s, int i) {
super(s, i);
final ContainerEnchantTable enchantTable;
// CraftBukkit start
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
public org.bukkit.entity.Player player;
private int maxStack = MAX_STACK;
public ItemStack[] getContents() {
return this.items;
}
public void onOpen(CraftHumanEntity who) {
transaction.add(who);
}
public void onClose(CraftHumanEntity who) {
transaction.remove(who);
}
public List<HumanEntity> getViewers() {
return transaction;
}
public org.bukkit.inventory.InventoryHolder getOwner() {
return this.player;
}
public void setMaxStackSize(int size) {
maxStack = size;
}
// CraftBukkit end
ContainerEnchantTableInventory(ContainerEnchantTable containerenchanttable, String s, boolean flag, int i) {
super(s, flag, i);
this.enchantTable = containerenchanttable;
super.setMaxStackSize(1); // CraftBukkit
this.setMaxStackSize(1); // CraftBukkit
}
public int getMaxStackSize() {
return super.getMaxStackSize(); // CraftBukkit
return maxStack; // CraftBukkit
}
public void update() {

View File

@@ -7,10 +7,11 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView;
public class ContainerFurnace extends Container {
public TileEntityFurnace furnace; // CraftBukkit - Private -> Public
private int b = 0;
private int c = 0;
private int h = 0;
private TileEntityFurnace furnace;
private int f;
private int g;
private int h;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
@@ -30,7 +31,7 @@ public class ContainerFurnace extends Container {
this.furnace = tileentityfurnace;
this.a(new Slot(tileentityfurnace, 0, 56, 17));
this.a(new Slot(tileentityfurnace, 1, 56, 53));
this.a(new SlotResult2(playerinventory.player, tileentityfurnace, 2, 116, 35));
this.a(new SlotFurnaceResult(playerinventory.player, tileentityfurnace, 2, 116, 35));
this.player = playerinventory; // CraftBukkit - save player
int i;
@@ -53,17 +54,17 @@ public class ContainerFurnace extends Container {
icrafting.setContainerData(this, 2, this.furnace.ticksForCurrentFuel);
}
public void a() {
super.a();
public void b() {
super.b();
for (int i = 0; i < this.listeners.size(); ++i) {
ICrafting icrafting = (ICrafting) this.listeners.get(i);
if (this.b != this.furnace.cookTime) {
if (this.f != this.furnace.cookTime) {
icrafting.setContainerData(this, 0, this.furnace.cookTime);
}
if (this.c != this.furnace.burnTime) {
if (this.g != this.furnace.burnTime) {
icrafting.setContainerData(this, 1, this.furnace.burnTime);
}
@@ -72,21 +73,21 @@ public class ContainerFurnace extends Container {
}
}
this.b = this.furnace.cookTime;
this.c = this.furnace.burnTime;
this.f = this.furnace.cookTime;
this.g = this.furnace.burnTime;
this.h = this.furnace.ticksForCurrentFuel;
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.furnace.a(entityhuman);
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
@@ -97,7 +98,7 @@ public class ContainerFurnace extends Container {
slot.a(itemstack1, itemstack);
} else if (i != 1 && i != 0) {
if (FurnaceRecipes.getInstance().getResult(itemstack1.getItem().id) != null) {
if (RecipesFurnace.getInstance().getResult(itemstack1) != null) {
if (!this.a(itemstack1, 0, 1, false)) {
return null;
}
@@ -119,14 +120,14 @@ public class ContainerFurnace extends Container {
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;

View File

@@ -0,0 +1,85 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
// CraftBukkit end
public class ContainerHopper extends Container {
private final IInventory hopper;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
public CraftInventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventory inventory = new CraftInventory(this.hopper);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;
}
// CraftBukkit end
public ContainerHopper(PlayerInventory playerinventory, IInventory iinventory) {
this.hopper = iinventory;
this.player = playerinventory; // CraftBukkit - save player
iinventory.startOpen();
byte b0 = 51;
int i;
for (i = 0; i < iinventory.getSize(); ++i) {
this.a(new Slot(iinventory, i, 44 + i * 18, 20));
}
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, i * 18 + b0));
}
}
for (i = 0; i < 9; ++i) {
this.a(new Slot(playerinventory, i, 8 + i * 18, 58 + b0));
}
}
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.hopper.a(entityhuman);
}
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i < this.hopper.getSize()) {
if (!this.a(itemstack1, this.hopper.getSize(), this.c.size(), true)) {
return null;
}
} else if (!this.a(itemstack1, 0, this.hopper.getSize(), false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.f();
}
}
return itemstack;
}
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
this.hopper.closeContainer();
}
}

View File

@@ -0,0 +1,104 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
public class ContainerHorse extends Container {
private IInventory a;
private EntityHorse f;
// CraftBukkit start
org.bukkit.craftbukkit.inventory.CraftInventoryView bukkitEntity;
PlayerInventory player;
@Override
public InventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryHorse(this.a);
return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), inventory, this);
}
public ContainerHorse(IInventory iinventory, IInventory iinventory1, EntityHorse entityhorse) {
player = (PlayerInventory) iinventory;
// CraftBukkit end
this.a = iinventory1;
this.f = entityhorse;
byte b0 = 3;
iinventory1.startOpen();
int i = (b0 - 4) * 18;
this.a(new SlotHorseSaddle(this, iinventory1, 0, 8, 18));
this.a(new SlotHorseArmor(this, iinventory1, 1, 8, 36, entityhorse));
int j;
int k;
if (entityhorse.hasChest()) {
for (j = 0; j < b0; ++j) {
for (k = 0; k < 5; ++k) {
this.a(new Slot(iinventory1, 2 + k + j * 5, 80 + k * 18, 18 + j * 18));
}
}
}
for (j = 0; j < 3; ++j) {
for (k = 0; k < 9; ++k) {
this.a(new Slot(iinventory, k + j * 9 + 9, 8 + k * 18, 102 + j * 18 + i));
}
}
for (j = 0; j < 9; ++j) {
this.a(new Slot(iinventory, j, 8 + j * 18, 160 + i));
}
}
public boolean a(EntityHuman entityhuman) {
return this.a.a(entityhuman) && this.f.isAlive() && this.f.e(entityhuman) < 8.0F;
}
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i < this.a.getSize()) {
if (!this.a(itemstack1, this.a.getSize(), this.c.size(), true)) {
return null;
}
} else if (this.getSlot(1).isAllowed(itemstack1) && !this.getSlot(1).hasItem()) {
if (!this.a(itemstack1, 1, 2, false)) {
return null;
}
} else if (this.getSlot(0).isAllowed(itemstack1)) {
if (!this.a(itemstack1, 0, 1, false)) {
return null;
}
} else if (this.a.getSize() <= 2 || !this.a(itemstack1, 2, this.a.getSize(), false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.f();
}
}
return itemstack;
}
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
this.a.closeContainer();
}
}

View File

@@ -0,0 +1,131 @@
package net.minecraft.server;
import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit
public class ContainerMerchant extends Container {
private IMerchant merchant;
private InventoryMerchant f;
private final World g;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
@Override
public CraftInventoryView getBukkitView() {
if (bukkitEntity == null) {
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventoryMerchant(this.getMerchantInventory()), this);
}
return bukkitEntity;
}
// CraftBukkit end
public ContainerMerchant(PlayerInventory playerinventory, IMerchant imerchant, World world) {
this.merchant = imerchant;
this.g = world;
this.f = new InventoryMerchant(playerinventory.player, imerchant);
this.a(new Slot(this.f, 0, 36, 53));
this.a(new Slot(this.f, 1, 62, 53));
this.a((Slot) (new SlotMerchantResult(playerinventory.player, imerchant, this.f, 2, 120, 53)));
this.player = playerinventory; // CraftBukkit - save player
int i;
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.a(new Slot(playerinventory, i, 8 + i * 18, 142));
}
}
public InventoryMerchant getMerchantInventory() {
return this.f;
}
public void addSlotListener(ICrafting icrafting) {
super.addSlotListener(icrafting);
}
public void b() {
super.b();
}
public void a(IInventory iinventory) {
this.f.h();
super.a(iinventory);
}
public void e(int i) {
this.f.c(i);
}
public boolean a(EntityHuman entityhuman) {
return this.merchant.b() == entityhuman;
}
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
if (i == 2) {
if (!this.a(itemstack1, 3, 39, true)) {
return null;
}
slot.a(itemstack1, itemstack);
} else if (i != 0 && i != 1) {
if (i >= 3 && i < 30) {
if (!this.a(itemstack1, 30, 39, false)) {
return null;
}
} else if (i >= 30 && i < 39 && !this.a(itemstack1, 3, 30, false)) {
return null;
}
} else if (!this.a(itemstack1, 3, 39, false)) {
return null;
}
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.a(entityhuman, itemstack1);
}
return itemstack;
}
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
this.merchant.a_((EntityHuman) null);
super.b(entityhuman);
if (!this.g.isStatic) {
ItemStack itemstack = this.f.splitWithoutUpdate(0);
if (itemstack != null) {
entityhuman.drop(itemstack, false);
}
itemstack = this.f.splitWithoutUpdate(1);
if (itemstack != null) {
entityhuman.drop(itemstack, false);
}
}
}
}

View File

@@ -7,25 +7,22 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView;
public class ContainerPlayer extends Container {
public InventoryCrafting craftInventory;
public IInventory resultInventory;
public boolean c;
public InventoryCrafting craftInventory = new InventoryCrafting(this, 2, 2);
public IInventory resultInventory = new InventoryCraftResult();
public boolean g;
private final EntityHuman h;
// CraftBukkit start
private CraftInventoryView bukkitEntity = null;
private PlayerInventory player;
// CraftBukkit end
public ContainerPlayer(PlayerInventory playerinventory) {
this(playerinventory, true);
}
public ContainerPlayer(PlayerInventory playerinventory, boolean flag) {
public ContainerPlayer(PlayerInventory playerinventory, boolean flag, EntityHuman entityhuman) {
this.g = flag;
this.h = entityhuman;
this.resultInventory = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction
this.craftInventory = new InventoryCrafting(this, 2, 2, playerinventory.player); // CraftBukkit - pass player
this.craftInventory.resultInventory = this.resultInventory; // CraftBukkit - let InventoryCrafting know about its result slot
this.player = playerinventory; // CraftBukkit - save player
this.c = false;
this.c = flag;
this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 144, 36)));
int i;
@@ -57,40 +54,40 @@ public class ContainerPlayer extends Container {
public void a(IInventory iinventory) {
// CraftBukkit start (Note: the following line would cause an error if called during construction)
CraftingManager.getInstance().lastCraftView = getBukkitView();
ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory);
ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.h.world);
this.resultInventory.setItem(0, craftResult);
if (super.listeners.size() < 1) {
return;
}
EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it.
player.netServerHandler.sendPacket(new Packet103SetSlot(player.activeContainer.windowId, 0, craftResult));
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult));
// CraftBukkit end
}
public void a(EntityHuman entityhuman) {
super.a(entityhuman);
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
for (int i = 0; i < 4; ++i) {
ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i);
if (itemstack != null) {
entityhuman.drop(itemstack);
entityhuman.drop(itemstack, false);
}
}
this.resultInventory.setItem(0, (ItemStack) null);
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
return true;
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
@@ -100,6 +97,20 @@ public class ContainerPlayer extends Container {
}
slot.a(itemstack1, itemstack);
} else if (i >= 1 && i < 5) {
if (!this.a(itemstack1, 9, 45, false)) {
return null;
}
} else if (i >= 5 && i < 9) {
if (!this.a(itemstack1, 9, 45, false)) {
return null;
}
} else if (itemstack.getItem() instanceof ItemArmor && !((Slot) this.c.get(5 + ((ItemArmor) itemstack.getItem()).b)).hasItem()) {
int j = 5 + ((ItemArmor) itemstack.getItem()).b;
if (!this.a(itemstack1, j, j + 1, false)) {
return null;
}
} else if (i >= 9 && i < 36) {
if (!this.a(itemstack1, 36, 45, false)) {
return null;
@@ -115,24 +126,29 @@ public class ContainerPlayer extends Container {
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;
}
public boolean a(ItemStack itemstack, Slot slot) {
return slot.inventory != this.resultInventory && super.a(itemstack, slot);
}
// CraftBukkit start
public CraftInventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;

View File

@@ -9,7 +9,7 @@ public class ContainerWorkbench extends Container {
public InventoryCrafting craftInventory; // CraftBukkit - move initialization into constructor
public IInventory resultInventory; // CraftBukkit - move initialization into constructor
private World c;
private World g;
private int h;
private int i;
private int j;
@@ -19,13 +19,13 @@ public class ContainerWorkbench extends Container {
// CraftBukkit end
public ContainerWorkbench(PlayerInventory playerinventory, World world, int i, int j, int k) {
// CraftBukkit start - switched order of IInventory construction and stored player
// CraftBukkit start - Switched order of IInventory construction and stored player
this.resultInventory = new InventoryCraftResult();
this.craftInventory = new InventoryCrafting(this, 3, 3, playerinventory.player); // CraftBukkit - pass player
this.craftInventory.resultInventory = this.resultInventory;
this.player = playerinventory;
// CraftBukkit end
this.c = world;
this.g = world;
this.h = i;
this.i = j;
this.j = k;
@@ -56,40 +56,40 @@ public class ContainerWorkbench extends Container {
public void a(IInventory iinventory) {
// CraftBukkit start
CraftingManager.getInstance().lastCraftView = getBukkitView();
ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory);
ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.g);
this.resultInventory.setItem(0, craftResult);
if (super.listeners.size() < 1) {
return;
}
EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it.
player.netServerHandler.sendPacket(new Packet103SetSlot(player.activeContainer.windowId, 0, craftResult));
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult));
// CraftBukkit end
}
public void a(EntityHuman entityhuman) {
super.a(entityhuman);
if (!this.c.isStatic) {
public void b(EntityHuman entityhuman) {
super.b(entityhuman);
if (!this.g.isStatic) {
for (int i = 0; i < 9; ++i) {
ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i);
if (itemstack != null) {
entityhuman.drop(itemstack);
entityhuman.drop(itemstack, false);
}
}
}
}
public boolean b(EntityHuman entityhuman) {
public boolean a(EntityHuman entityhuman) {
if (!this.checkReachable) return true; // CraftBukkit
return this.c.getTypeId(this.h, this.i, this.j) != Block.WORKBENCH.id ? false : entityhuman.e((double) this.h + 0.5D, (double) this.i + 0.5D, (double) this.j + 0.5D) <= 64.0D;
return this.g.getType(this.h, this.i, this.j) != Blocks.WORKBENCH ? false : entityhuman.e((double) this.h + 0.5D, (double) this.i + 0.5D, (double) this.j + 0.5D) <= 64.0D;
}
public ItemStack a(int i) {
public ItemStack b(EntityHuman entityhuman, int i) {
ItemStack itemstack = null;
Slot slot = (Slot) this.e.get(i);
Slot slot = (Slot) this.c.get(i);
if (slot != null && slot.c()) {
if (slot != null && slot.hasItem()) {
ItemStack itemstack1 = slot.getItem();
itemstack = itemstack1.cloneItemStack();
@@ -114,24 +114,29 @@ public class ContainerWorkbench extends Container {
if (itemstack1.count == 0) {
slot.set((ItemStack) null);
} else {
slot.d();
slot.f();
}
if (itemstack1.count == itemstack.count) {
return null;
}
slot.c(itemstack1);
slot.a(entityhuman, itemstack1);
}
return itemstack;
}
public boolean a(ItemStack itemstack, Slot slot) {
return slot.inventory != this.resultInventory && super.a(itemstack, slot);
}
// CraftBukkit start
public CraftInventoryView getBukkitView() {
if (bukkitEntity != null) {
return bukkitEntity;
}
CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory);
bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this);
return bukkitEntity;

View File

@@ -0,0 +1,87 @@
package net.minecraft.server;
import org.bukkit.craftbukkit.TrigMath; // CraftBukkit
public class ControllerLook {
private EntityInsentient a;
private float b;
private float c;
private boolean d;
private double e;
private double f;
private double g;
public ControllerLook(EntityInsentient entityinsentient) {
this.a = entityinsentient;
}
public void a(Entity entity, float f, float f1) {
this.e = entity.locX;
if (entity instanceof EntityLiving) {
this.f = entity.locY + (double) entity.getHeadHeight();
} else {
this.f = (entity.boundingBox.b + entity.boundingBox.e) / 2.0D;
}
this.g = entity.locZ;
this.b = f;
this.c = f1;
this.d = true;
}
public void a(double d0, double d1, double d2, float f, float f1) {
this.e = d0;
this.f = d1;
this.g = d2;
this.b = f;
this.c = f1;
this.d = true;
}
public void a() {
this.a.pitch = 0.0F;
if (this.d) {
this.d = false;
double d0 = this.e - this.a.locX;
double d1 = this.f - (this.a.locY + (double) this.a.getHeadHeight());
double d2 = this.g - this.a.locZ;
double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2);
// CraftBukkit start - Math -> TrigMath
float f = (float) (TrigMath.atan2(d2, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
float f1 = (float) (-(TrigMath.atan2(d1, d3) * 180.0D / 3.1415927410125732D));
// CraftBukkit end
this.a.pitch = this.a(this.a.pitch, f1, this.c);
this.a.aO = this.a(this.a.aO, f, this.b);
} else {
this.a.aO = this.a(this.a.aO, this.a.aM, 10.0F);
}
float f2 = MathHelper.g(this.a.aO - this.a.aM);
if (!this.a.getNavigation().g()) {
if (f2 < -75.0F) {
this.a.aO = this.a.aM - 75.0F;
}
if (f2 > 75.0F) {
this.a.aO = this.a.aM + 75.0F;
}
}
}
private float a(float f, float f1, float f2) {
float f3 = MathHelper.g(f1 - f);
if (f3 > f2) {
f3 = f2;
}
if (f3 < -f2) {
f3 = -f2;
}
return f + f3;
}
}

View File

@@ -0,0 +1,71 @@
package net.minecraft.server;
public class ControllerMove {
private EntityInsentient a;
private double b;
private double c;
private double d;
private double e;
private boolean f;
public ControllerMove(EntityInsentient entityinsentient) {
this.a = entityinsentient;
this.b = entityinsentient.locX;
this.c = entityinsentient.locY;
this.d = entityinsentient.locZ;
}
public boolean a() {
return this.f;
}
public double b() {
return this.e;
}
public void a(double d0, double d1, double d2, double d3) {
this.b = d0;
this.c = d1;
this.d = d2;
this.e = d3;
this.f = true;
}
public void c() {
this.a.n(0.0F);
if (this.f) {
this.f = false;
int i = MathHelper.floor(this.a.boundingBox.b + 0.5D);
double d0 = this.b - this.a.locX;
double d1 = this.d - this.a.locZ;
double d2 = this.c - (double) i;
double d3 = d0 * d0 + d2 * d2 + d1 * d1;
if (d3 >= 2.500000277905201E-7D) {
// CraftBukkit - Math -> TrigMath
float f = (float) (org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
this.a.yaw = this.a(this.a.yaw, f, 30.0F);
this.a.i((float) (this.e * this.a.getAttributeInstance(GenericAttributes.d).getValue()));
if (d2 > 0.0D && d0 * d0 + d1 * d1 < 1.0D) {
this.a.getControllerJump().a();
}
}
}
}
private float a(float f, float f1, float f2) {
float f3 = MathHelper.g(f1 - f);
if (f3 > f2) {
f3 = f2;
}
if (f3 < -f2) {
f3 = -f2;
}
return f + f3;
}
}

View File

@@ -4,25 +4,24 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
public class CraftingManager {
private static final CraftingManager a = new CraftingManager();
public List recipies = new ArrayList(); // CraftBukkit - private -> public
// CraftBukkit start
public CraftingRecipe lastRecipe;
public InventoryView lastCraftView;
public List recipes = new ArrayList(); // private -> public
public IRecipe lastRecipe;
public org.bukkit.inventory.InventoryView lastCraftView;
// CraftBukkit end
public static final CraftingManager getInstance() {
return a;
}
public CraftingManager() { // CraftBukkit - private -> public
// CraftBukkit - private -> public
public CraftingManager() {
(new RecipesTools()).a(this);
(new RecipesWeapons()).a(this);
(new RecipeIngots()).a(this);
@@ -30,92 +29,137 @@ public class CraftingManager {
(new RecipesCrafting()).a(this);
(new RecipesArmor()).a(this);
(new RecipesDyes()).a(this);
this.registerShapedRecipe(new ItemStack(Item.PAPER, 3), new Object[] { "###", Character.valueOf('#'), Item.SUGAR_CANE});
this.registerShapedRecipe(new ItemStack(Item.BOOK, 1), new Object[] { "#", "#", "#", Character.valueOf('#'), Item.PAPER});
this.registerShapedRecipe(new ItemStack(Block.FENCE, 2), new Object[] { "###", "###", Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Block.NETHER_FENCE, 6), new Object[] { "###", "###", Character.valueOf('#'), Block.NETHER_BRICK});
this.registerShapedRecipe(new ItemStack(Block.FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Item.STICK, Character.valueOf('W'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.JUKEBOX, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Block.WOOD, Character.valueOf('X'), Item.DIAMOND});
this.registerShapedRecipe(new ItemStack(Block.NOTE_BLOCK, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Block.WOOD, Character.valueOf('X'), Item.REDSTONE});
this.registerShapedRecipe(new ItemStack(Block.BOOKSHELF, 1), new Object[] { "###", "XXX", "###", Character.valueOf('#'), Block.WOOD, Character.valueOf('X'), Item.BOOK});
this.registerShapedRecipe(new ItemStack(Block.SNOW_BLOCK, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.SNOW_BALL});
this.registerShapedRecipe(new ItemStack(Block.CLAY, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.CLAY_BALL});
this.registerShapedRecipe(new ItemStack(Block.BRICK, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.CLAY_BRICK});
this.registerShapedRecipe(new ItemStack(Block.GLOWSTONE, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.GLOWSTONE_DUST});
this.registerShapedRecipe(new ItemStack(Block.WOOL, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.STRING});
this.registerShapedRecipe(new ItemStack(Block.TNT, 1), new Object[] { "X#X", "#X#", "X#X", Character.valueOf('X'), Item.SULPHUR, Character.valueOf('#'), Block.SAND});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 3), new Object[] { "###", Character.valueOf('#'), Block.COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 0), new Object[] { "###", Character.valueOf('#'), Block.STONE});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 1), new Object[] { "###", Character.valueOf('#'), Block.SANDSTONE});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 2), new Object[] { "###", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 4), new Object[] { "###", Character.valueOf('#'), Block.BRICK});
this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 5), new Object[] { "###", Character.valueOf('#'), Block.SMOOTH_BRICK});
this.registerShapedRecipe(new ItemStack(Block.LADDER, 3), new Object[] { "# #", "###", "# #", Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Item.WOOD_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.TRAP_DOOR, 2), new Object[] { "###", "###", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Item.IRON_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Item.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Item.SIGN, 1), new Object[] { "###", "###", " X ", Character.valueOf('#'), Block.WOOD, Character.valueOf('X'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Item.CAKE, 1), new Object[] { "AAA", "BEB", "CCC", Character.valueOf('A'), Item.MILK_BUCKET, Character.valueOf('B'), Item.SUGAR, Character.valueOf('C'), Item.WHEAT, Character.valueOf('E'), Item.EGG});
this.registerShapedRecipe(new ItemStack(Item.SUGAR, 1), new Object[] { "#", Character.valueOf('#'), Item.SUGAR_CANE});
this.registerShapedRecipe(new ItemStack(Block.WOOD, 4, 0), new Object[] { "#", Character.valueOf('#'), new ItemStack(Block.LOG, 1, 0)});
this.registerShapedRecipe(new ItemStack(Block.WOOD, 4, 1), new Object[] { "#", Character.valueOf('#'), new ItemStack(Block.LOG, 1, 1)});
this.registerShapedRecipe(new ItemStack(Block.WOOD, 4, 2), new Object[] { "#", Character.valueOf('#'), new ItemStack(Block.LOG, 1, 2)});
this.registerShapedRecipe(new ItemStack(Block.WOOD, 4, 3), new Object[] { "#", Character.valueOf('#'), new ItemStack(Block.LOG, 1, 3)});
this.registerShapedRecipe(new ItemStack(Item.STICK, 4), new Object[] { "#", "#", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), Item.COAL, Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Block.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), new ItemStack(Item.COAL, 1, 1), Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Item.BOWL, 4), new Object[] { "# #", " # ", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Item.GLASS_BOTTLE, 3), new Object[] { "# #", " # ", Character.valueOf('#'), Block.GLASS});
this.registerShapedRecipe(new ItemStack(Block.RAILS, 16), new Object[] { "X X", "X#X", "X X", Character.valueOf('X'), Item.IRON_INGOT, Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Block.GOLDEN_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Item.GOLD_INGOT, Character.valueOf('R'), Item.REDSTONE, Character.valueOf('#'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Block.DETECTOR_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Item.IRON_INGOT, Character.valueOf('R'), Item.REDSTONE, Character.valueOf('#'), Block.STONE_PLATE});
this.registerShapedRecipe(new ItemStack(Item.MINECART, 1), new Object[] { "# #", "###", Character.valueOf('#'), Item.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Item.CAULDRON, 1), new Object[] { "# #", "# #", "###", Character.valueOf('#'), Item.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Item.BREWING_STAND, 1), new Object[] { " B ", "###", Character.valueOf('#'), Block.COBBLESTONE, Character.valueOf('B'), Item.BLAZE_ROD});
this.registerShapedRecipe(new ItemStack(Block.JACK_O_LANTERN, 1), new Object[] { "A", "B", Character.valueOf('A'), Block.PUMPKIN, Character.valueOf('B'), Block.TORCH});
this.registerShapedRecipe(new ItemStack(Item.STORAGE_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Block.CHEST, Character.valueOf('B'), Item.MINECART});
this.registerShapedRecipe(new ItemStack(Item.POWERED_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Block.FURNACE, Character.valueOf('B'), Item.MINECART});
this.registerShapedRecipe(new ItemStack(Item.BOAT, 1), new Object[] { "# #", "###", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Item.BUCKET, 1), new Object[] { "# #", " # ", Character.valueOf('#'), Item.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Item.FLINT_AND_STEEL, 1), new Object[] { "A ", " B", Character.valueOf('A'), Item.IRON_INGOT, Character.valueOf('B'), Item.FLINT});
this.registerShapedRecipe(new ItemStack(Item.BREAD, 1), new Object[] { "###", Character.valueOf('#'), Item.WHEAT});
this.registerShapedRecipe(new ItemStack(Block.WOOD_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Item.FISHING_ROD, 1), new Object[] { " #", " #X", "# X", Character.valueOf('#'), Item.STICK, Character.valueOf('X'), Item.STRING});
this.registerShapedRecipe(new ItemStack(Block.COBBLESTONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Block.COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Block.BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Block.BRICK});
this.registerShapedRecipe(new ItemStack(Block.STONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Block.SMOOTH_BRICK});
this.registerShapedRecipe(new ItemStack(Block.NETHER_BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Block.NETHER_BRICK});
this.registerShapedRecipe(new ItemStack(Item.PAINTING, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Item.STICK, Character.valueOf('X'), Block.WOOL});
this.registerShapedRecipe(new ItemStack(Item.GOLDEN_APPLE, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Item.GOLD_NUGGET, Character.valueOf('X'), Item.APPLE});
this.registerShapedRecipe(new ItemStack(Block.LEVER, 1), new Object[] { "X", "#", Character.valueOf('#'), Block.COBBLESTONE, Character.valueOf('X'), Item.STICK});
this.registerShapedRecipe(new ItemStack(Block.REDSTONE_TORCH_ON, 1), new Object[] { "X", "#", Character.valueOf('#'), Item.STICK, Character.valueOf('X'), Item.REDSTONE});
this.registerShapedRecipe(new ItemStack(Item.DIODE, 1), new Object[] { "#X#", "III", Character.valueOf('#'), Block.REDSTONE_TORCH_ON, Character.valueOf('X'), Item.REDSTONE, Character.valueOf('I'), Block.STONE});
this.registerShapedRecipe(new ItemStack(Item.WATCH, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Item.GOLD_INGOT, Character.valueOf('X'), Item.REDSTONE});
this.registerShapedRecipe(new ItemStack(Item.COMPASS, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Item.IRON_INGOT, Character.valueOf('X'), Item.REDSTONE});
this.registerShapedRecipe(new ItemStack(Item.MAP, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Item.PAPER, Character.valueOf('X'), Item.COMPASS});
this.registerShapedRecipe(new ItemStack(Block.STONE_BUTTON, 1), new Object[] { "#", "#", Character.valueOf('#'), Block.STONE});
this.registerShapedRecipe(new ItemStack(Block.STONE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Block.STONE});
this.registerShapedRecipe(new ItemStack(Block.WOOD_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.DISPENSER, 1), new Object[] { "###", "#X#", "#R#", Character.valueOf('#'), Block.COBBLESTONE, Character.valueOf('X'), Item.BOW, Character.valueOf('R'), Item.REDSTONE});
this.registerShapedRecipe(new ItemStack(Block.PISTON, 1), new Object[] { "TTT", "#X#", "#R#", Character.valueOf('#'), Block.COBBLESTONE, Character.valueOf('X'), Item.IRON_INGOT, Character.valueOf('R'), Item.REDSTONE, Character.valueOf('T'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.PISTON_STICKY, 1), new Object[] { "S", "P", Character.valueOf('S'), Item.SLIME_BALL, Character.valueOf('P'), Block.PISTON});
this.registerShapedRecipe(new ItemStack(Item.BED, 1), new Object[] { "###", "XXX", Character.valueOf('#'), Block.WOOL, Character.valueOf('X'), Block.WOOD});
this.registerShapedRecipe(new ItemStack(Block.ENCHANTMENT_TABLE, 1), new Object[] { " B ", "D#D", "###", Character.valueOf('#'), Block.OBSIDIAN, Character.valueOf('B'), Item.BOOK, Character.valueOf('D'), Item.DIAMOND});
this.registerShapelessRecipe(new ItemStack(Item.EYE_OF_ENDER, 1), new Object[] { Item.ENDER_PEARL, Item.BLAZE_POWDER});
this.registerShapelessRecipe(new ItemStack(Item.FIREBALL, 3), new Object[] { Item.SULPHUR, Item.BLAZE_POWDER, Item.COAL});
this.registerShapelessRecipe(new ItemStack(Item.FIREBALL, 3), new Object[] { Item.SULPHUR, Item.BLAZE_POWDER, new ItemStack(Item.COAL, 1, 1)});
//Collections.sort(this.b, new RecipeSorter(this)); // CraftBukkit - removed; see below
this.sort(); // CraftBukkit - moved sort to a separate method
System.out.println(this.recipies.size() + " recipes");
this.recipes.add(new RecipeArmorDye());
this.recipes.add(new RecipeBookClone());
this.recipes.add(new RecipeMapClone());
this.recipes.add(new RecipeMapExtend());
this.recipes.add(new RecipeFireworks());
this.registerShapedRecipe(new ItemStack(Items.PAPER, 3), new Object[] { "###", Character.valueOf('#'), Items.SUGAR_CANE});
this.registerShapelessRecipe(new ItemStack(Items.BOOK, 1), new Object[] { Items.PAPER, Items.PAPER, Items.PAPER, Items.LEATHER});
this.registerShapelessRecipe(new ItemStack(Items.BOOK_AND_QUILL, 1), new Object[] { Items.BOOK, new ItemStack(Items.INK_SACK, 1, 0), Items.FEATHER});
this.registerShapedRecipe(new ItemStack(Blocks.FENCE, 2), new Object[] { "###", "###", Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.COBBLE_WALL, 6, 0), new Object[] { "###", "###", Character.valueOf('#'), Blocks.COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Blocks.COBBLE_WALL, 6, 1), new Object[] { "###", "###", Character.valueOf('#'), Blocks.MOSSY_COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Blocks.NETHER_FENCE, 6), new Object[] { "###", "###", Character.valueOf('#'), Blocks.NETHER_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.JUKEBOX, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.WOOD, Character.valueOf('X'), Items.DIAMOND});
this.registerShapedRecipe(new ItemStack(Items.LEASH, 2), new Object[] { "~~ ", "~O ", " ~", Character.valueOf('~'), Items.STRING, Character.valueOf('O'), Items.SLIME_BALL});
this.registerShapedRecipe(new ItemStack(Blocks.NOTE_BLOCK, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.WOOD, Character.valueOf('X'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Blocks.BOOKSHELF, 1), new Object[] { "###", "XXX", "###", Character.valueOf('#'), Blocks.WOOD, Character.valueOf('X'), Items.BOOK});
this.registerShapedRecipe(new ItemStack(Blocks.SNOW_BLOCK, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.SNOW_BALL});
this.registerShapedRecipe(new ItemStack(Blocks.SNOW, 6), new Object[] { "###", Character.valueOf('#'), Blocks.SNOW_BLOCK});
this.registerShapedRecipe(new ItemStack(Blocks.CLAY, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.CLAY_BALL});
this.registerShapedRecipe(new ItemStack(Blocks.BRICK, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.CLAY_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.GLOWSTONE, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.GLOWSTONE_DUST});
this.registerShapedRecipe(new ItemStack(Blocks.QUARTZ_BLOCK, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.QUARTZ});
this.registerShapedRecipe(new ItemStack(Blocks.WOOL, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.STRING});
this.registerShapedRecipe(new ItemStack(Blocks.TNT, 1), new Object[] { "X#X", "#X#", "X#X", Character.valueOf('X'), Items.SULPHUR, Character.valueOf('#'), Blocks.SAND});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 3), new Object[] { "###", Character.valueOf('#'), Blocks.COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 0), new Object[] { "###", Character.valueOf('#'), Blocks.STONE});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 1), new Object[] { "###", Character.valueOf('#'), Blocks.SANDSTONE});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 4), new Object[] { "###", Character.valueOf('#'), Blocks.BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 5), new Object[] { "###", Character.valueOf('#'), Blocks.SMOOTH_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 6), new Object[] { "###", Character.valueOf('#'), Blocks.NETHER_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.STEP, 6, 7), new Object[] { "###", Character.valueOf('#'), Blocks.QUARTZ_BLOCK});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 0), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 0)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 2), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 2)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 1), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 1)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 3), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 3)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 4), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 4)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STEP, 6, 5), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 5)});
this.registerShapedRecipe(new ItemStack(Blocks.LADDER, 3), new Object[] { "# #", "###", "# #", Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Items.WOOD_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.TRAP_DOOR, 2), new Object[] { "###", "###", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Items.IRON_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Items.SIGN, 3), new Object[] { "###", "###", " X ", Character.valueOf('#'), Blocks.WOOD, Character.valueOf('X'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Items.CAKE, 1), new Object[] { "AAA", "BEB", "CCC", Character.valueOf('A'), Items.MILK_BUCKET, Character.valueOf('B'), Items.SUGAR, Character.valueOf('C'), Items.WHEAT, Character.valueOf('E'), Items.EGG});
this.registerShapedRecipe(new ItemStack(Items.SUGAR, 1), new Object[] { "#", Character.valueOf('#'), Items.SUGAR_CANE});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 0), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, 0)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 1), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, 1)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 2), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, 2)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 3), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, 3)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 4), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG2, 1, 0)});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD, 4, 5), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG2, 1, 1)});
this.registerShapedRecipe(new ItemStack(Items.STICK, 4), new Object[] { "#", "#", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), Items.COAL, Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), new ItemStack(Items.COAL, 1, 1), Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Items.BOWL, 4), new Object[] { "# #", " # ", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Items.GLASS_BOTTLE, 3), new Object[] { "# #", " # ", Character.valueOf('#'), Blocks.GLASS});
this.registerShapedRecipe(new ItemStack(Blocks.RAILS, 16), new Object[] { "X X", "X#X", "X X", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.GOLDEN_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Items.GOLD_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('#'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.ACTIVATOR_RAIL, 6), new Object[] { "XSX", "X#X", "XSX", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('#'), Blocks.REDSTONE_TORCH_ON, Character.valueOf('S'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.DETECTOR_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('#'), Blocks.STONE_PLATE});
this.registerShapedRecipe(new ItemStack(Items.MINECART, 1), new Object[] { "# #", "###", Character.valueOf('#'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Items.CAULDRON, 1), new Object[] { "# #", "# #", "###", Character.valueOf('#'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Items.BREWING_STAND, 1), new Object[] { " B ", "###", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('B'), Items.BLAZE_ROD});
this.registerShapedRecipe(new ItemStack(Blocks.JACK_O_LANTERN, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.PUMPKIN, Character.valueOf('B'), Blocks.TORCH});
this.registerShapedRecipe(new ItemStack(Items.STORAGE_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.CHEST, Character.valueOf('B'), Items.MINECART});
this.registerShapedRecipe(new ItemStack(Items.POWERED_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.FURNACE, Character.valueOf('B'), Items.MINECART});
this.registerShapedRecipe(new ItemStack(Items.MINECART_TNT, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.TNT, Character.valueOf('B'), Items.MINECART});
this.registerShapedRecipe(new ItemStack(Items.MINECART_HOPPER, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.HOPPER, Character.valueOf('B'), Items.MINECART});
this.registerShapedRecipe(new ItemStack(Items.BOAT, 1), new Object[] { "# #", "###", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Items.BUCKET, 1), new Object[] { "# #", " # ", Character.valueOf('#'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Items.FLOWER_POT, 1), new Object[] { "# #", " # ", Character.valueOf('#'), Items.CLAY_BRICK});
this.registerShapelessRecipe(new ItemStack(Items.FLINT_AND_STEEL, 1), new Object[] { new ItemStack(Items.IRON_INGOT, 1), new ItemStack(Items.FLINT, 1)});
this.registerShapedRecipe(new ItemStack(Items.BREAD, 1), new Object[] { "###", Character.valueOf('#'), Items.WHEAT});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 0)});
this.registerShapedRecipe(new ItemStack(Blocks.BIRCH_WOOD_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 2)});
this.registerShapedRecipe(new ItemStack(Blocks.SPRUCE_WOOD_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 1)});
this.registerShapedRecipe(new ItemStack(Blocks.JUNGLE_WOOD_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 3)});
this.registerShapedRecipe(new ItemStack(Blocks.ACACIA_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 4)});
this.registerShapedRecipe(new ItemStack(Blocks.DARK_OAK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.WOOD, 1, 5)});
this.registerShapedRecipe(new ItemStack(Items.FISHING_ROD, 1), new Object[] { " #", " #X", "# X", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.STRING});
this.registerShapedRecipe(new ItemStack(Items.CARROT_STICK, 1), new Object[] { "# ", " X", Character.valueOf('#'), Items.FISHING_ROD, Character.valueOf('X'), Items.CARROT}).c();
this.registerShapedRecipe(new ItemStack(Blocks.COBBLESTONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.COBBLESTONE});
this.registerShapedRecipe(new ItemStack(Blocks.BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.STONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.SMOOTH_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.NETHER_BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.NETHER_BRICK});
this.registerShapedRecipe(new ItemStack(Blocks.SANDSTONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.SANDSTONE});
this.registerShapedRecipe(new ItemStack(Blocks.QUARTZ_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.QUARTZ_BLOCK});
this.registerShapedRecipe(new ItemStack(Items.PAINTING, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Blocks.WOOL});
this.registerShapedRecipe(new ItemStack(Items.ITEM_FRAME, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.LEATHER});
this.registerShapedRecipe(new ItemStack(Items.GOLDEN_APPLE, 1, 0), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_INGOT, Character.valueOf('X'), Items.APPLE});
this.registerShapedRecipe(new ItemStack(Items.GOLDEN_APPLE, 1, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.GOLD_BLOCK, Character.valueOf('X'), Items.APPLE});
this.registerShapedRecipe(new ItemStack(Items.CARROT_GOLDEN, 1, 0), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_NUGGET, Character.valueOf('X'), Items.CARROT});
this.registerShapedRecipe(new ItemStack(Items.SPECKLED_MELON, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_NUGGET, Character.valueOf('X'), Items.MELON});
this.registerShapedRecipe(new ItemStack(Blocks.LEVER, 1), new Object[] { "X", "#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.STICK});
this.registerShapedRecipe(new ItemStack(Blocks.TRIPWIRE_SOURCE, 2), new Object[] { "I", "S", "#", Character.valueOf('#'), Blocks.WOOD, Character.valueOf('S'), Items.STICK, Character.valueOf('I'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Blocks.REDSTONE_TORCH_ON, 1), new Object[] { "X", "#", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Items.DIODE, 1), new Object[] { "#X#", "III", Character.valueOf('#'), Blocks.REDSTONE_TORCH_ON, Character.valueOf('X'), Items.REDSTONE, Character.valueOf('I'), Blocks.STONE});
this.registerShapedRecipe(new ItemStack(Items.REDSTONE_COMPARATOR, 1), new Object[] { " # ", "#X#", "III", Character.valueOf('#'), Blocks.REDSTONE_TORCH_ON, Character.valueOf('X'), Items.QUARTZ, Character.valueOf('I'), Blocks.STONE});
this.registerShapedRecipe(new ItemStack(Items.WATCH, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Items.GOLD_INGOT, Character.valueOf('X'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Items.COMPASS, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Items.IRON_INGOT, Character.valueOf('X'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Items.MAP_EMPTY, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.PAPER, Character.valueOf('X'), Items.COMPASS});
this.registerShapedRecipe(new ItemStack(Blocks.STONE_BUTTON, 1), new Object[] { "#", Character.valueOf('#'), Blocks.STONE});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_BUTTON, 1), new Object[] { "#", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.STONE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Blocks.STONE});
this.registerShapedRecipe(new ItemStack(Blocks.WOOD_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.IRON_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Items.IRON_INGOT});
this.registerShapedRecipe(new ItemStack(Blocks.GOLD_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Items.GOLD_INGOT});
this.registerShapedRecipe(new ItemStack(Blocks.DISPENSER, 1), new Object[] { "###", "#X#", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.BOW, Character.valueOf('R'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Blocks.DROPPER, 1), new Object[] { "###", "# #", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('R'), Items.REDSTONE});
this.registerShapedRecipe(new ItemStack(Blocks.PISTON, 1), new Object[] { "TTT", "#X#", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('T'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.PISTON_STICKY, 1), new Object[] { "S", "P", Character.valueOf('S'), Items.SLIME_BALL, Character.valueOf('P'), Blocks.PISTON});
this.registerShapedRecipe(new ItemStack(Items.BED, 1), new Object[] { "###", "XXX", Character.valueOf('#'), Blocks.WOOL, Character.valueOf('X'), Blocks.WOOD});
this.registerShapedRecipe(new ItemStack(Blocks.ENCHANTMENT_TABLE, 1), new Object[] { " B ", "D#D", "###", Character.valueOf('#'), Blocks.OBSIDIAN, Character.valueOf('B'), Items.BOOK, Character.valueOf('D'), Items.DIAMOND});
this.registerShapedRecipe(new ItemStack(Blocks.ANVIL, 1), new Object[] { "III", " i ", "iii", Character.valueOf('I'), Blocks.IRON_BLOCK, Character.valueOf('i'), Items.IRON_INGOT});
this.registerShapelessRecipe(new ItemStack(Items.EYE_OF_ENDER, 1), new Object[] { Items.ENDER_PEARL, Items.BLAZE_POWDER});
this.registerShapelessRecipe(new ItemStack(Items.FIREBALL, 3), new Object[] { Items.SULPHUR, Items.BLAZE_POWDER, Items.COAL});
this.registerShapelessRecipe(new ItemStack(Items.FIREBALL, 3), new Object[] { Items.SULPHUR, Items.BLAZE_POWDER, new ItemStack(Items.COAL, 1, 1)});
this.registerShapedRecipe(new ItemStack(Blocks.DAYLIGHT_DETECTOR), new Object[] { "GGG", "QQQ", "WWW", Character.valueOf('G'), Blocks.GLASS, Character.valueOf('Q'), Items.QUARTZ, Character.valueOf('W'), Blocks.WOOD_STEP});
this.registerShapedRecipe(new ItemStack(Blocks.HOPPER), new Object[] { "I I", "ICI", " I ", Character.valueOf('I'), Items.IRON_INGOT, Character.valueOf('C'), Blocks.CHEST});
// Collections.sort(this.recipes, new RecipeSorter(this)); // CraftBukkit - moved below
this.sort(); // CraftBukkit - call new sort method
}
// CraftBukkit start
public void sort() {
Collections.sort(this.recipies, new RecipeSorter(this));
Collections.sort(this.recipes, new RecipeSorter(this));
}
// CraftBukkit end
public void registerShapedRecipe(ItemStack itemstack, Object... aobject) { // CraftBukkit - default -> public
// CraftBukkit - default -> public
public ShapedRecipes registerShapedRecipe(ItemStack itemstack, Object... aobject) {
String s = "";
int i = 0;
int j = 0;
@@ -150,7 +194,7 @@ public class CraftingManager {
if (aobject[i + 1] instanceof Item) {
itemstack1 = new ItemStack((Item) aobject[i + 1]);
} else if (aobject[i + 1] instanceof Block) {
itemstack1 = new ItemStack((Block) aobject[i + 1], 1, -1);
itemstack1 = new ItemStack((Block) aobject[i + 1], 1, 32767);
} else if (aobject[i + 1] instanceof ItemStack) {
itemstack1 = (ItemStack) aobject[i + 1];
}
@@ -170,10 +214,14 @@ public class CraftingManager {
}
}
this.recipies.add(new ShapedRecipes(j, k, aitemstack, itemstack));
ShapedRecipes shapedrecipes = new ShapedRecipes(j, k, aitemstack, itemstack);
this.recipes.add(shapedrecipes);
return shapedrecipes;
}
public void registerShapelessRecipe(ItemStack itemstack, Object... aobject) { // CraftBukkit - default -> public
// CraftBukkit - default -> public
public void registerShapelessRecipe(ItemStack itemstack, Object... aobject) {
ArrayList arraylist = new ArrayList();
Object[] aobject1 = aobject;
int i = aobject.length;
@@ -194,10 +242,10 @@ public class CraftingManager {
}
}
this.recipies.add(new ShapelessRecipes(itemstack, arraylist));
this.recipes.add(new ShapelessRecipes(itemstack, arraylist));
}
public ItemStack craft(InventoryCrafting inventorycrafting) {
public ItemStack craft(InventoryCrafting inventorycrafting, World world) {
int i = 0;
ItemStack itemstack = null;
ItemStack itemstack1 = null;
@@ -220,19 +268,19 @@ public class CraftingManager {
}
}
if (i == 2 && itemstack.id == itemstack1.id && itemstack.count == 1 && itemstack1.count == 1 && Item.byId[itemstack.id].g()) {
Item item = Item.byId[itemstack.id];
int k = item.getMaxDurability() - itemstack.g();
int l = item.getMaxDurability() - itemstack1.g();
int i1 = k + l + item.getMaxDurability() * 10 / 100;
if (i == 2 && itemstack.getItem() == itemstack1.getItem() && itemstack.count == 1 && itemstack1.count == 1 && itemstack.getItem().usesDurability()) {
Item item = itemstack.getItem();
int k = item.getMaxDurability() - itemstack.j();
int l = item.getMaxDurability() - itemstack1.j();
int i1 = k + l + item.getMaxDurability() * 5 / 100;
int j1 = item.getMaxDurability() - i1;
if (j1 < 0) {
j1 = 0;
}
// CraftBukkit start - construct a dummy repair recipe
ItemStack result = new ItemStack(itemstack.id, 1, j1);
// CraftBukkit start - Construct a dummy repair recipe
ItemStack result = new ItemStack(itemstack.getItem(), 1, j1);
List<ItemStack> ingredients = new ArrayList<ItemStack>();
ingredients.add(itemstack.cloneItemStack());
ingredients.add(itemstack1.cloneItemStack());
@@ -242,24 +290,24 @@ public class CraftingManager {
return result;
// CraftBukkit end
} else {
for (j = 0; j < this.recipies.size(); ++j) {
CraftingRecipe craftingrecipe = (CraftingRecipe) this.recipies.get(j);
for (j = 0; j < this.recipes.size(); ++j) {
IRecipe irecipe = (IRecipe) this.recipes.get(j);
if (craftingrecipe.a(inventorycrafting)) {
if (irecipe.a(inventorycrafting, world)) {
// CraftBukkit start - INVENTORY_PRE_CRAFT event
inventorycrafting.currentRecipe = craftingrecipe;
ItemStack result = craftingrecipe.b(inventorycrafting);
result = CraftEventFactory.callPreCraftEvent(inventorycrafting, result, lastCraftView, false);
return result;
inventorycrafting.currentRecipe = irecipe;
ItemStack result = irecipe.a(inventorycrafting);
return CraftEventFactory.callPreCraftEvent(inventorycrafting, result, lastCraftView, false);
// CraftBukkit end
}
}
inventorycrafting.currentRecipe = null; // CraftBukkit
inventorycrafting.currentRecipe = null; // CraftBukkit - Clear recipe when no recipe is found
return null;
}
}
public List getRecipies() {
return this.recipies;
public List getRecipes() {
return this.recipes;
}
}

View File

@@ -1,16 +0,0 @@
package net.minecraft.server;
import org.bukkit.inventory.Recipe; // CraftBukkit
public interface CraftingRecipe {
boolean a(InventoryCrafting inventorycrafting);
ItemStack b(InventoryCrafting inventorycrafting);
int a();
ItemStack b();
Recipe toBukkitRecipe(); // CraftBukkit
}

View File

@@ -0,0 +1,235 @@
package net.minecraft.server;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import net.minecraft.util.org.apache.commons.io.IOUtils;
import net.minecraft.util.org.apache.commons.lang3.ArrayUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CrashReport {
private static final Logger a = LogManager.getLogger();
private final String b;
private final Throwable c;
private final CrashReportSystemDetails d = new CrashReportSystemDetails(this, "System Details");
private final List e = new ArrayList();
private File f;
private boolean g = true;
private StackTraceElement[] h = new StackTraceElement[0];
public CrashReport(String s, Throwable throwable) {
this.b = s;
this.c = throwable;
this.h();
}
private void h() {
this.d.a("Minecraft Version", (Callable) (new CrashReportVersion(this)));
this.d.a("Operating System", (Callable) (new CrashReportOperatingSystem(this)));
this.d.a("Java Version", (Callable) (new CrashReportJavaVersion(this)));
this.d.a("Java VM Version", (Callable) (new CrashReportJavaVMVersion(this)));
this.d.a("Memory", (Callable) (new CrashReportMemory(this)));
this.d.a("JVM Flags", (Callable) (new CrashReportJVMFlags(this)));
this.d.a("AABB Pool Size", (Callable) (new CrashReportAABBPoolSize(this)));
this.d.a("IntCache", (Callable) (new CrashReportIntCacheSize(this)));
this.d.a("CraftBukkit Information", (Callable) (new org.bukkit.craftbukkit.CraftCrashReport())); // CraftBukkit
}
public String a() {
return this.b;
}
public Throwable b() {
return this.c;
}
public void a(StringBuilder stringbuilder) {
if ((this.h == null || this.h.length <= 0) && this.e.size() > 0) {
this.h = (StackTraceElement[]) ArrayUtils.subarray(((CrashReportSystemDetails) this.e.get(0)).a(), 0, 1);
}
if (this.h != null && this.h.length > 0) {
stringbuilder.append("-- Head --\n");
stringbuilder.append("Stacktrace:\n");
StackTraceElement[] astacktraceelement = this.h;
int i = astacktraceelement.length;
for (int j = 0; j < i; ++j) {
StackTraceElement stacktraceelement = astacktraceelement[j];
stringbuilder.append("\t").append("at ").append(stacktraceelement.toString());
stringbuilder.append("\n");
}
stringbuilder.append("\n");
}
Iterator iterator = this.e.iterator();
while (iterator.hasNext()) {
CrashReportSystemDetails crashreportsystemdetails = (CrashReportSystemDetails) iterator.next();
crashreportsystemdetails.a(stringbuilder);
stringbuilder.append("\n\n");
}
this.d.a(stringbuilder);
}
public String d() {
StringWriter stringwriter = null;
PrintWriter printwriter = null;
Object object = this.c;
if (((Throwable) object).getMessage() == null) {
if (object instanceof NullPointerException) {
object = new NullPointerException(this.b);
} else if (object instanceof StackOverflowError) {
object = new StackOverflowError(this.b);
} else if (object instanceof OutOfMemoryError) {
object = new OutOfMemoryError(this.b);
}
((Throwable) object).setStackTrace(this.c.getStackTrace());
}
String s = ((Throwable) object).toString();
try {
stringwriter = new StringWriter();
printwriter = new PrintWriter(stringwriter);
((Throwable) object).printStackTrace(printwriter);
s = stringwriter.toString();
} finally {
IOUtils.closeQuietly(stringwriter);
IOUtils.closeQuietly(printwriter);
}
return s;
}
public String e() {
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("---- Minecraft Crash Report ----\n");
stringbuilder.append("// ");
stringbuilder.append(i());
stringbuilder.append("\n\n");
stringbuilder.append("Time: ");
stringbuilder.append((new SimpleDateFormat()).format(new Date()));
stringbuilder.append("\n");
stringbuilder.append("Description: ");
stringbuilder.append(this.b);
stringbuilder.append("\n\n");
stringbuilder.append(this.d());
stringbuilder.append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n");
for (int i = 0; i < 87; ++i) {
stringbuilder.append("-");
}
stringbuilder.append("\n\n");
this.a(stringbuilder);
return stringbuilder.toString();
}
public boolean a(File file1) {
if (this.f != null) {
return false;
} else {
if (file1.getParentFile() != null) {
file1.getParentFile().mkdirs();
}
try {
FileWriter filewriter = new FileWriter(file1);
filewriter.write(this.e());
filewriter.close();
this.f = file1;
return true;
} catch (Throwable throwable) {
a.error("Could not save crash report to " + file1, throwable);
return false;
}
}
}
public CrashReportSystemDetails g() {
return this.d;
}
public CrashReportSystemDetails a(String s) {
return this.a(s, 1);
}
public CrashReportSystemDetails a(String s, int i) {
CrashReportSystemDetails crashreportsystemdetails = new CrashReportSystemDetails(this, s);
if (this.g) {
int j = crashreportsystemdetails.a(i);
StackTraceElement[] astacktraceelement = this.c.getStackTrace();
StackTraceElement stacktraceelement = null;
StackTraceElement stacktraceelement1 = null;
int k = astacktraceelement.length - j;
if (k < 0) {
System.out.println("Negative index in crash report handler (" + astacktraceelement.length + "/" + j + ")");
}
if (astacktraceelement != null && 0 <= k && k < astacktraceelement.length) {
stacktraceelement = astacktraceelement[k];
if (astacktraceelement.length + 1 - j < astacktraceelement.length) {
stacktraceelement1 = astacktraceelement[astacktraceelement.length + 1 - j];
}
}
this.g = crashreportsystemdetails.a(stacktraceelement, stacktraceelement1);
if (j > 0 && !this.e.isEmpty()) {
CrashReportSystemDetails crashreportsystemdetails1 = (CrashReportSystemDetails) this.e.get(this.e.size() - 1);
crashreportsystemdetails1.b(j);
} else if (astacktraceelement != null && astacktraceelement.length >= j && 0 <= k && k < astacktraceelement.length) {
this.h = new StackTraceElement[astacktraceelement.length - j];
System.arraycopy(astacktraceelement, 0, this.h, 0, this.h.length);
} else {
this.g = false;
}
}
this.e.add(crashreportsystemdetails);
return crashreportsystemdetails;
}
private static String i() {
String[] astring = new String[] { "Who set us up the TNT?", "Everything\'s going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I\'m sorry, Dave.", "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", "You should try our sister game, Minceraft!", "Don\'t be sad. I\'ll do better next time, I promise!", "Don\'t be sad, have a hug! <3", "I just don\'t know what went wrong :(", "Shall we play a game?", "Quite honestly, I wouldn\'t worry myself about that.", "I bet Cylons wouldn\'t have this problem.", "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", "Hi. I\'m Minecraft, and I\'m a crashaholic.", "Ooh. Shiny.", "This doesn\'t make any sense!", "Why is it breaking :(", "Don\'t do that.", "Ouch. That hurt :(", "You\'re mean.", "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", "There are four lights!", "But it works on my machine."};
try {
return astring[(int) (System.nanoTime() % (long) astring.length)];
} catch (Throwable throwable) {
return "Witty comment unavailable :(";
}
}
public static CrashReport a(Throwable throwable, String s) {
CrashReport crashreport;
if (throwable instanceof ReportedException) {
crashreport = ((ReportedException) throwable).a();
} else {
crashreport = new CrashReport(s, throwable);
}
return crashreport;
}
}

View File

@@ -0,0 +1,472 @@
package net.minecraft.server;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// CraftBukkit start
import java.io.PrintStream;
import org.apache.logging.log4j.Level;
import org.bukkit.craftbukkit.LoggerOutputStream;
import org.bukkit.event.server.ServerCommandEvent;
// CraftBukkit end
public class DedicatedServer extends MinecraftServer implements IMinecraftServer {
private static final Logger i = LogManager.getLogger();
private final List j = Collections.synchronizedList(new ArrayList());
private RemoteStatusListener k;
private RemoteControlListener l;
public PropertyManager propertyManager; // CraftBukkit - private -> public
private EULA n;
private boolean generateStructures;
private EnumGamemode p;
private boolean q;
// CraftBukkit start - Signature changed
public DedicatedServer(joptsimple.OptionSet options) {
super(options, Proxy.NO_PROXY);
// super(file1, Proxy.NO_PROXY);
// CraftBukkit end
new ThreadSleepForever(this, "Server Infinisleeper");
}
protected boolean init() throws java.net.UnknownHostException { // CraftBukkit - throws UnknownHostException
ThreadCommandReader threadcommandreader = new ThreadCommandReader(this, "Server console handler");
threadcommandreader.setDaemon(true);
threadcommandreader.start();
// CraftBukkit start - TODO: handle command-line logging arguments
java.util.logging.Logger global = java.util.logging.Logger.getLogger("");
global.setUseParentHandlers(false);
for (java.util.logging.Handler handler : global.getHandlers()) {
global.removeHandler(handler);
}
global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler());
final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger());
for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) {
if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) {
logger.removeAppender(appender);
}
}
new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start();
System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true));
System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true));
// CraftBukkit end
i.info("Starting minecraft server version 1.7.10");
if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
i.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
}
i.info("Loading properties");
this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support
this.n = new EULA(new File("eula.txt"));
if (!this.n.a()) {
i.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info.");
this.n.b();
return false;
} else {
if (this.N()) {
this.c("127.0.0.1");
} else {
this.setOnlineMode(this.propertyManager.getBoolean("online-mode", true));
this.c(this.propertyManager.getString("server-ip", ""));
}
this.setSpawnAnimals(this.propertyManager.getBoolean("spawn-animals", true));
this.setSpawnNPCs(this.propertyManager.getBoolean("spawn-npcs", true));
this.setPvP(this.propertyManager.getBoolean("pvp", true));
this.setAllowFlight(this.propertyManager.getBoolean("allow-flight", false));
this.setTexturePack(this.propertyManager.getString("resource-pack", ""));
this.setMotd(this.propertyManager.getString("motd", "A Minecraft Server"));
this.setForceGamemode(this.propertyManager.getBoolean("force-gamemode", false));
this.setIdleTimeout(this.propertyManager.getInt("player-idle-timeout", 0));
if (this.propertyManager.getInt("difficulty", 1) < 0) {
this.propertyManager.setProperty("difficulty", Integer.valueOf(0));
} else if (this.propertyManager.getInt("difficulty", 1) > 3) {
this.propertyManager.setProperty("difficulty", Integer.valueOf(3));
}
this.generateStructures = this.propertyManager.getBoolean("generate-structures", true);
int gamemode = this.propertyManager.getInt("gamemode", EnumGamemode.SURVIVAL.getId()); // CraftBukkit - Unique name to avoid stomping on logger
this.p = WorldSettings.a(gamemode); // CraftBukkit - Use new name
i.info("Default game type: " + this.p);
InetAddress inetaddress = null;
if (this.getServerIp().length() > 0) {
inetaddress = InetAddress.getByName(this.getServerIp());
}
if (this.L() < 0) {
this.setPort(this.propertyManager.getInt("server-port", 25565));
}
i.info("Generating keypair");
this.a(MinecraftEncryption.b());
i.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.L());
try {
this.ai().a(inetaddress, this.L());
} catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable
i.warn("**** FAILED TO BIND TO PORT!");
i.warn("The exception was: {}", new Object[] { ioexception.toString()});
i.warn("Perhaps a server is already running on that port?");
return false;
}
this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit
if (!this.getOnlineMode()) {
i.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
i.warn("The server will make no attempt to authenticate usernames. Beware.");
i.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose.");
i.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
}
if (this.aE()) {
this.getUserCache().c();
}
if (!NameReferencingFileConverter.a(this.propertyManager)) {
return false;
} else {
// this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit - moved up
this.convertable = new WorldLoaderServer(server.getWorldContainer()); // CraftBukkit - moved from MinecraftServer constructor
long j = System.nanoTime();
if (this.O() == null) {
this.k(this.propertyManager.getString("level-name", "world"));
}
String s = this.propertyManager.getString("level-seed", "");
String s1 = this.propertyManager.getString("level-type", "DEFAULT");
String s2 = this.propertyManager.getString("generator-settings", "");
long k = (new Random()).nextLong();
if (s.length() > 0) {
try {
long l = Long.parseLong(s);
if (l != 0L) {
k = l;
}
} catch (NumberFormatException numberformatexception) {
k = (long) s.hashCode();
}
}
WorldType worldtype = WorldType.getType(s1);
if (worldtype == null) {
worldtype = WorldType.NORMAL;
}
this.at();
this.getEnableCommandBlock();
this.l();
this.getSnooperEnabled();
this.c(this.propertyManager.getInt("max-build-height", 256));
this.c((this.getMaxBuildHeight() + 8) / 16 * 16);
this.c(MathHelper.a(this.getMaxBuildHeight(), 64, 256));
this.propertyManager.setProperty("max-build-height", Integer.valueOf(this.getMaxBuildHeight()));
i.info("Preparing level \"" + this.O() + "\"");
this.a(this.O(), this.O(), k, worldtype, s2);
long i1 = System.nanoTime() - j;
String s3 = String.format("%.3fs", new Object[] { Double.valueOf((double) i1 / 1.0E9D)});
i.info("Done (" + s3 + ")! For help, type \"help\" or \"?\"");
if (this.propertyManager.getBoolean("enable-query", false)) {
i.info("Starting GS4 status listener");
this.k = new RemoteStatusListener(this);
this.k.a();
}
if (this.propertyManager.getBoolean("enable-rcon", false)) {
i.info("Starting remote control listener");
this.l = new RemoteControlListener(this);
this.l.a();
this.remoteConsole = new org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender(); // CraftBukkit
}
// CraftBukkit start
if (this.server.getBukkitSpawnRadius() > -1) {
i.info("'settings.spawn-radius' in bukkit.yml has been moved to 'spawn-protection' in server.properties. I will move your config for you.");
this.propertyManager.properties.remove("spawn-protection");
this.propertyManager.getInt("spawn-protection", this.server.getBukkitSpawnRadius());
this.server.removeBukkitSpawnRadius();
this.propertyManager.savePropertiesFile();
}
// CraftBukkit end
return true;
}
}
}
// CraftBukkit start
public PropertyManager getPropertyManager() {
return this.propertyManager;
}
// CraftBukkit end
public boolean getGenerateStructures() {
return this.generateStructures;
}
public EnumGamemode getGamemode() {
return this.p;
}
public EnumDifficulty getDifficulty() {
return EnumDifficulty.getById(this.propertyManager.getInt("difficulty", 1));
}
public boolean isHardcore() {
return this.propertyManager.getBoolean("hardcore", false);
}
protected void a(CrashReport crashreport) {}
public CrashReport b(CrashReport crashreport) {
crashreport = super.b(crashreport);
crashreport.g().a("Is Modded", (Callable) (new CrashReportModded(this)));
crashreport.g().a("Type", (Callable) (new CrashReportType(this)));
return crashreport;
}
protected void t() {
System.exit(0);
}
public void v() { // CraftBukkit - protected -> public (decompile error?)
super.v();
this.aB();
}
public boolean getAllowNether() {
return this.propertyManager.getBoolean("allow-nether", true);
}
public boolean getSpawnMonsters() {
return this.propertyManager.getBoolean("spawn-monsters", true);
}
public void a(MojangStatisticsGenerator mojangstatisticsgenerator) {
mojangstatisticsgenerator.a("whitelist_enabled", Boolean.valueOf(this.aC().getHasWhitelist()));
mojangstatisticsgenerator.a("whitelist_count", Integer.valueOf(this.aC().getWhitelisted().length));
super.a(mojangstatisticsgenerator);
}
public boolean getSnooperEnabled() {
return this.propertyManager.getBoolean("snooper-enabled", true);
}
public void issueCommand(String s, ICommandListener icommandlistener) {
this.j.add(new ServerCommand(s, icommandlistener));
}
public void aB() {
while (!this.j.isEmpty()) {
ServerCommand servercommand = (ServerCommand) this.j.remove(0);
// CraftBukkit start - ServerCommand for preprocessing
ServerCommandEvent event = new ServerCommandEvent(this.console, servercommand.command);
this.server.getPluginManager().callEvent(event);
servercommand = new ServerCommand(event.getCommand(), servercommand.source);
// this.getCommandHandler().a(servercommand.source, servercommand.command); // Called in dispatchServerCommand
this.server.dispatchServerCommand(this.console, servercommand);
// CraftBukkit end
}
}
public boolean X() {
return true;
}
public DedicatedPlayerList aC() {
return (DedicatedPlayerList) super.getPlayerList();
}
public int a(String s, int i) {
return this.propertyManager.getInt(s, i);
}
public String a(String s, String s1) {
return this.propertyManager.getString(s, s1);
}
public boolean a(String s, boolean flag) {
return this.propertyManager.getBoolean(s, flag);
}
public void a(String s, Object object) {
this.propertyManager.setProperty(s, object);
}
public void a() {
this.propertyManager.savePropertiesFile();
}
public String b() {
File file1 = this.propertyManager.c();
return file1 != null ? file1.getAbsolutePath() : "No settings file";
}
public void aD() {
ServerGUI.a(this);
this.q = true;
}
public boolean ak() {
return this.q;
}
public String a(EnumGamemode enumgamemode, boolean flag) {
return "";
}
public boolean getEnableCommandBlock() {
return this.propertyManager.getBoolean("enable-command-block", false);
}
public int getSpawnProtection() {
return this.propertyManager.getInt("spawn-protection", super.getSpawnProtection());
}
public boolean a(World world, int i, int j, int k, EntityHuman entityhuman) {
if (world.worldProvider.dimension != 0) {
return false;
} else if (this.aC().getOPs().isEmpty()) {
return false;
} else if (this.aC().isOp(entityhuman.getProfile())) {
return false;
} else if (this.getSpawnProtection() <= 0) {
return false;
} else {
ChunkCoordinates chunkcoordinates = world.getSpawn();
int l = MathHelper.a(i - chunkcoordinates.x);
int i1 = MathHelper.a(k - chunkcoordinates.z);
int j1 = Math.max(l, i1);
return j1 <= this.getSpawnProtection();
}
}
public int l() {
return this.propertyManager.getInt("op-permission-level", 4);
}
public void setIdleTimeout(int i) {
super.setIdleTimeout(i);
this.propertyManager.setProperty("player-idle-timeout", Integer.valueOf(i));
this.a();
}
public boolean m() {
return this.propertyManager.getBoolean("broadcast-rcon-to-ops", true);
}
public boolean at() {
return this.propertyManager.getBoolean("announce-player-achievements", true);
}
protected boolean aE() {
boolean flag = false;
int i;
for (i = 0; !flag && i <= 2; ++i) {
if (i > 0) {
// CraftBukkit - Fix decompiler stomping on field
DedicatedServer.i.warn("Encountered a problem while converting the user banlist, retrying in a few seconds");
this.aG();
}
flag = NameReferencingFileConverter.a((MinecraftServer) this);
}
boolean flag1 = false;
for (i = 0; !flag1 && i <= 2; ++i) {
if (i > 0) {
// CraftBukkit - Fix decompiler stomping on field
DedicatedServer.i.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds");
this.aG();
}
flag1 = NameReferencingFileConverter.b((MinecraftServer) this);
}
boolean flag2 = false;
for (i = 0; !flag2 && i <= 2; ++i) {
if (i > 0) {
// CraftBukkit - Fix decompiler stomping on field
DedicatedServer.i.warn("Encountered a problem while converting the op list, retrying in a few seconds");
this.aG();
}
flag2 = NameReferencingFileConverter.c((MinecraftServer) this);
}
boolean flag3 = false;
for (i = 0; !flag3 && i <= 2; ++i) {
if (i > 0) {
// CraftBukkit - Fix decompiler stomping on field
DedicatedServer.i.warn("Encountered a problem while converting the whitelist, retrying in a few seconds");
this.aG();
}
flag3 = NameReferencingFileConverter.d((MinecraftServer) this);
}
boolean flag4 = false;
for (i = 0; !flag4 && i <= 2; ++i) {
if (i > 0) {
// CraftBukkit - Fix decompiler stomping on field
DedicatedServer.i.warn("Encountered a problem while converting the player save files, retrying in a few seconds");
this.aG();
}
flag4 = NameReferencingFileConverter.a(this, this.propertyManager);
}
return flag || flag1 || flag2 || flag3 || flag4;
}
private void aG() {
try {
Thread.sleep(5000L);
} catch (InterruptedException interruptedexception) {
;
}
}
public PlayerList getPlayerList() {
return this.aC();
}
static Logger aF() {
return i;
}
}

View File

@@ -0,0 +1,67 @@
package net.minecraft.server;
import java.util.List;
// CraftBukkit start
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.event.block.BlockDispenseEvent;
// CraftBukkit end
final class DispenseBehaviorArmor extends DispenseBehaviorItem {
DispenseBehaviorArmor() {}
protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) {
EnumFacing enumfacing = BlockDispenser.b(isourceblock.h());
int i = isourceblock.getBlockX() + enumfacing.getAdjacentX();
int j = isourceblock.getBlockY() + enumfacing.getAdjacentY();
int k = isourceblock.getBlockZ() + enumfacing.getAdjacentZ();
AxisAlignedBB axisalignedbb = AxisAlignedBB.a((double) i, (double) j, (double) k, (double) (i + 1), (double) (j + 1), (double) (k + 1));
List list = isourceblock.k().a(EntityLiving.class, axisalignedbb, (IEntitySelector) (new EntitySelectorEquipable(itemstack)));
if (list.size() > 0) {
EntityLiving entityliving = (EntityLiving) list.get(0);
int l = entityliving instanceof EntityHuman ? 1 : 0;
int i1 = EntityInsentient.b(itemstack);
// CraftBukkit start
ItemStack itemstack1 = itemstack.a(1);
World world = isourceblock.k();
org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockX(), isourceblock.getBlockY(), isourceblock.getBlockZ());
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
if (!BlockDispenser.eventFired) {
world.getServer().getPluginManager().callEvent(event);
}
if (event.isCancelled()) {
itemstack.count++;
return itemstack;
}
if (!event.getItem().equals(craftItem)) {
itemstack.count++;
// Chain to handler for new item
ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.a.get(eventStack.getItem());
if (idispensebehavior != IDispenseBehavior.a && idispensebehavior != this) {
idispensebehavior.a(isourceblock, eventStack);
return itemstack;
}
}
// CraftBukkit end
itemstack1.count = 1;
entityliving.setEquipment(i1 - l, itemstack1);
if (entityliving instanceof EntityInsentient) {
((EntityInsentient) entityliving).a(i1, 2.0F);
}
// --itemstack.count; // CraftBukkit - handled above
return itemstack;
} else {
return super.b(isourceblock, itemstack);
}
}
}

Some files were not shown because too many files have changed in this diff Show More