43 Commits

Author SHA1 Message Date
e2903514fe read me updated. 2014-02-07 10:54:45 +01:00
44e86059de Bumped version to 2.4.0 2014-02-05 20:48:58 +01:00
fe0946117e Read me updated. 2014-02-05 20:48:37 +01:00
43dd934f48 Docs updated. 2014-02-05 20:43:08 +01:00
b37f1000ab Merge branch 'development' of github.com:craftinc/craftinc-gates into development 2014-02-05 20:36:34 +01:00
c7a423ff20 Display information about allowed vehicles when executing the info command. 2014-02-05 20:36:23 +01:00
b676af278d Display a not allowed while riding message. 2014-02-05 20:23:59 +01:00
a579209037 Do call the exit changed method of the gates manager. 2014-02-05 20:16:16 +01:00
ca74b2e3ed Removed invalid to do notes. 2014-02-05 20:15:56 +01:00
6924e36249 Added soft-depend for multi-world plugins 2014-01-27 09:51:57 +01:00
f8f31640ef Added gate change listener interface used for dynmap. 2014-01-26 14:29:28 +01:00
c80b0f0f68 Fix not persistent allow/deny riding flag. 2014-01-19 21:01:28 +01:00
2bd8b0ff03 Fixed broken migration for old storage versions. 2014-01-06 17:28:59 +01:00
a613b1933a Send messages to players when executing allow/deny riding commands. 2014-01-06 17:21:43 +01:00
d8fff26c9e Added a allow riding attribute to the gate class. Added code to guaranty compatibility. Added two new commands for setting the riding attribute. 2014-01-06 17:13:02 +01:00
0c13d0d3e3 Fix for missing clone of pig attributes. 2013-12-29 09:51:26 +01:00
29592823b6 Bumped version to 2.4.0-DEV 2013-12-29 09:50:14 +01:00
56c6af02b1 Keep velocity when teleporing boats and minecarts. This commit completes issue #10 2013-12-28 16:43:18 +01:00
8b873a6d60 Added support for vehicles. 2013-12-28 15:11:12 +01:00
e36519c246 gitignore updated. 2013-12-28 15:10:30 +01:00
125d327a0d Updated bukkit dependency. 2013-12-28 10:25:09 +01:00
6c8658f7c5 Fixed typo. Did some cleanup. 2013-12-28 10:24:55 +01:00
14041f8cd7 Updated bukkit dependency to 1.7.2-R0.1-SNAPSHOT. 2013-12-08 16:21:18 +01:00
bb4a41e782 Readme updated. #2 2013-11-26 09:21:01 +01:00
82df684c22 Readme updated. 2013-11-26 09:16:14 +01:00
7f89917e81 Updated version to 2.3.0. 2013-11-24 12:55:47 +01:00
a1cb0102f8 Changed the executing phase of deployment script. 2013-11-23 15:31:27 +01:00
5af520f8ea include mcstats in jar file when packaging with maven 2013-11-23 15:11:13 +01:00
28cacfdb19 Updated the changelog and other documents for the upcoming 2.3 release. 2013-11-16 17:54:33 +01:00
757d6b5a48 readme updated. 2013-11-16 15:40:53 +01:00
056b8896a6 Updated bukkit depency. 2013-11-16 15:40:45 +01:00
12a0bba6cc Print the names of nearby gates when executing /gate nb.
Fixed a serious bug when trying to print a very long title.
Made the info command work without a supplied gate id. It then will print information about the closest gate. (Issue #13)
2013-09-17 17:57:31 +02:00
e9a454182a Added the ability to change gate block types. Issue #26.
Refactoring: Added a ConfigurationUtil class. Moved all configuration keys into it.
2013-09-15 17:09:17 +02:00
260cabc509 Small typo fix. 2013-08-07 16:40:59 +02:00
0b29936958 Changed some text getting displayed while executing the info command. 2013-07-27 12:03:38 +02:00
efc30d0ae0 Added the nearby command. Issue #12 2013-07-24 10:39:37 +02:00
f4111fb34f Added a URL and license to the pom file. 2013-07-21 19:29:12 +02:00
37bce23e3d Updated a description inside the plugin.yml. 2013-07-18 12:09:50 +02:00
d5ff63c163 Added Plugin Metrics. 2013-07-16 12:09:20 +02:00
e60c735153 Removed the .settings folder. 2013-07-16 12:08:24 +02:00
013fad2b95 Added a license header to the exitopen command class. 2013-07-11 22:35:55 +02:00
5ace80e6d1 Added an exitopen command. This command will set the exit location of a gate and open it afterwards. 2013-07-11 22:35:01 +02:00
42b293e6bc Updated the pom file:
* Updated (craft-) bukkit dependencies to 1.6.2-R0.1-SNAPSHOT
* Bumped version 2.3.0-DEV
2013-07-11 22:33:38 +02:00
31 changed files with 1058 additions and 161 deletions

1
.gitignore vendored
View File

@ -31,3 +31,4 @@ bukkit/
# bukkit test-server # bukkit test-server
bukkit-testserver/ bukkit-testserver/
dependency-reduced-pom.xml

View File

@ -1,12 +0,0 @@
#Wed Apr 06 16:59:25 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,12 +1,12 @@
The following persons contributed to Craft Inc. Gates (previously named Ancient Gates): The following persons contributed to Craft Inc. Gates (previously named Ancient Gates):
CURRENT MAINTAINER CURRENT MAINTAINERS
Tobias Ottenweller <mail@ottenweller.net> Tobias Ottenweller <mail@ottenweller.net>
Paul Schulze <info@paul-schulze.de> Paul Schulze <info@paul-schulze.de>
FORMER CONTRIBUTOR (alphabetical order) FORMER CONTRIBUTORS (alphabetical order)
Jacob Brunson <jacob@dimensionsmachine.com> Jacob Brunson <jacob@dimensionsmachine.com>
locutus <bladedpenguin@gmail.com> locutus <bladedpenguin@gmail.com>

View File

@ -1,10 +1,5 @@
# Craft Inc. Gates # # Craft Inc. Gates #
<Logo here>
We are happy to finally announce __Craft Inc. Gates__.
This awesome plugin lets you _travel_ to far away places and worlds _faster than light_! Just create a gate at any location and set an exit somewhere else. This awesome plugin lets you _travel_ to far away places and worlds _faster than light_! Just create a gate at any location and set an exit somewhere else.
This has been made available by the hard work of the research and development department of the _Craft Inc. Corporation_. Under the lead of Professor Ddidderr Craftman scientists worked years to find a way to bend time and space inside the Minecraft universe to enable _ultra fast transportation_. This has been made available by the hard work of the research and development department of the _Craft Inc. Corporation_. Under the lead of Professor Ddidderr Craftman scientists worked years to find a way to bend time and space inside the Minecraft universe to enable _ultra fast transportation_.
@ -13,10 +8,12 @@ Now it is time for _you_ to try out this wonderful plugin. Simply install, creat
The key features of this are: The key features of this are:
* Dynmap integration
* Gates with and without frames * Gates with and without frames
* Gates consisting of portal blocks and gates made of air (so called hidden gates) * Gates consisting of portal blocks and gates made of air (so called hidden gates)
* Gates with destinations in different worlds * Gates with destinations in different worlds
* Gates with custom shapes (gates can look any way you want) * Gates with custom shapes (gates can look any way you want)
* Riding through gates
*The Craft Inc. Corporation won't take any responsibility for seasickness, memory loss and sudden suffocation in walls while traveling with one of our gates! *The Craft Inc. Corporation won't take any responsibility for seasickness, memory loss and sudden suffocation in walls while traveling with one of our gates!
@ -57,8 +54,9 @@ Have a look at the [_Commands_](http://dev.bukkit.org/bukkit-plugins/craftinc-ga
## Installing ## ## Installing ##
1. Download the latest release _[here](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/files/)_ 1. Download the latest release _[here](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/files/)_
2. Extract the content of the zip file into the plugins folder of your Bukkit server. 2. Delete any old versions of _Craft Inc. Gates_ (only the .jar files) including the extra dynmap-plugin of this plugin.
3. Start or reload the server. 3. Extract the content of the zip file into the plugins folder of your Bukkit server.
4. Start or reload the server.
## Craft Inc. ## ## Craft Inc. ##
Check out our __[Craft Inc. Minecraft Server](http://www.craftinc.de)__. Everyone is welcome! Check out our __[Craft Inc. Minecraft Server](http://www.craftinc.de)__. Everyone is welcome!
@ -75,13 +73,6 @@ allows players to build a replicator to replicate blocks and other items. (still
coming soon! coming soon!
## Roadmap ## ## Roadmap ##
* __Version 2.3__
* Info-Tools for gates. (Get the name of a gate you standing next to.)
* Search command for nearby gates. (Visually highlight nearby gates. Especially useful for hidden gates!)
* __Future__
* Optionally allow animals and mobs to travel via gates.
* Allow players to use gates while sitting inside a minecart or boat
* Dynmap integration.
* Per player permissions for using and managing gates. * Per player permissions for using and managing gates.
* Horizontal gates. * Horizontal gates.
@ -91,3 +82,4 @@ Please use our [_issue tracker_](https://github.com/craftinc/craftinc-gates/issu
## Legal Information ## ## Legal Information ##
This project is a fork of the original [_Ancient Gates_](https://github.com/bladedpenguin/minecraft-ancient-gates). It is licensed under the [_LGPL_](http://www.gnu.org/licenses/lgpl-3.0.txt) just like the Bukkit project. Thanks to all current and previous [_contributors_](https://github.com/craftinc/craftinc-gates/blob/development/AUTHORS.txt). This project is a fork of the original [_Ancient Gates_](https://github.com/bladedpenguin/minecraft-ancient-gates). It is licensed under the [_LGPL_](http://www.gnu.org/licenses/lgpl-3.0.txt) just like the Bukkit project. Thanks to all current and previous [_contributors_](https://github.com/craftinc/craftinc-gates/blob/development/AUTHORS.txt).
The font used for the Craft Inc. Gates logo is called [_MineCrafter 3_](http://www.minecraftforum.net/topic/892789-minecrafter-3-font-simply-easy/) and has been made available under the creative commons license. Thanks to Asherz08, MadPixel and Ashley Denham for this great font. The font used for the Craft Inc. Gates logo is called [_MineCrafter 3_](http://www.minecraftforum.net/topic/892789-minecrafter-3-font-simply-easy/) and has been made available under the creative commons license. Thanks to Asherz08, MadPixel and Ashley Denham for this great font.
This plugin utilizes [_Hidendra's plugin metrics system_](http://mcstats.org), which means that the following information is collected and sent to mcstats.org: a unique identifier, the server's version of Java, whether the server is in offline or online mode, the plugin's version, the server's version, the OS version/name and architecture, the core count for the CPU, the number of players online, the Metrics version. __You can disable the stat collection via /plugins/PluginMetrics/config.yml if you wish.__

View File

@ -1,3 +1,15 @@
## 2.4.0 ##
* Resolved issues with closing gates (special thanks to THCFrosD)
* Added support for riding through gates (with horses, mine carts, pigs and boats)
* Dynmap integration (extra plugin)
## 2.3.0 ##
* Added a command for setting the exit and opening a gate at once.
* Enabled the ability to change the gate block material.
* Added a command printing all nearby gates while highlighting them.
* Changed the info command to highlight gates.
* Updated the info command to print information about the nearest gate if no gate name got supplied.
## 2.2.1 ## ## 2.2.1 ##
* Changed priority of some event listeners to solve problems with WorldGuard and other protection plugins. * Changed priority of some event listeners to solve problems with WorldGuard and other protection plugins.

View File

@ -1,12 +1,21 @@
* __/gate allowRiding, ar [id]__
Update a gate so players can travel through it while riding.
* __/gate close, c [id]__ * __/gate close, c [id]__
Closes a gate to prevent players from using it. Closes a gate to prevent players from using it.
* __/gate denyRiding, dr [id]__
Update a gate so players can NOT travel through it while riding.
* __/gate delete, del, remove [id]__ * __/gate delete, del, remove [id]__
Removes the gate from the game. Removes the gate from the game.
* __/gate exit, e [id]__ * __/gate exit, e [id]__
Changes the location where the gate will teleport players to your current location. Changes the location where the gate will teleport players to your current location.
* __/gate exitopen, eo [id]__
Changes the location where the gate will teleport players to your current location. Also tries to open that gate afterwards.
* __/gate help, ? [page]__ * __/gate help, ? [page]__
Prints help pages. Prints help pages.
@ -14,7 +23,7 @@ Prints help pages.
Makes a gate NOT consist of gate blocks while open. Makes a gate NOT consist of gate blocks while open.
* __/gate info, i [id]__ * __/gate info, i [id]__
Prints details about a certain gate. Prints details about a certain gate. Will print information about the nearest gate if no _id_ is supplied. Also highlights the gate you're requesting information about.
* __/gate list, ls [page]__ * __/gate list, ls [page]__
Prints all available gates. Prints all available gates.
@ -22,6 +31,9 @@ Prints all available gates.
* __/gate location, lo [id]__ * __/gate location, lo [id]__
Sets the entrance of the gate to your current location. Sets the entrance of the gate to your current location.
* __/gate nearby, nb__
Prints the name of nearby gates. Also highlights them.
* __/gate new, n [id]__ * __/gate new, n [id]__
Creates a gate at your current location. Creates a gate at your current location.

View File

@ -41,11 +41,17 @@ be displayed.
* __gateTeleportNoPermissionMessage__ * __gateTeleportNoPermissionMessage__
A string value going to displayed every time when a player enters a gate and is not A string value going to displayed every time when a player enters a gate and is not allowed to use that gate. Will only be displayed if _showTeleportNoPermissionMessage_
allowed to use that gate. Will only be displayed if _showTeleportNoPermissionMessage_
is set to _true_. is set to _true_.
* __gateTeleportVehicleNotAllowedMessage__
A string value being displayed when a player tries to go through a gate while riding when riding through this gate is disabled. Will only be displayed if _showTeleportNoPermissionMessage_ is set to _true_.
* __showTeleportNoPermissionMessage__ * __showTeleportNoPermissionMessage__
A boolean (_true_ or _false_) determining wether the _no permission message_ will A boolean (_true_ or _false_) determining wether the _no permission message_ will
be displayed. be displayed.
* __gateMaterial__
A String representing the material all gates will consist of. Have a look at our [_Gate Material Page_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/gate-materials/) for all possible values.

27
doc/Gate Materials.md Normal file
View File

@ -0,0 +1,27 @@
Starting with version 2.3.0 different gate materials can be used. You can set them via the configuration file. The following Materials are currently defined:
* sapling
* water
* lava
* cobweb
* grass
* dead bush
* dandelion
* poppy
* brown mushroom
* red mushroom
* torch
* redstone torch (off)
* redstone torch (on)
* fence
* nether portal
* iron bars
* glass pane
* fence gate
* nether brick fence
* nether wart
* end portal
* cobblestone wall
Your favorite material is missing? Please contact us and we will see if we can add it.

View File

@ -1,7 +1,7 @@
name: ${project.name} name: ${project.name}
version: ${project.version} version: ${project.version}
description: A plugin to create gates for fast traveling. description: A plugin to create gates for fast traveling.
softdepend: [Vault] softdepend: [Vault, Multiverse-Core, MultiWorld, RoyalCommands]
author: tomco, s1m0ne author: tomco, s1m0ne
authors: [oloflarsson, locutus, DrAgonmoray, s1m0ne, tomco] authors: [oloflarsson, locutus, DrAgonmoray, s1m0ne, tomco]
website: http://dev.bukkit.org/bukkit-plugins/craftinc-gates/ website: http://dev.bukkit.org/bukkit-plugins/craftinc-gates/
@ -16,7 +16,7 @@ commands:
permissions: permissions:
craftincgates.*: craftincgates.*:
description: Gives access to all ancient gates commands and lets you use open gates. description: Gives access to all Craft Inc. Gates commands.
children: children:
craftincgates.info: true craftincgates.info: true
craftincgates.use: true craftincgates.use: true

66
pom.xml
View File

@ -5,13 +5,25 @@
<groupId>de.craftinc</groupId> <groupId>de.craftinc</groupId>
<artifactId>CraftIncGates</artifactId> <artifactId>CraftIncGates</artifactId>
<name>Craft Inc. Gates</name> <name>Craft Inc. Gates</name>
<url>http://dev.bukkit.org/bukkit-plugins/craftinc-gates/</url>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>2.2.1</version> <version>2.4.0</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<!-- License -->
<licenses>
<license>
<name>GNU Lesser General Public License Version 3</name>
<url>https://www.gnu.org/licenses/lgpl-3.0-standalone.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<build> <build>
<finalName>${project.name} ${project.version}</finalName> <finalName>${project.name} ${project.version}</finalName>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
@ -43,7 +55,7 @@
<executions> <executions>
<execution> <execution>
<id>Run Test Bukkit Server</id> <id>Run Test Bukkit Server</id>
<phase>package</phase> <phase>install</phase>
<goals> <goals>
<goal>exec</goal> <goal>exec</goal>
</goals> </goals>
@ -53,41 +65,73 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7.1</version>
<configuration>
<artifactSet>
<includes>
<include>org.mcstats.bukkit:metrics</include>
</includes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <artifactId>bukkit</artifactId>
<version>1.5.2-R1.0</version> <version>1.7.2-R0.2-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.5.2-R1.0</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.milkbowl.vault</groupId> <groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId> <artifactId>Vault</artifactId>
<version>1.2.26-SNAPSHOT</version> <version>1.2.27-SNAPSHOT</version>
<type>jar</type> <type>jar</type>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mcstats.bukkit</groupId>
<artifactId>metrics</artifactId>
<version>R8-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
<repository> <repository>
<id>bukkit-repo</id> <id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url> <url>http://repo.bukkit.org/content/groups/public</url>
</repository> </repository>
<repository> <repository>
<id>vault-repo</id> <id>vault-repo</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything</url> <url>http://ci.herocraftonline.com/plugin/repository/everything</url>
</repository> </repository>
<repository>
<id>Plugin Metrics</id>
<url>http://repo.mcstats.org/content/repositories/public</url>
</repository>
</repositories> </repositories>
</project> </project>

View File

@ -1,8 +1,11 @@
maxGateBlocks: 50 maxGateBlocks: 50
playerGateBlockUpdateRadius: 64 playerGateBlockUpdateRadius: 64
highlightDuration: 5
saveOnChanges: true saveOnChanges: true
checkForBrokenGateFrames: true checkForBrokenGateFrames: true
gateTeleportMessage: "Thank you for traveling with Craft Inc. Gates." gateTeleportMessage: "Thank you for traveling with Craft Inc. Gates."
showTeleportMessage: true showTeleportMessage: true
gateTeleportNoPermissionMessage: "You are not allowed to use this gate!" gateTeleportNoPermissionMessage: "You are not allowed to use this gate!"
showTeleportNoPermissionMessage: true showTeleportNoPermissionMessage: true
gateTeleportVehicleNotAllowedMessage: "You must not use that gate while riding!"
gateMaterial: "nether portal"

View File

@ -16,6 +16,7 @@
*/ */
package de.craftinc.gates; package de.craftinc.gates;
import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.FloodUtil; import de.craftinc.gates.util.FloodUtil;
import de.craftinc.gates.persistence.LocationUtil; import de.craftinc.gates.persistence.LocationUtil;
import org.bukkit.Location; import org.bukkit.Location;
@ -37,6 +38,8 @@ public class Gate implements ConfigurationSerializable
protected boolean isHidden = false; protected boolean isHidden = false;
protected boolean isOpen = false; protected boolean isOpen = false;
protected boolean allowsVehicles = true;
protected String id; protected String id;
/** /**
@ -57,7 +60,7 @@ public class Gate implements ConfigurationSerializable
/** /**
* *
* @return This method might return a 'null' value. * @return This method might return a 'null' data.
*/ */
public Location getLocation() public Location getLocation()
{ {
@ -100,7 +103,7 @@ public class Gate implements ConfigurationSerializable
/** /**
* *
* @param exit Supplying 'null' is permitted. * @param exit Supplying 'null' is permitted.
* @throws Exception An exception will be thrown if 'null' value is supplied and this gate is open. Note that the * @throws Exception An exception will be thrown if 'null' data is supplied and this gate is open. Note that the
* supplied 'exit' will be set even if an exception is thrown. Note that this gate will be closed if an * supplied 'exit' will be set even if an exception is thrown. Note that this gate will be closed if an
* exception is thrown. * exception is thrown.
*/ */
@ -166,6 +169,18 @@ public class Gate implements ConfigurationSerializable
} }
public void setAllowsVehicles(boolean allowsVehicles)
{
this.allowsVehicles = allowsVehicles;
}
public boolean getAllowsVehicles()
{
return this.allowsVehicles;
}
/** /**
* *
* @return Will never return 'null' but might return an empty Set. * @return Will never return 'null' but might return an empty Set.
@ -235,7 +250,7 @@ public class Gate implements ConfigurationSerializable
throw new Exception("Gate got closed. The frame is missing or broken. (no gate blocks)"); throw new Exception("Gate got closed. The frame is missing or broken. (no gate blocks)");
} }
if (!isHidden() && Plugin.getPlugin().getConfig().getBoolean(Plugin.confCheckForBrokenGateFramesKey)) { if (!isHidden() && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey)) {
for (Block b : gateFrameBlocks) { for (Block b : gateFrameBlocks) {
@ -264,6 +279,7 @@ public class Gate implements ConfigurationSerializable
static protected String locationPitchKey = "locationPitch"; static protected String locationPitchKey = "locationPitch";
static protected String exitYawKey = "exitYaw"; static protected String exitYawKey = "exitYaw";
static protected String exitPitchKey = "exitPitch"; static protected String exitPitchKey = "exitPitch";
static protected String allowsVehiclesKey = "allowsVehiclesKey";
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -272,10 +288,6 @@ public class Gate implements ConfigurationSerializable
try { try {
id = map.get(idKey).toString().toLowerCase(); id = map.get(idKey).toString().toLowerCase();
if (id == null) {
throw new Exception("gates need to have an id");
}
isHidden = (Boolean)map.get(isHiddenKey); isHidden = (Boolean)map.get(isHiddenKey);
isOpen = (Boolean)map.get(isOpenKey); isOpen = (Boolean)map.get(isOpenKey);
@ -292,6 +304,10 @@ public class Gate implements ConfigurationSerializable
location.setYaw(((Number)map.get(locationYawKey)).floatValue()); location.setYaw(((Number)map.get(locationYawKey)).floatValue());
} }
if (map.containsKey(allowsVehiclesKey)) {
allowsVehicles = (Boolean)map.get(allowsVehiclesKey);
}
gateBlockLocations = new HashSet<Location>(); gateBlockLocations = new HashSet<Location>();
List<Map<String, Object>> serializedGateBlocks = (List<Map<String, Object>>)map.get(gateBlocksKey); List<Map<String, Object>> serializedGateBlocks = (List<Map<String, Object>>)map.get(gateBlocksKey);
@ -326,6 +342,7 @@ public class Gate implements ConfigurationSerializable
retVal.put(exitKey, LocationUtil.serializeLocation(exit)); retVal.put(exitKey, LocationUtil.serializeLocation(exit));
retVal.put(isHiddenKey, isHidden); retVal.put(isHiddenKey, isHidden);
retVal.put(isOpenKey, isOpen); retVal.put(isOpenKey, isOpen);
retVal.put(allowsVehiclesKey, allowsVehicles);
if (exit != null) { if (exit != null) {
retVal.put(exitPitchKey, exit.getPitch()); retVal.put(exitPitchKey, exit.getPitch());

View File

@ -0,0 +1,31 @@
/* Craft Inc. Gates
Copyright (C) 2011-2014 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates;
import java.util.Map;
public interface GateChangeListener
{
public static final String newGate = "GateChangeListener-newGate"; // value will be null
public static final String removedGate = "GateChangeListener-removedGate"; // value will be null
public static final String changedID = "GateChangeListener-changedID"; // value will be the old ID
public static final String changedLocation = "GateChangeListener-changedLocation"; // value will the old location
public static final String changedExit = "GateChangeListener-changedExit"; // value will be the old exit
public void gateChangedHandler(final Gate g, final Map<String, Object>changeSet);
}

View File

@ -24,6 +24,7 @@ import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import de.craftinc.gates.persistence.MigrationUtil; import de.craftinc.gates.persistence.MigrationUtil;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -40,7 +41,7 @@ public class GatesManager
protected FileConfiguration gatesConfig; protected FileConfiguration gatesConfig;
protected static final String gatesPath = "gates"; // path to gates inside the yaml file protected static final String gatesPath = "gates"; // path to gates inside the yaml file
protected static final String storageVersionPath = "version"; protected static final String storageVersionPath = "version";
protected static final int storageVersion = 1; protected static final int storageVersion = 2;
protected int chunkRadius; protected int chunkRadius;
@ -53,6 +54,20 @@ public class GatesManager
protected boolean storageFileIsInvalid = false; protected boolean storageFileIsInvalid = false;
protected Set<GateChangeListener> changeListeners = new HashSet<GateChangeListener>();
public void addGateChangeListener(GateChangeListener listener)
{
this.changeListeners.add(listener);
}
public void removeGateChangeListener(GateChangeListener listener)
{
this.changeListeners.remove(listener);
}
public Gate getGateWithId(final String id) public Gate getGateWithId(final String id)
{ {
@ -67,6 +82,35 @@ public class GatesManager
} }
/**
* Returns the closest gate.
* @param location The location at which to look for a gate.
* @return Might return null if there are no nearby gates.
*/
public Gate getNearestGate(final Location location)
{
Set<Gate> nearbyGates = getNearbyGates(location.getChunk());
if (nearbyGates == null) {
return null;
}
double minDist = Double.MAX_VALUE;
Gate nearestGate = null;
for (Gate g : nearbyGates) {
double dist = location.distance(g.getLocation());
if (dist < minDist) {
minDist = dist;
nearestGate = g;
}
}
return nearestGate;
}
public Gate getGateAtLocation(final Location location) public Gate getGateAtLocation(final Location location)
{ {
SimpleLocation simpleLocation = new SimpleLocation(location); SimpleLocation simpleLocation = new SimpleLocation(location);
@ -193,7 +237,7 @@ public class GatesManager
protected int getChunkRadius() protected int getChunkRadius()
{ {
if (this.chunkRadius == 0) { if (this.chunkRadius == 0) {
this.chunkRadius = Plugin.getPlugin().getConfig().getInt(Plugin.confPlayerGateBlockUpdateRadiusKey); this.chunkRadius = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confPlayerGateBlockUpdateRadiusKey);
this.chunkRadius = this.chunkRadius >> 4; this.chunkRadius = this.chunkRadius >> 4;
} }
@ -459,6 +503,13 @@ public class GatesManager
{ {
this.removeGateById(oldId); this.removeGateById(oldId);
this.addGateWithId(g); this.addGateWithId(g);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedID, oldId);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
} }
@ -475,6 +526,26 @@ public class GatesManager
this.removeGateByFrameLocation(oldGateFrameBlocks); this.removeGateByFrameLocation(oldGateFrameBlocks);
this.addGateByFrameLocations(g); this.addGateByFrameLocations(g);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedLocation, oldLocation);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
public void handleGateExitChange(final Gate g, final Location oldExit)
{
// nothing to do
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedExit, oldExit);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
} }
@ -486,6 +557,14 @@ public class GatesManager
this.addGateByLocations(g); this.addGateByLocations(g);
this.addGateWithId(g); this.addGateWithId(g);
this.addGateByFrameLocations(g); this.addGateByFrameLocations(g);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.newGate, null);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
} }
@ -497,6 +576,13 @@ public class GatesManager
this.removeGateFromChunk(g, g.getLocation()); this.removeGateFromChunk(g, g.getLocation());
this.removeGateByLocation(g.getGateBlockLocations()); this.removeGateByLocation(g.getGateBlockLocations());
this.removeGateByFrameLocation(g.getGateFrameBlocks()); this.removeGateByFrameLocation(g.getGateFrameBlocks());
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.removedGate, null);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
} }

View File

@ -16,12 +16,14 @@
*/ */
package de.craftinc.gates; package de.craftinc.gates;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import de.craftinc.gates.listeners.*; import de.craftinc.gates.listeners.*;
import de.craftinc.gates.util.ConfigurationUtil;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -33,6 +35,7 @@ import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import de.craftinc.gates.commands.*; import de.craftinc.gates.commands.*;
import org.mcstats.Metrics;
public class Plugin extends JavaPlugin public class Plugin extends JavaPlugin
@ -41,15 +44,6 @@ public class Plugin extends JavaPlugin
public static final String permissionManage = "craftincgates.manage"; public static final String permissionManage = "craftincgates.manage";
public static final String permissionUse = "craftincgates.use"; public static final String permissionUse = "craftincgates.use";
public static final String confMaxGateBlocksKey = "maxGateBlocks";
public static final String confPlayerGateBlockUpdateRadiusKey = "playerGateBlockUpdateRadius";
public static final String confCheckForBrokenGateFramesKey = "checkForBrokenGateFrames";
public static final String confGateTeleportMessageKey = "gateTeleportMessage";
public static final String confShowTeleportMessageKey = "showTeleportMessage";
public static final String confGateTeleportNoPermissionMessageKey = "gateTeleportNoPermissionMessage";
public static final String confShowTeleportNoPermissionMessageKey = "showTeleportNoPermissionMessage";
public static final String confSaveOnChangesKey = "saveOnChanges";
private static Plugin instance; private static Plugin instance;
private static Permission permission; private static Permission permission;
@ -123,6 +117,15 @@ public class Plugin extends JavaPlugin
@Override @Override
public void onEnable() public void onEnable()
{ {
// Setup Metrics
try {
Metrics metrics = new Metrics(this);
metrics.start();
}
catch (IOException e) {
log("Failed to start metrics!");
}
// Setup configuration // Setup configuration
this.saveDefaultConfig(); this.saveDefaultConfig();
@ -142,6 +145,10 @@ public class Plugin extends JavaPlugin
commands.add(new CommandInfo()); commands.add(new CommandInfo());
commands.add(new CommandHide()); commands.add(new CommandHide());
commands.add(new CommandUnhide()); commands.add(new CommandUnhide());
commands.add(new CommandExitOpen());
commands.add(new CommandNearby());
commands.add(new CommandAllowRiding());
commands.add(new CommandDenyRiding());
// Register events // Register events
@ -170,7 +177,7 @@ public class Plugin extends JavaPlugin
pm.registerEvents(this.worldChangeListener, this); pm.registerEvents(this.worldChangeListener, this);
pm.registerEvents(this.joinListener, this); pm.registerEvents(this.joinListener, this);
if (getConfig().getBoolean(confCheckForBrokenGateFramesKey)) { if (getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey)) {
pm.registerEvents(this.blockBreakListener, this); pm.registerEvents(this.blockBreakListener, this);
} }
} }

