/flyingblocksapi

API for developers to create flying and moving blocks in Minecraft (http://minecraft.net) using Bukkit (http://bukkit.org).

Primary LanguageJavaGNU General Public License v3.0GPL-3.0

flyingblocksapi

API for developers to create flying and moving blocks in Minecraft using Bukkit.

Some Impressions

Huh, a nice-looking image should be here :(

Used in...

... no plugin yet :( You can write me a PM on Bukkit, on Reddit, send me an email, or make a pull request if you want your plugin to appear here.

Important Links

Supported Versions

As this plugin uses submodules, you can use the same plugin JAR for different Minecraft versions despite the frequent relocations of the NMS/OBC classes. Currently, this includes the versions

  • 1_6_R3 (1.6.4)
  • 1_7_R1 (1.7.0 - 1.7.2)
  • 1_7_R2 (1.7.5)
  • 1_7_R3 (1.7.8, 1.7.9)
  • 1_7_R4 (1.7.10)

Overview

Commands & Permissions

  • /flyingblocks-removeall - Removes all flying blocks from the worlds. Good for debugging. flyingblocks.removeall (OP by default)
  • /flyingblocks-examples - Lists all commands of the examples, check them out! :P Note: Most of the examples depend on world ticks (day/night cycle needs to be running) flyingblocks.examples (OP by default)

Building

This plugin uses Maven as build tool. Just download this repositotry's zipfile or clone it via Git using git clone http://github.com/ase34/flyingblocksapi.git, then invoke mvn clean package to build a new JAR file.

Important Notice concerning the DCMA takedown

Since the official Maven repos for Bukkit and CraftBukkit went down due to the DCMA takedown notice, please compile and install Bukkit and CraftBukkit by yourself into your local Maven repository. Xephi's forks of Bukkit and Craftbukkit are equal with the (Craft-)Bukkit repos as befor the takedown.

If you don't need support for all of the supported CraftBukkit versions, you can comment out the not needed modules out of pom.xml and plugin/pom.xml so you don't need to install the older CraftBukkit versions for compiling.

Example building instructions with support for only v1_7_R4 (MC 1.7.10) with patch: gist

Underlying Technique

This technique is heavily inspired by The Holographic Displays of Asdjke. Without his ideas and research, this plugin would likely never been made. Thanks. This should give you an abstract explanation how this plugin achieves its behavior:

  • First, a Wither Skull will be spawned about 100 blocks above the block's desired spawnpoint. That skull is not affected by gravity at the client, so there is no constant downfall-cancellation (for example, using packets) needed.
  • Then, a Horse is attached to the skull with an age of -4057200. The extremely low age causes the client to render the horse as invisible, but also setting the position of their passengers around 100 block below the horse.
  • Finally, a Falling Sand Block with a different block id is attached to the horse. Because of the age of the horse and the height of the skull, the block appears a the exact spawn position. The falling block is not affected by gravity on the client because it is an (indirect) passenger of the skull.

API Usage

Adding to build path

In order to use the API, you need to add flyingblocksapi to your plugin's build path. If you are not using Maven or comparable, you actually do the same thing like with your craftbukkit.jar or bukkit.jar. For Maven users, I provide a public repository on this GitHub project page. Just add these bits of markup in your pom.xml:

...
<repositories>
  <!-- Bukkit repo -->
  ...
  <repository>
    <id>ase34-repo</id>
    <url>http://ase34.github.io/maven-repo</url>
  </repository>
</repositories>
...
<dependencies>
  <!-- more depenencies -->
  ...
  <dependency>
    <groupId>de.ase34</groupId>
    <artifactId>flyingblocksapi</artifactId>
    <version>LATEST</version>
    <scope>provided</scope>
  </dependency>
</dependencies>
...

Then, don't forget to add depend: [flyingblocksapi] to your plugin.yml.

Implement own movement logic

Using the API as a developer is quite easy, he/she just has to extend the class de.ase34.flyingblocksapi.FlyingBlock and override the onTick() method by his own movement logic. In the method body, some special rules need to be follown:

  • Due to a misimplementation/bug/whatever getBukkitEntity().teleport(Location) does fail for entities with a passenger attached. flyingblocksapi provides an alternative by invoking setLocation(Location). You might use setBlockLocation(Location) to set the location of the block's center and not of the skull (If you are not using default parameters for horse age and height offset, this might not work).
  • In order to set the velocity/direction/movement of the skull using the Bukkit API, please use setVelocity(Vector) and not setDirection(Vector).
  • Please keep in mind that you are modifying the skull entity, not the falling block. The skull is normally located 100 blocks higher than the appearance of the block. (See getHeightOffset())
  • The offset is calibrated so that the y-coordinate of the skull minus the default height offset (getHeightOffset()) is equal to the y-coordinate of the center and not the downfacing side of the block. So, a block spawned at (10.5, 60.5, 23.5) will perfectly align with the grid of the 'normal' blocks.

To spawn the prepared flying block, just construct a new object of a FlyingBlock, and then call spawn(Location), and you're done! Then the onTick() gets then called once every tick. For more information about the methods, please go to the Javadoc page.

Examples

Sample codes are available in the de.ase34.flyingblocksapi.commands.examples package. Many of the examples are using anonymous or nested classes. Here's a small selection:

To see these examples in-game, use the /flyingblocks-examples command.

Other notes for the developer

The developer has to take certain precautions when using this plugin:

  • Flying blocks get removed during

    • Disablings of flyingblocksapi (reloads/stops of the server) in all worlds.
    • WorldUnloadEvents in the unloaded world.
    • When the last player leaves a world in the now empty world.

    To make them persistent, the developer needs to save the blocks (in a file for example) and to respawn them during the opposite events of the above-mentioned (onEnable(), WorldLoadEvent, PlayerJoinEvent).

  • The parameter trackerUpdateInterval specifies how often the NMS entity tracker sends packets to update the location of the flying block per tick. See EntityTrackerEntry.java of the mc-dev repository. (Important lines: 99, 116-129).

    • It does not influence the smoothness of flying blocks with velocities applied. Packets about velocity updates are broadcasted immediately after the onTick() method. However, the tracker still broadcasts packets about the location in the specified interval to prevent desyncs.
    • When teleporting, the updating packet will be sent when the entity tracker triggers. (So, the maximum delay is the value of the tracker-update-interval)

    Thus, choose a high tracker-update-interval (5-10) if your movement only relies on velocities, and choose a low one (1-2) if your movement heavily relies on fast location updates.

  • As the technique requires the Horse entities, the developer has to check if animal entities won't be instantly killed because of the spawn-animals flag set to false in the server.properties file.

Credits & Special Thanks

License

The code is licensed under the terms of the GNU General Public License Version 3. See LICENSE for full license text.

Copyright (C) 2014 ase34

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Language Notice

As I'm not a native english speaker, I appreciate every suggestion concerning the written words of this paper, of the comments in the code, or of the javadoc (spelling, grammar, phrasing, language style, ...). You can write me a PM on Bukkit, on Reddit, send me an email, or make a pull request. Thanks for your tolerance.