View File

@ -19,6 +19,7 @@ package de.craftinc.gates.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -69,7 +70,7 @@ public abstract class BaseCommand
this.perform(); this.perform();
if (this.shouldPersistToDisk && Plugin.getPlugin().getConfig().getBoolean(Plugin.confSaveOnChangesKey)) { if (this.shouldPersistToDisk && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confSaveOnChangesKey)) {
Plugin.getPlugin().getGatesManager().saveGatesToDisk(); Plugin.getPlugin().getGatesManager().saveGatesToDisk();
} }
} }

View File

@ -0,0 +1,48 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin;
import org.bukkit.ChatColor;
public class CommandAllowRiding extends BaseCommand
{
public CommandAllowRiding()
{
aliases.add("allowRiding");
aliases.add("ar");
requiredParameters.add("id");
helpDescription = "Allow players to travel while riding.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
protected void perform()
{
gate.setAllowsVehicles(true);
sendMessage(ChatColor.GREEN + "Traveling while riding is now enabled for this gate.");
}
}

View File

@ -0,0 +1,47 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin;
import org.bukkit.ChatColor;
public class CommandDenyRiding extends BaseCommand
{
public CommandDenyRiding()
{
aliases.add("denyRiding");
aliases.add("dr");
requiredParameters.add("id");
helpDescription = "Deny players to travel while riding.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
protected void perform()
{
gate.setAllowsVehicles(false);
sendMessage(ChatColor.GREEN + "Traveling while riding is now disabled for this gate.");
}
}

View File

@ -22,6 +22,7 @@ import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import org.bukkit.Location;
public class CommandExit extends BaseCommand public class CommandExit extends BaseCommand
@ -47,8 +48,10 @@ public class CommandExit extends BaseCommand
{ {
try try
{ {
Location oldExit = gate.getExit();
gate.setExit(player.getLocation()); gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand."); sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
Plugin.getPlugin().getGatesManager().handleGateExitChange(gate, oldExit);
} }
catch (Exception e) { catch (Exception e) {
GateBlockChangeSender.updateGateBlocks(gate); GateBlockChangeSender.updateGateBlocks(gate);

View File

@ -0,0 +1,83 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import java.util.logging.Level;
public class CommandExitOpen extends BaseCommand
{
public CommandExitOpen()
{
aliases.add("exitopen");
aliases.add("eo");
requiredParameters.add("id");
helpDescription = "Change exit of location and open that gate afterwards.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform()
{
try
{
Location oldExit = gate.getExit();
gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
Plugin.getPlugin().getGatesManager().handleGateExitChange(gate, oldExit);
try {
boolean needsGateManagerUpdate = false;
if (gate.getGateBlockLocations().isEmpty()) {
needsGateManagerUpdate = true;
}
gate.setOpen(true);
GateBlockChangeSender.updateGateBlocks(gate);
if (needsGateManagerUpdate) {
Plugin.getPlugin().getGatesManager().handleGateLocationChange(gate, null, null, null);
}
sendMessage(ChatColor.GREEN + "The gate was opened.");
}
catch (Exception e) {
sendMessage(ChatColor.RED + e.getMessage());
}
}
catch (Exception e) {
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.RED + "Setting the exit for the gate failed! This gate is now closed! (See server log for more information.)");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -44,6 +44,8 @@ public class CommandHelp extends BaseCommand
allUsageStrings.add( new CommandInfo().getUsageTemplate(true, true) ); allUsageStrings.add( new CommandInfo().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandHide().getUsageTemplate(true, true) ); allUsageStrings.add( new CommandHide().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandUnhide().getUsageTemplate(true, true) ); allUsageStrings.add( new CommandUnhide().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandExitOpen().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandNearby().getUsageTemplate(true, true) );
Collections.sort(allUsageStrings); Collections.sort(allUsageStrings);

View File

@ -17,10 +17,12 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
import org.bukkit.entity.Player;
public class CommandInfo extends BaseCommand public class CommandInfo extends BaseCommand
@ -30,21 +32,50 @@ public class CommandInfo extends BaseCommand
aliases.add("info"); aliases.add("info");
aliases.add("i"); aliases.add("i");
requiredParameters.add("id"); optionalParameters.add("id");
helpDescription = "Print detailed information about a certain gate."; helpDescription = "Print detailed information about a certain or the closest gate.";
requiredPermission = Plugin.permissionInfo; requiredPermission = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false; shouldPersistToDisk = false;
senderMustBePlayer = false; senderMustBePlayer = false;
hasGateParam = false;
} }
public void perform() public void perform()
{ {
if (this.parameters.size() > 0) {
if (!this.setGateUsingParameter(this.parameters.get(0))) {
sendMessage(ChatColor.RED + "You either provided a invalid gate or do not have permission to " + this.helpDescription.toLowerCase());
return;
}
sendMessage(TextUtil.titleize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'")); sendMessage(TextUtil.titleize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'"));
}
else {
boolean senderIsPlayer = this.sender instanceof Player;
if (!senderIsPlayer) {
sendMessage(ChatColor.RED + "Only ingame players can perform this command without a supplied gate id!");
return;
}
Player p = (Player)this.sender;
this.gate = Plugin.getPlugin().getGatesManager().getNearestGate(p.getLocation());
if (!this.hasPermission() || this.gate == null) {
sendMessage(ChatColor.RED + "There is either no gate nearby or you do not have permission to " + this.helpDescription.toLowerCase());
return;
}
Plugin.log(this.gate.toString());
sendMessage(TextUtil.titleize("Information about closest gate: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'"));
}
String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is"; String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is";
@ -61,17 +92,26 @@ public class CommandInfo extends BaseCommand
sendMessage(openHiddenMessage); sendMessage(openHiddenMessage);
if (gate.getLocation() != null) if (gate.getLocation() != null)
sendMessage(ChatColor.DARK_AQUA + "from: " + ChatColor.AQUA + "( " + (int)gate.getLocation().getX() + sendMessage(ChatColor.DARK_AQUA + "location: " + ChatColor.AQUA + "( " + (int)gate.getLocation().getX() +
" | " + (int)gate.getLocation().getY() + " | " + (int)gate.getLocation().getZ() + " ) in " + " | " + (int)gate.getLocation().getY() + " | " + (int)gate.getLocation().getZ() + " ) in " +
gate.getLocation().getWorld().getName()); gate.getLocation().getWorld().getName());
else else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no location"); sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no location");
if (gate.getExit() != null) if (gate.getExit() != null)
sendMessage(ChatColor.DARK_AQUA + "to: " + ChatColor.AQUA + "( " + (int)gate.getExit().getX() + " | " sendMessage(ChatColor.DARK_AQUA + "exit: " + ChatColor.AQUA + "( " + (int)gate.getExit().getX() + " | "
+ (int)gate.getExit().getY() + " | " + (int)gate.getExit().getZ() + " ) in " + + (int)gate.getExit().getY() + " | " + (int)gate.getExit().getZ() + " ) in " +
gate.getExit().getWorld().getName()); gate.getExit().getWorld().getName());
else else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit"); sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit");
if (gate.getAllowsVehicles())
sendMessage(ChatColor.DARK_AQUA + "You can ride through this gate.");
if (this.sender instanceof Player) {
GateBlockChangeSender.temporaryHighlightGateFrame((Player)this.sender, this.gate);
}
} }
} }

View File

@ -29,7 +29,6 @@ import org.bukkit.block.Block;
public class CommandLocation extends BaseLocationCommand public class CommandLocation extends BaseLocationCommand
{ {
public CommandLocation() public CommandLocation()
{ {
aliases.add("location"); aliases.add("location");

View File

@ -0,0 +1,53 @@
package de.craftinc.gates.commands;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.TextUtil;
import java.util.ArrayList;
import java.util.Set;
public class CommandNearby extends BaseLocationCommand
{
public CommandNearby()
{
aliases.add("nearby");
aliases.add("nb");
helpDescription = "Highlight nearby gates";
requiredPermission = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = false;
senderMustBePlayer = true;
hasGateParam = false;
}
public void perform()
{
GatesManager manager = Plugin.getPlugin().getGatesManager();
Set<Gate> nearbyGates = manager.getNearbyGates(player.getLocation().getChunk());
if (nearbyGates == null) {
player.sendMessage("There are no gates near you!");
}
else {
GateBlockChangeSender.temporaryHighlightGatesFrames(player, nearbyGates);
ArrayList<String> gateNames = new ArrayList<String>();
for (Gate g : nearbyGates) {
gateNames.add(g.getId());
}
player.sendMessage("Nearby gates: " + TextUtil.implode(gateNames, ", "));
}
}
}

View File

@ -19,10 +19,14 @@ package de.craftinc.gates.listeners;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.GateBlockChangeSender; import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.VehicleCloner;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -31,6 +35,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
import de.craftinc.gates.Gate; import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager; import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
public class PlayerMoveListener implements Listener public class PlayerMoveListener implements Listener
@ -48,43 +53,30 @@ public class PlayerMoveListener implements Listener
GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo()); GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo());
} }
GatesManager gateManager = Plugin.getPlugin().getGatesManager(); final GatesManager gateManager = Plugin.getPlugin().getGatesManager();
Gate gateAtLocation = gateManager.getGateAtLocation(event.getTo()); final Gate gateAtLocation = gateManager.getGateAtLocation(event.getTo());
if (gateAtLocation == null) { if ((gateAtLocation == null) || !gateAtLocation.isOpen()) {
// Location headTo = new Location(event.getTo().getWorld(),
// event.getTo().getX(),
// event.getTo().getY()+1.0,
// event.getTo().getZ());
//
// gateAtLocation = gateManager.getGateAtLocation(headTo);
// if (gateAtLocation == null) {
return;
// }
}
if (!gateAtLocation.isOpen()) {
return; return;
} }
// Check for permission // Check for permission
if (!hasPermission(event.getPlayer(), gateAtLocation) if (!hasPermission(event.getPlayer(), gateAtLocation)
&& Plugin.getPlugin().getConfig().getBoolean(Plugin.confShowTeleportNoPermissionMessageKey)) { && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
String playerName = event.getPlayer().getName(); final String playerName = event.getPlayer().getName();
if (playerName == null) { if (playerName == null) {
return; return;
} }
// get the current time // get the current time
Long now = Calendar.getInstance().getTimeInMillis(); final Long now = Calendar.getInstance().getTimeInMillis();
// do not display messages more often than once per second // do not display messages more often than once per second
if (!this.lastNoPermissionMessages.containsKey(playerName) || this.lastNoPermissionMessages.get(playerName) < now - 10000L) { if (!this.lastNoPermissionMessages.containsKey(playerName) || this.lastNoPermissionMessages.get(playerName) < now - 10000L) {
String noPermissionString = Plugin.getPlugin().getConfig().getString(Plugin.confGateTeleportNoPermissionMessageKey); final String noPermissionString = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportNoPermissionMessageKey);
event.getPlayer().sendMessage(ChatColor.RED + noPermissionString); event.getPlayer().sendMessage(ChatColor.RED + noPermissionString);
this.lastNoPermissionMessages.put(playerName, now); this.lastNoPermissionMessages.put(playerName, now);
} }
@ -97,38 +89,79 @@ public class PlayerMoveListener implements Listener
/** /**
* Teleports a player. * Teleports a player.
* @param p The player to teleport. * @param player The player to teleport.
* @param g The gate to which exit the player will be teleported. * @param gate The gate to which exit the player will be teleported.
*/ */
private void teleportPlayer(Player p, Gate g) private void teleportPlayer(final Player player, final Gate gate)
{ {
Float newYaw = g.getExit().getYaw() - g.getLocation().getYaw() + p.getLocation().getYaw(); // Destination
final Float newYaw = gate.getExit().getYaw() - gate.getLocation().getYaw() + player.getLocation().getYaw();
Location destLocation = new Location( g.getExit().getWorld(), final Location destLocation = new Location( gate.getExit().getWorld(),
g.getExit().getX(), gate.getExit().getX(),
g.getExit().getY(), gate.getExit().getY(),
g.getExit().getZ(), gate.getExit().getZ(),
newYaw, newYaw,
p.getLocation().getPitch() player.getLocation().getPitch()
); );
p.teleport(destLocation); // Riding
final Entity vehicle = player.getVehicle();
final boolean vehicleIsSuitable = (vehicle != null) && (vehicle instanceof Vehicle);
if (Plugin.getPlugin().getConfig().getBoolean(Plugin.confShowTeleportMessageKey)) { if (vehicle != null && (!vehicleIsSuitable) || !gate.getAllowsVehicles()) {
String teleporMessage = Plugin.getPlugin().getConfig().getString(Plugin.confGateTeleportMessageKey);
p.sendMessage(ChatColor.DARK_AQUA + teleporMessage); if (!gate.getAllowsVehicles() && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
final String notAllowedMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportVehicleNotAllowedMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + notAllowedMessage);
}
return;
}
// (eject player)
if (vehicleIsSuitable) {
vehicle.eject();
vehicle.remove();
}
// Teleport
player.teleport(destLocation);
// Riding (mount player)
if (vehicleIsSuitable) {
final Plugin plugin = Plugin.getPlugin();
final BukkitScheduler scheduler = plugin.getServer().getScheduler();
destLocation.getChunk().load(); // load the destination chunk, no new entity will be created otherwise
scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
public void run()
{
// FIXME: the code below should be executed after the chunk got loaded and not after a fixed time!
// create a new entity at the destination location
final Vehicle newVehicle = VehicleCloner.clone((Vehicle)vehicle, destLocation);
newVehicle.setPassenger(player);
}
}, 2);
}
// Message
if (Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportMessageKey)) {
final String teleportMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + teleportMessage);
} }
} }
protected boolean hasPermission(Player player, Gate gate) protected boolean hasPermission(final Player player, final Gate gate)
{ {
if (Plugin.getPermission() == null) { // fallback: use the standard bukkit permission system if (Plugin.getPermission() == null) { // fallback: use the standard bukkit permission system
return player.hasPermission(Plugin.permissionUse); return player.hasPermission(Plugin.permissionUse);
} }
else { else {
boolean permAtLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse); final boolean permAtLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse);
boolean permAtExit = Plugin.getPermission().has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse); final boolean permAtExit = Plugin.getPermission().has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse);
return permAtLocation && permAtExit; return permAtLocation && permAtExit;
} }

View File

@ -31,8 +31,26 @@ public class MigrationUtil
{ {
public static boolean performMigration(int storageVersion, int currentVersion, List<Gate> gates) public static boolean performMigration(int storageVersion, int currentVersion, List<Gate> gates)
{ {
if (currentVersion == 1 && storageVersion == 0) { if (storageVersion == 0 && currentVersion >= 2) {
removePortalBlocks(gates);
updateAllowVehicles(gates);
return true;
}
else if (storageVersion == 1 && currentVersion >= 2) {
updateAllowVehicles(gates);
return true;
}
else {
Plugin.log(Level.SEVERE, "Supplied storage version is currently not supported! Make sure you have the latest version of Craft Inc. Gates installed. Plugin will be disabled!");
return false;
}
}
protected static void removePortalBlocks(List<Gate> gates)
{
for (Gate g : gates) { for (Gate g : gates) {
for (Location l : g.getGateBlockLocations()) { for (Location l : g.getGateBlockLocations()) {
@ -43,12 +61,14 @@ public class MigrationUtil
} }
} }
} }
}
return true;
} protected static void updateAllowVehicles(List<Gate> gates)
else { {
Plugin.log(Level.SEVERE, "Supplied storage version is currently not supported! Make sure you have the latest version of Craft Inc. Gates installed. Plugin will be disabled!"); for (Gate g : gates) {
return false;
g.setAllowsVehicles(true);
} }
} }
} }

View File

@ -0,0 +1,127 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util;
import de.craftinc.gates.Plugin;
import org.bukkit.Material;
import java.util.logging.Level;
public class ConfigurationUtil
{
public static final String confMaxGateBlocksKey = "maxGateBlocks";
public static final String confPlayerGateBlockUpdateRadiusKey = "playerGateBlockUpdateRadius";
public static final String confCheckForBrokenGateFramesKey = "checkForBrokenGateFrames";
public static final String confGateTeleportMessageKey = "gateTeleportMessage";
public static final String confGateTeleportVehicleNotAllowedMessageKey = "gateTeleportVehicleNotAllowedMessage";
public static final String confShowTeleportMessageKey = "showTeleportMessage";
public static final String confGateTeleportNoPermissionMessageKey = "gateTeleportNoPermissionMessage";
public static final String confShowTeleportNoPermissionMessageKey = "showTeleportNoPermissionMessage";
public static final String confSaveOnChangesKey = "saveOnChanges";
public static final String confHighlightDurationKey = "highlightDuration";
public static final String confGateMaterialKey = "gateMaterial";
public static GateMaterial getPortalMaterial()
{
String materialString = Plugin.getPlugin().getConfig().getString(confGateMaterialKey);
GateMaterial material = new GateMaterial();
if (materialString.equals("sapling")) {
material.material = Material.SAPLING;
}
else if (materialString.equals("water")) {
material.material = Material.STATIONARY_WATER;
}
else if (materialString.equals("lava")) {
material.material = Material.STATIONARY_LAVA;
}
else if (materialString.equals("cobweb")) {
material.material = Material.WEB;
}
else if (materialString.equals("grass")) {
material.material = Material.LONG_GRASS;
material.data = 1;
}
else if (materialString.equals("dead bush")) {
material.material = Material.DEAD_BUSH;
}
else if (materialString.equals("dandelion")) {
material.material = Material.YELLOW_FLOWER;
}
else if (materialString.equals("poppy")) {
material.material = Material.RED_ROSE;
}
else if (materialString.equals("brown mushroom")) {
material.material = Material.BROWN_MUSHROOM;
}
else if (materialString.equals("red mushroom")) {
material.material = Material.RED_MUSHROOM;
}
else if (materialString.equals("torch")) {
material.material = Material.TORCH;
}
else if (materialString.equals("redstone torch (off)")) {
material.material = Material.REDSTONE_TORCH_OFF;
}
else if (materialString.equals("redstone torch (on)")) {
material.material = Material.REDSTONE_TORCH_ON;
}
else if (materialString.equals("fence")) {
material.material = Material.FENCE;
}
else if (materialString.equals("nether portal")) {
material.material = Material.PORTAL;
}
else if (materialString.equals("iron bars")) {
material.material = Material.IRON_FENCE;
}
else if (materialString.equals("glass pane")) {
material.material = Material.THIN_GLASS;
}
else if (materialString.equals("fence gate")) {
material.material = Material.FENCE_GATE;
}
else if (materialString.equals("nether brick fence")) {
material.material = Material.NETHER_FENCE;
}
else if (materialString.equals("nether wart")) {
material.material = Material.NETHER_WARTS;
}
else if (materialString.equals("end portal")) {
material.material = Material.ENDER_PORTAL;
}
else if (materialString.equals("cobblestone wall")) {
material.material = Material.COBBLE_WALL;
}
else { // fallback!
material.material = Material.PORTAL;
Plugin.log(Level.WARNING, "Gate material invalid! Please check and correct your configuration file!");
}
return material;
}
}
class GateMaterial
{
public Material material = Material.PORTAL;
public byte data = 0;
}

View File

@ -148,7 +148,7 @@ public class FloodUtil
throw new IllegalArgumentException("'block' must not be 'null'"); throw new IllegalArgumentException("'block' must not be 'null'");
} }
int frameBlockSearchLimit = Plugin.getPlugin().getConfig().getInt(Plugin.confMaxGateBlocksKey); int frameBlockSearchLimit = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confMaxGateBlocksKey);
Set<Block> blocks1 = getAirFloodBlocks(block, new HashSet<Block>(), exp1, frameBlockSearchLimit); Set<Block> blocks1 = getAirFloodBlocks(block, new HashSet<Block>(), exp1, frameBlockSearchLimit);
Set<Block> blocks2 = getAirFloodBlocks(block, new HashSet<Block>(), exp2, frameBlockSearchLimit); Set<Block> blocks2 = getAirFloodBlocks(block, new HashSet<Block>(), exp2, frameBlockSearchLimit);

View File

@ -19,17 +19,108 @@ package de.craftinc.gates.util;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.Gate; import de.craftinc.gates.Gate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import static de.craftinc.gates.util.ConfigurationUtil.*;
public class GateBlockChangeSender public class GateBlockChangeSender
{ {
/**
* Replaces gate frame blocks with glowstone for a short period of time.
* Uses the data stored in 'highlightDuration' inside the config file
* for determining when to de-highlight the frames.
* @param player The player for whom the frame should be highlighted.
* Must not be null!
*/
public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates)
{
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
if (gates == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0);
}
}
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGatesFrames(player, gates);
}
}, highlightDuration);
}
public static void temporaryHighlightGateFrame(final Player player, final Gate gate)
{
if (gate == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0);
}
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGateFrame(player, gate);
}
}, highlightDuration);
}
protected static void dehighlightGatesFrames(final Player player, final Set<Gate> gates)
{
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte)0);
}
}
}
protected static void dehighlightGateFrame(final Player player, final Gate gate)
{
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte)0);
}
}
/** /**
* Sends gate blocks to player at a given location. Will send the updates either immediately or * Sends gate blocks to player at a given location. Will send the updates either immediately or
* immediately and after a short delay. * immediately and after a short delay.
@ -49,6 +140,7 @@ public class GateBlockChangeSender
} }
Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk());
GateMaterial gateMaterial = getPortalMaterial();
if (gatesNearby == null) { if (gatesNearby == null) {
return; // no gates nearby return; // no gates nearby
@ -63,7 +155,7 @@ public class GateBlockChangeSender
for (Location l : g.getGateBlockLocations()) { for (Location l : g.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) { if (l.getBlock().getType() == Material.AIR) {
player.sendBlockChange(l, Material.PORTAL, (byte)0); player.sendBlockChange(l, gateMaterial.material, gateMaterial.data);
} }
} }
} }
@ -126,7 +218,7 @@ public class GateBlockChangeSender
ArrayList<Player> playersNearby = new ArrayList<Player>(); ArrayList<Player> playersNearby = new ArrayList<Player>();
int searchRadius = Plugin.getPlugin().getConfig().getInt(Plugin.confPlayerGateBlockUpdateRadiusKey); int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey);
for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) { for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) {
@ -135,10 +227,13 @@ public class GateBlockChangeSender
} }
} }
GateMaterial gateMaterial = getPortalMaterial();
Material material; Material material;
byte data = 0;
if (gate.isOpen() && !gate.isHidden() && !remove) { if (gate.isOpen() && !gate.isHidden() && !remove) {
material = Material.PORTAL; material = gateMaterial.material;
data = gateMaterial.data;
} }
else { else {
material = Material.AIR; material = Material.AIR;
@ -149,7 +244,7 @@ public class GateBlockChangeSender
for (Location l : gate.getGateBlockLocations()) { for (Location l : gate.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) { // on server-side a gate is always made out of AIR if (l.getBlock().getType() == Material.AIR) { // on server-side a gate is always made out of AIR
p.sendBlockChange(l, material, (byte)0); p.sendBlockChange(l, material, data);
} }
} }
} }

View File

@ -24,14 +24,21 @@ public class TextUtil
{ {
public static String titleize(String str) public static String titleize(String str)
{ {
String line = ChatColor.GOLD + repeat("_", 60);
String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ]."; String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ].";
if (center.length() >= 60) {
return ChatColor.GOLD + center;
}
else {
String line = ChatColor.GOLD + repeat("_", 60);
int pivot = line.length() / 2; int pivot = line.length() / 2;
int eatLeft = center.length() / 2; int eatLeft = center.length() / 2;
int eatRight = center.length() - eatLeft; int eatRight = center.length() - eatLeft;
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight); return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight);
} }
}
public static String repeat(String s, int times) public static String repeat(String s, int times)

View File

@ -0,0 +1,113 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util;
import org.bukkit.Location;
import org.bukkit.entity.*;
public class VehicleCloner
{
public static Vehicle clone(Vehicle parent, Location cloneLocation)
{
Vehicle clone = cloneLocation.getWorld().spawn(cloneLocation, parent.getClass());
clone.setFallDistance(parent.getFallDistance());
clone.setFireTicks(parent.getFireTicks());
clone.setVelocity(parent.getVelocity());
clone.setTicksLived(parent.getTicksLived());
clone.setLastDamageCause(parent.getLastDamageCause());
if (clone instanceof Boat) {
Boat boat = (Boat)clone;
Boat parentBoat = (Boat)parent;
boat.setMaxSpeed(parentBoat.getMaxSpeed());
boat.setOccupiedDeceleration(parentBoat.getOccupiedDeceleration());
boat.setUnoccupiedDeceleration(parentBoat.getUnoccupiedDeceleration());
boat.setWorkOnLand(parentBoat.getWorkOnLand());
boat.setVelocity(parentBoat.getVelocity());
}
else if (clone instanceof Animals) {
Animals animal = (Animals)clone;
Animals parentAnimal = (Animals)parent;
animal.setMaxHealth(parentAnimal.getMaxHealth());
animal.setHealth(parentAnimal.getMaxHealth());
animal.setRemainingAir(parentAnimal.getRemainingAir());
animal.setMaximumAir(parentAnimal.getMaximumAir());
animal.setMaximumNoDamageTicks(parentAnimal.getMaximumNoDamageTicks());
animal.setLastDamage(parentAnimal.getLastDamage());
animal.setNoDamageTicks(parentAnimal.getNoDamageTicks());
animal.addPotionEffects(parentAnimal.getActivePotionEffects());
animal.setRemoveWhenFarAway(parentAnimal.getRemoveWhenFarAway());
animal.setCanPickupItems(parentAnimal.getCanPickupItems());
animal.setCustomName(parentAnimal.getCustomName());
animal.setCustomNameVisible(parentAnimal.isCustomNameVisible());
animal.setTarget(parentAnimal.getTarget());
animal.setAge(parentAnimal.getAge());
animal.setAgeLock(parentAnimal.getAgeLock());
if (clone instanceof Horse) {
Horse horse = (Horse)clone;
Horse parentHorse = (Horse)parent;
horse.getInventory().setArmor(parentHorse.getInventory().getArmor());
horse.getInventory().setSaddle(parentHorse.getInventory().getSaddle());
horse.setCarryingChest(parentHorse.isCarryingChest());
horse.getInventory().setContents(parentHorse.getInventory().getContents());
horse.setTamed(parentHorse.isTamed());
horse.setOwner(parentHorse.getOwner());
horse.setJumpStrength(parentHorse.getJumpStrength());
horse.setMaxDomestication(parentHorse.getMaxDomestication());
horse.setDomestication(parentHorse.getDomestication());
horse.setStyle(parentHorse.getStyle());
horse.setColor(parentHorse.getColor());
horse.setVariant(parentHorse.getVariant());
if (parentHorse.isAdult()) {
horse.setAdult();
}
else {
horse.setBaby();
}
horse.setBreed(parentHorse.canBreed());
}
else if (clone instanceof Pig) {
Pig pig = (Pig)clone;
Pig parentPig = (Pig)parent;
pig.setSaddle(parentPig.hasSaddle());
}
}
else if (clone instanceof Minecart) {
Minecart minecart = (Minecart)clone;
Minecart parentMinecart = (Minecart)parent;
minecart.setDerailedVelocityMod(parentMinecart.getDerailedVelocityMod());
minecart.setFlyingVelocityMod(parentMinecart.getFlyingVelocityMod());
minecart.setSlowWhenEmpty(parentMinecart.isSlowWhenEmpty());
minecart.setMaxSpeed(parentMinecart.getMaxSpeed());
minecart.setDamage(parentMinecart.getDamage());
minecart.setVelocity(parentMinecart.getVelocity());
}
return clone;
}
}