Merge branch 'clans/test-server' of http://184.154.0.242:7990/scm/min/mineplex into clans_custom_gear

Conflicts:
	Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/economy/GoldManager.java
This commit is contained in:
Ty Sayers 2015-06-22 16:24:31 -04:00
commit 1541dc329e
59 changed files with 4789 additions and 30 deletions

View File

@ -2,6 +2,9 @@
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" /> <option name="DEFAULT_COMPILER" value="Javac" />
<excludeFromCompile>
<directory url="file://$PROJECT_DIR$/Nautilus.Game.PvP" includeSubdirectories="true" />
</excludeFromCompile>
<resourceExtensions /> <resourceExtensions />
<wildcardResourcePatterns> <wildcardResourcePatterns>
<entry name="!?*.java" /> <entry name="!?*.java" />
@ -23,5 +26,4 @@
<component name="JavacSettings"> <component name="JavacSettings">
<option name="GENERATE_NO_WARNINGS" value="true" /> <option name="GENERATE_NO_WARNINGS" value="true" />
</component> </component>
</project> </project>

View File

@ -7,7 +7,7 @@
</list> </list>
</component> </component>
<component name="IdProvider" IDEtalkID="7E81636CD93857493DFE224533ECF492" /> <component name="IdProvider" IDEtalkID="7E81636CD93857493DFE224533ECF492" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -3,7 +3,7 @@
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" filepath="$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" group="Core" /> <module fileurl="file://$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" filepath="$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" group="Core" />
<module fileurl="file://$PROJECT_DIR$/JedisTest/JedisTest.iml" filepath="$PROJECT_DIR$/JedisTest/JedisTest.iml" /> <module fileurl="file://$PROJECT_DIR$/JedisTest/JedisTest.iml" filepath="$PROJECT_DIR$/JedisTest/JedisTest.iml" group="Legacy" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" filepath="$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" group="Bungee" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" filepath="$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" group="Bungee" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" group="Core" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" group="Core" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" filepath="$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" group="Core" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" filepath="$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" group="Core" />
@ -14,10 +14,10 @@
<module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.BungeeSigns/Mineplex.Minecraft.BungeeSigns.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.BungeeSigns/Mineplex.Minecraft.BungeeSigns.iml" group="Bungee" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.BungeeSigns/Mineplex.Minecraft.BungeeSigns.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.BungeeSigns/Mineplex.Minecraft.BungeeSigns.iml" group="Bungee" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.Game.ClassCombat/Mineplex.Minecraft.Game.ClassCombat.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.Game.ClassCombat/Mineplex.Minecraft.Game.ClassCombat.iml" group="Game" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.Game.ClassCombat/Mineplex.Minecraft.Game.ClassCombat.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.Game.ClassCombat/Mineplex.Minecraft.Game.ClassCombat.iml" group="Game" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.Game.Core/Mineplex.Minecraft.Game.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.Game.Core/Mineplex.Minecraft.Game.Core.iml" group="Game" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.Minecraft.Game.Core/Mineplex.Minecraft.Game.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Minecraft.Game.Core/Mineplex.Minecraft.Game.Core.iml" group="Game" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.PlayerCache/Mineplex.PlayerCache.iml" filepath="$PROJECT_DIR$/Mineplex.PlayerCache/Mineplex.PlayerCache.iml" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.PlayerCache/Mineplex.PlayerCache.iml" filepath="$PROJECT_DIR$/Mineplex.PlayerCache/Mineplex.PlayerCache.iml" group="Core" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.ServerData/Mineplex.ServerData.iml" filepath="$PROJECT_DIR$/Mineplex.ServerData/Mineplex.ServerData.iml" group="Core" /> <module fileurl="file://$PROJECT_DIR$/Mineplex.ServerData/Mineplex.ServerData.iml" filepath="$PROJECT_DIR$/Mineplex.ServerData/Mineplex.ServerData.iml" group="Core" />
<module fileurl="file://$PROJECT_DIR$/Mineplex.ServerMonitor/Mineplex.ServerMonitor.iml" filepath="$PROJECT_DIR$/Mineplex.ServerMonitor/Mineplex.ServerMonitor.iml" group="Core" />
<module fileurl="file://$PROJECT_DIR$/Nautilus.Game.Arcade/Nautilus.Game.Arcade.iml" filepath="$PROJECT_DIR$/Nautilus.Game.Arcade/Nautilus.Game.Arcade.iml" group="Game" /> <module fileurl="file://$PROJECT_DIR$/Nautilus.Game.Arcade/Nautilus.Game.Arcade.iml" filepath="$PROJECT_DIR$/Nautilus.Game.Arcade/Nautilus.Game.Arcade.iml" group="Game" />
<module fileurl="file://$PROJECT_DIR$/Nautilus.Game.PvP/Nautilus.Game.PvP.iml" filepath="$PROJECT_DIR$/Nautilus.Game.PvP/Nautilus.Game.PvP.iml" group="Legacy" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -0,0 +1,57 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Byte_Array} tag.
*/
public final class ByteArrayTag extends Tag {
private final byte[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteArrayTag(byte[] value) {
super();
this.value = value;
}
@Override
public byte[] getValue() {
return value;
}
@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (byte b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
return "TAG_Byte_Array(" + hex + ")";
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Byte} tag.
*/
public final class ByteTag extends Tag {
private final byte value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteTag(byte value) {
super();
this.value = value;
}
@Override
public Byte getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Byte(" + value + ")";
}
}

View File

@ -0,0 +1,420 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The {@code TAG_Compound} tag.
*/
public final class CompoundTag extends Tag {
private final Map<String, Tag> value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public CompoundTag(Map<String, Tag> value) {
super();
this.value = Collections.unmodifiableMap(value);
}
/**
* Returns whether this compound tag contains the given key.
*
* @param key the given key
* @return true if the tag contains the given key
*/
public boolean containsKey(String key) {
return value.containsKey(key);
}
@Override
public Map<String, Tag> getValue() {
return value;
}
/**
* Return a new compound tag with the given values.
*
* @param value the value
* @return the new compound tag
*/
public CompoundTag setValue(Map<String, Tag> value) {
return new CompoundTag(value);
}
/**
* Create a compound tag builder.
*
* @return the builder
*/
public CompoundTagBuilder createBuilder() {
return new CompoundTagBuilder(new HashMap<String, Tag>(value));
}
/**
* Get a byte array named with the given key.
*
* <p>If the key does not exist or its value is not a byte array tag,
* then an empty byte array will be returned.</p>
*
* @param key the key
* @return a byte array
*/
public byte[] getByteArray(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given key.
*
* <p>If the key does not exist or its value is not a byte tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a byte
*/
public byte getByte(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given key.
*
* <p>If the key does not exist or its value is not a double tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a double
*/
public double getDouble(String key) {
Tag tag = value.get(key);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a double
*/
public double asDouble(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given key.
*
* <p>If the key does not exist or its value is not a float tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a float
*/
public float getFloat(String key) {
Tag tag = value.get(key);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given key.
*
* <p>If the key does not exist or its value is not an int array tag,
* then an empty array will be returned.</p>
*
* @param key the key
* @return an int array
*/
public int[] getIntArray(String key) {
Tag tag = value.get(key);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given key.
*
* <p>If the key does not exist or its value is not an int tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return an int
*/
public int getInt(String key) {
Tag tag = value.get(key);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return an int
*/
public int asInt(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty list will be returned.</p>
*
* @param key the key
* @return a list of tags
*/
public List<Tag> getList(String key) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty tag list will be returned.</p>
*
* @param key the key
* @return a tag list instance
*/
public ListTag getListTag(String key) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given key.
*
* <p>If the key does not exist or its value is not a list tag,
* then an empty list will be returned. If the given key references
* a list but the list of of a different type, then an empty
* list will also be returned.</p>
*
* @param key the key
* @param listType the class of the contained type
* @return a list of tags
* @param <T> the type of list
*/
@SuppressWarnings("unchecked")
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
Tag tag = value.get(key);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given key.
*
* <p>If the key does not exist or its value is not a long tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a long
*/
public long getLong(String key) {
Tag tag = value.get(key);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given key, even if it's another
* type of number.
*
* <p>If the key does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a long
*/
public long asLong(String key) {
Tag tag = value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0L;
}
}
/**
* Get a short named with the given key.
*
* <p>If the key does not exist or its value is not a short tag,
* then {@code 0} will be returned.</p>
*
* @param key the key
* @return a short
*/
public short getShort(String key) {
Tag tag = value.get(key);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given key.
*
* <p>If the key does not exist or its value is not a string tag,
* then {@code ""} will be returned.</p>
*
* @param key the key
* @return a string
*/
public String getString(String key) {
Tag tag = value.get(key);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_Compound").append(": ").append(value.size()).append(" entries\r\n{\r\n");
for (Map.Entry<String, Tag> entry : value.entrySet()) {
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,204 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create compound tags.
*/
public class CompoundTagBuilder {
private final Map<String, Tag> entries;
/**
* Create a new instance.
*/
CompoundTagBuilder() {
this.entries = new HashMap<String, Tag>();
}
/**
* Create a new instance and use the given map (which will be modified).
*
* @param value the value
*/
CompoundTagBuilder(Map<String, Tag> value) {
checkNotNull(value);
this.entries = value;
}
/**
* Put the given key and tag into the compound tag.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder put(String key, Tag value) {
checkNotNull(key);
checkNotNull(value);
entries.put(key, value);
return this;
}
/**
* Put the given key and value into the compound tag as a
* {@code ByteArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByteArray(String key, byte[] value) {
return put(key, new ByteArrayTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code ByteTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByte(String key, byte value) {
return put(key, new ByteTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code DoubleTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putDouble(String key, double value) {
return put(key, new DoubleTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code FloatTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putFloat(String key, float value) {
return put(key, new FloatTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code IntArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putIntArray(String key, int[] value) {
return put(key, new IntArrayTag(value));
}
/**
* Put the given key and value into the compound tag as an {@code IntTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putInt(String key, int value) {
return put(key, new IntTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code LongTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putLong(String key, long value) {
return put(key, new LongTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code ShortTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putShort(String key, short value) {
return put(key, new ShortTag(value));
}
/**
* Put the given key and value into the compound tag as a
* {@code StringTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putString(String key, String value) {
return put(key, new StringTag(value));
}
/**
* Put all the entries from the given map into this map.
*
* @param value the map of tags
* @return this object
*/
public CompoundTagBuilder putAll(Map<String, ? extends Tag> value) {
checkNotNull(value);
for (Map.Entry<String, ? extends Tag> entry : value.entrySet()) {
put(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Build an unnamed compound tag with this builder's entries.
*
* @return the new compound tag
*/
public CompoundTag build() {
return new CompoundTag(new HashMap<String, Tag>(entries));
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static CompoundTagBuilder create() {
return new CompoundTagBuilder();
}
}

View File

@ -0,0 +1,50 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Double} tag.
*
*/
public final class DoubleTag extends Tag {
private final double value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public DoubleTag(double value) {
super();
this.value = value;
}
@Override
public Double getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Double(" + value + ")";
}
}

View File

@ -0,0 +1,37 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_End} tag.
*/
public final class EndTag extends Tag {
@Override
public Object getValue() {
return null;
}
@Override
public String toString() {
return "TAG_End";
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Float} tag.
*/
public final class FloatTag extends Tag {
private final float value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public FloatTag(float value) {
super();
this.value = value;
}
@Override
public Float getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Float(" + value + ")";
}
}

View File

@ -0,0 +1,60 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_Int_Array} tag.
*/
public final class IntArrayTag extends Tag {
private final int[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntArrayTag(int[] value) {
super();
checkNotNull(value);
this.value = value;
}
@Override
public int[] getValue() {
return value;
}
@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (int b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
return "TAG_Int_Array(" + hex + ")";
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Int} tag.
*/
public final class IntTag extends Tag {
private final int value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntTag(int value) {
super();
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Int(" + value + ")";
}
}

View File

@ -0,0 +1,431 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_List} tag.
*/
public final class ListTag extends Tag {
private final Class<? extends Tag> type;
private final List<Tag> value;
/**
* Creates the tag with an empty name.
*
* @param type the type of tag
* @param value the value of the tag
*/
public ListTag(Class<? extends Tag> type, List<? extends Tag> value) {
super();
checkNotNull(value);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Gets the type of item in this list.
*
* @return The type of item in this list.
*/
public Class<? extends Tag> getType() {
return type;
}
@Override
public List<Tag> getValue() {
return value;
}
/**
* Create a new list tag with this tag's name and type.
*
* @param list the new list
* @return a new list tag
*/
public ListTag setValue(List<Tag> list) {
return new ListTag(getType(), list);
}
/**
* Get the tag if it exists at the given index.
*
* @param index the index
* @return the tag or null
*/
@Nullable
public Tag getIfExists(int index) {
try {
return value.get(index);
} catch (NoSuchElementException e) {
return null;
}
}
/**
* Get a byte array named with the given index.
*
* <p>If the index does not exist or its value is not a byte array tag,
* then an empty byte array will be returned.</p>
*
* @param index the index
* @return a byte array
*/
public byte[] getByteArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given index.
*
* <p>If the index does not exist or its value is not a byte tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a byte
*/
public byte getByte(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given index.
*
* <p>If the index does not exist or its value is not a double tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a double
*/
public double getDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a double
*/
public double asDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given index.
*
* <p>If the index does not exist or its value is not a float tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a float
*/
public float getFloat(int index) {
Tag tag = getIfExists(index);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given index.
*
* <p>If the index does not exist or its value is not an int array tag,
* then an empty array will be returned.</p>
*
* @param index the index
* @return an int array
*/
public int[] getIntArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given index.
*
* <p>If the index does not exist or its value is not an int tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return an int
*/
public int getInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return an int
*/
public int asInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty list will be returned.</p>
*
* @param index the index
* @return a list of tags
*/
public List<Tag> getList(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty tag list will be returned.</p>
*
* @param index the index
* @return a tag list instance
*/
public ListTag getListTag(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given index.
*
* <p>If the index does not exist or its value is not a list tag,
* then an empty list will be returned. If the given index references
* a list but the list of of a different type, then an empty
* list will also be returned.</p>
*
* @param index the index
* @param listType the class of the contained type
* @return a list of tags
* @param <T> the NBT type
*/
@SuppressWarnings("unchecked")
public <T extends Tag> List<T> getList(int index, Class<T> listType) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given index.
*
* <p>If the index does not exist or its value is not a long tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a long
*/
public long getLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given index, even if it's another
* type of number.
*
* <p>If the index does not exist or its value is not a number,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a long
*/
public long asLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0;
}
}
/**
* Get a short named with the given index.
*
* <p>If the index does not exist or its value is not a short tag,
* then {@code 0} will be returned.</p>
*
* @param index the index
* @return a short
*/
public short getShort(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given index.
*
* <p>If the index does not exist or its value is not a string tag,
* then {@code ""} will be returned.</p>
*
* @param index the index
* @return a string
*/
public String getString(int index) {
Tag tag = getIfExists(index);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_List").append(": ").append(value.size()).append(" entries of type ").append(NBTUtils.getTypeName(type)).append("\r\n{\r\n");
for (Tag t : value) {
bldr.append(" ").append(t.toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,119 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create list tags.
*/
public class ListTagBuilder {
private final Class<? extends Tag> type;
private final List<Tag> entries;
/**
* Create a new instance.
*
* @param type of tag contained in this list
*/
ListTagBuilder(Class<? extends Tag> type) {
checkNotNull(type);
this.type = type;
this.entries = new ArrayList<Tag>();
}
/**
* Add the given tag.
*
* @param value the tag
* @return this object
*/
public ListTagBuilder add(Tag value) {
checkNotNull(value);
if (!type.isInstance(value)) {
throw new IllegalArgumentException(value.getClass().getCanonicalName() + " is not of expected type " + type.getCanonicalName());
}
entries.add(value);
return this;
}
/**
* Add all the tags in the given list.
*
* @param value a list of tags
* @return this object
*/
public ListTagBuilder addAll(Collection<? extends Tag> value) {
checkNotNull(value);
for (Tag v : value) {
add(v);
}
return this;
}
/**
* Build an unnamed list tag with this builder's entries.
*
* @return the new list tag
*/
public ListTag build() {
return new ListTag(type, new ArrayList<Tag>(entries));
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static ListTagBuilder create(Class<? extends Tag> type) {
return new ListTagBuilder(type);
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static <T extends Tag> ListTagBuilder createWith(T ... entries) {
checkNotNull(entries);
if (entries.length == 0) {
throw new IllegalArgumentException("This method needs an array of at least one entry");
}
Class<? extends Tag> type = entries[0].getClass();
for (int i = 1; i < entries.length; i++) {
if (!type.isInstance(entries[i])) {
throw new IllegalArgumentException("An array of different tag types was provided");
}
}
ListTagBuilder builder = new ListTagBuilder(type);
builder.addAll(Arrays.asList(entries));
return builder;
}
}

View File

@ -0,0 +1,50 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Long} tag.
*
*/
public final class LongTag extends Tag {
private final long value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public LongTag(long value) {
super();
this.value = value;
}
@Override
public Long getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Long(" + value + ")";
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.nio.charset.Charset;
/**
* A class which holds constant values.
*/
public final class NBTConstants {
public static final Charset CHARSET = Charset.forName("UTF-8");
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2,
TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6,
TYPE_BYTE_ARRAY = 7, TYPE_STRING = 8, TYPE_LIST = 9,
TYPE_COMPOUND = 10, TYPE_INT_ARRAY = 11;
/**
* Default private constructor.
*/
private NBTConstants() {
}
/**
* Convert a type ID to its corresponding {@link Tag} class.
*
* @param id type ID
* @return tag class
* @throws IllegalArgumentException thrown if the tag ID is not valid
*/
public static Class<? extends Tag> getClassFromType(int id) {
switch (id) {
case TYPE_END:
return EndTag.class;
case TYPE_BYTE:
return ByteTag.class;
case TYPE_SHORT:
return ShortTag.class;
case TYPE_INT:
return IntTag.class;
case TYPE_LONG:
return LongTag.class;
case TYPE_FLOAT:
return FloatTag.class;
case TYPE_DOUBLE:
return DoubleTag.class;
case TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case TYPE_STRING:
return StringTag.class;
case TYPE_LIST:
return ListTag.class;
case TYPE_COMPOUND:
return CompoundTag.class;
case TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Unknown tag type ID of " + id);
}
}
}

View File

@ -0,0 +1,171 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* streams, and produces an object graph of subclasses of the {@code Tag}
* object.
*
* <p>The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
*/
public final class NBTInputStream implements Closeable {
private final DataInputStream is;
/**
* Creates a new {@code NBTInputStream}, which will source its data
* from the specified input stream.
*
* @param is the input stream
* @throws IOException if an I/O error occurs
*/
public NBTInputStream(InputStream is) throws IOException {
this.is = new DataInputStream(is);
}
/**
* Reads an NBT tag from the stream.
*
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
public NamedTag readNamedTag() throws IOException {
return readNamedTag(0);
}
/**
* Reads an NBT from the stream.
*
* @param depth the depth of this tag
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
private NamedTag readNamedTag(int depth) throws IOException {
int type = is.readByte() & 0xFF;
String name;
if (type != NBTConstants.TYPE_END) {
int nameLength = is.readShort() & 0xFFFF;
byte[] nameBytes = new byte[nameLength];
is.readFully(nameBytes);
name = new String(nameBytes, NBTConstants.CHARSET);
} else {
name = "";
}
return new NamedTag(name, readTagPayload(type, depth));
}
/**
* Reads the payload of a tag given the type.
*
* @param type the type
* @param depth the depth
* @return the tag
* @throws IOException if an I/O error occurs.
*/
private Tag readTagPayload(int type, int depth) throws IOException {
switch (type) {
case NBTConstants.TYPE_END:
if (depth == 0) {
throw new IOException(
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
} else {
return new EndTag();
}
case NBTConstants.TYPE_BYTE:
return new ByteTag(is.readByte());
case NBTConstants.TYPE_SHORT:
return new ShortTag(is.readShort());
case NBTConstants.TYPE_INT:
return new IntTag(is.readInt());
case NBTConstants.TYPE_LONG:
return new LongTag(is.readLong());
case NBTConstants.TYPE_FLOAT:
return new FloatTag(is.readFloat());
case NBTConstants.TYPE_DOUBLE:
return new DoubleTag(is.readDouble());
case NBTConstants.TYPE_BYTE_ARRAY:
int length = is.readInt();
byte[] bytes = new byte[length];
is.readFully(bytes);
return new ByteArrayTag(bytes);
case NBTConstants.TYPE_STRING:
length = is.readShort();
bytes = new byte[length];
is.readFully(bytes);
return new StringTag(new String(bytes, NBTConstants.CHARSET));
case NBTConstants.TYPE_LIST:
int childType = is.readByte();
length = is.readInt();
List<Tag> tagList = new ArrayList<Tag>();
for (int i = 0; i < length; ++i) {
Tag tag = readTagPayload(childType, depth + 1);
if (tag instanceof EndTag) {
throw new IOException("TAG_End not permitted in a list.");
}
tagList.add(tag);
}
return new ListTag(NBTUtils.getTypeClass(childType), tagList);
case NBTConstants.TYPE_COMPOUND:
Map<String, Tag> tagMap = new HashMap<String, Tag>();
while (true) {
NamedTag namedTag = readNamedTag(depth + 1);
Tag tag = namedTag.getTag();
if (tag instanceof EndTag) {
break;
} else {
tagMap.put(namedTag.getName(), tag);
}
}
return new CompoundTag(tagMap);
case NBTConstants.TYPE_INT_ARRAY:
length = is.readInt();
int[] data = new int[length];
for (int i = 0; i < length; i++) {
data[i] = is.readInt();
}
return new IntArrayTag(data);
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
@Override
public void close() throws IOException {
is.close();
}
}

View File

@ -0,0 +1,294 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* {@code Tag} objects to an underlying {@code OutputStream}.
*
* <p>The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.</p>
*/
public final class NBTOutputStream implements Closeable {
/**
* The output stream.
*/
private final DataOutputStream os;
/**
* Creates a new {@code NBTOutputStream}, which will write data to the
* specified underlying output stream.
*
* @param os
* The output stream.
* @throws IOException
* if an I/O error occurs.
*/
public NBTOutputStream(OutputStream os) throws IOException {
this.os = new DataOutputStream(os);
}
/**
* Writes a tag.
*
* @param tag
* The tag to write.
* @throws IOException
* if an I/O error occurs.
*/
public void writeNamedTag(String name, Tag tag) throws IOException {
checkNotNull(name);
checkNotNull(tag);
int type = NBTUtils.getTypeCode(tag.getClass());
byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
os.writeByte(type);
os.writeShort(nameBytes.length);
os.write(nameBytes);
if (type == NBTConstants.TYPE_END) {
throw new IOException("Named TAG_End not permitted.");
}
writeTagPayload(tag);
}
/**
* Writes tag payload.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeTagPayload(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
switch (type) {
case NBTConstants.TYPE_END:
writeEndTagPayload((EndTag) tag);
break;
case NBTConstants.TYPE_BYTE:
writeByteTagPayload((ByteTag) tag);
break;
case NBTConstants.TYPE_SHORT:
writeShortTagPayload((ShortTag) tag);
break;
case NBTConstants.TYPE_INT:
writeIntTagPayload((IntTag) tag);
break;
case NBTConstants.TYPE_LONG:
writeLongTagPayload((LongTag) tag);
break;
case NBTConstants.TYPE_FLOAT:
writeFloatTagPayload((FloatTag) tag);
break;
case NBTConstants.TYPE_DOUBLE:
writeDoubleTagPayload((DoubleTag) tag);
break;
case NBTConstants.TYPE_BYTE_ARRAY:
writeByteArrayTagPayload((ByteArrayTag) tag);
break;
case NBTConstants.TYPE_STRING:
writeStringTagPayload((StringTag) tag);
break;
case NBTConstants.TYPE_LIST:
writeListTagPayload((ListTag) tag);
break;
case NBTConstants.TYPE_COMPOUND:
writeCompoundTagPayload((CompoundTag) tag);
break;
case NBTConstants.TYPE_INT_ARRAY:
writeIntArrayTagPayload((IntArrayTag) tag);
break;
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
/**
* Writes a {@code TAG_Byte} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteTagPayload(ByteTag tag) throws IOException {
os.writeByte(tag.getValue());
}
/**
* Writes a {@code TAG_Byte_Array} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
byte[] bytes = tag.getValue();
os.writeInt(bytes.length);
os.write(bytes);
}
/**
* Writes a {@code TAG_Compound} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeCompoundTagPayload(CompoundTag tag) throws IOException {
for (Map.Entry<String, Tag> entry : tag.getValue().entrySet()) {
writeNamedTag(entry.getKey(), entry.getValue());
}
os.writeByte((byte) 0); // end tag - better way?
}
/**
* Writes a {@code TAG_List} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeListTagPayload(ListTag tag) throws IOException {
Class<? extends Tag> clazz = tag.getType();
List<Tag> tags = tag.getValue();
int size = tags.size();
os.writeByte(NBTUtils.getTypeCode(clazz));
os.writeInt(size);
for (Tag tag1 : tags) {
writeTagPayload(tag1);
}
}
/**
* Writes a {@code TAG_String} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeStringTagPayload(StringTag tag) throws IOException {
byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
os.writeShort(bytes.length);
os.write(bytes);
}
/**
* Writes a {@code TAG_Double} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
os.writeDouble(tag.getValue());
}
/**
* Writes a {@code TAG_Float} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeFloatTagPayload(FloatTag tag) throws IOException {
os.writeFloat(tag.getValue());
}
/**
* Writes a {@code TAG_Long} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeLongTagPayload(LongTag tag) throws IOException {
os.writeLong(tag.getValue());
}
/**
* Writes a {@code TAG_Int} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeIntTagPayload(IntTag tag) throws IOException {
os.writeInt(tag.getValue());
}
/**
* Writes a {@code TAG_Short} tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeShortTagPayload(ShortTag tag) throws IOException {
os.writeShort(tag.getValue());
}
/**
* Writes a {@code TAG_Empty} tag.
*
* @param tag the tag
*/
private void writeEndTagPayload(EndTag tag) {
/* empty */
}
private void writeIntArrayTagPayload(IntArrayTag tag) throws IOException {
int[] data = tag.getValue();
os.writeInt(data.length);
for (int aData : data) {
os.writeInt(aData);
}
}
@Override
public void close() throws IOException {
os.close();
}
}

View File

@ -0,0 +1,170 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import java.util.Map;
/**
* A class which contains NBT-related utility methods.
*
*/
public final class NBTUtils {
/**
* Default private constructor.
*/
private NBTUtils() {
}
/**
* Gets the type name of a tag.
*
* @param clazz the tag class
* @return The type name.
*/
public static String getTypeName(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte";
} else if (clazz.equals(CompoundTag.class)) {
return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double";
} else if (clazz.equals(EndTag.class)) {
return "TAG_End";
} else if (clazz.equals(FloatTag.class)) {
return "TAG_Float";
} else if (clazz.equals(IntTag.class)) {
return "TAG_Int";
} else if (clazz.equals(ListTag.class)) {
return "TAG_List";
} else if (clazz.equals(LongTag.class)) {
return "TAG_Long";
} else if (clazz.equals(ShortTag.class)) {
return "TAG_Short";
} else if (clazz.equals(StringTag.class)) {
return "TAG_String";
} else if (clazz.equals(IntArrayTag.class)) {
return "TAG_Int_Array";
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the type code of a tag class.
*
* @param clazz the tag class
* @return The type code.
* @throws IllegalArgumentException if the tag class is invalid.
*/
public static int getTypeCode(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE;
} else if (clazz.equals(CompoundTag.class)) {
return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE;
} else if (clazz.equals(EndTag.class)) {
return NBTConstants.TYPE_END;
} else if (clazz.equals(FloatTag.class)) {
return NBTConstants.TYPE_FLOAT;
} else if (clazz.equals(IntTag.class)) {
return NBTConstants.TYPE_INT;
} else if (clazz.equals(ListTag.class)) {
return NBTConstants.TYPE_LIST;
} else if (clazz.equals(LongTag.class)) {
return NBTConstants.TYPE_LONG;
} else if (clazz.equals(ShortTag.class)) {
return NBTConstants.TYPE_SHORT;
} else if (clazz.equals(StringTag.class)) {
return NBTConstants.TYPE_STRING;
} else if (clazz.equals(IntArrayTag.class)) {
return NBTConstants.TYPE_INT_ARRAY;
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the class of a type of tag.
*
* @param type the type
* @return The class.
* @throws IllegalArgumentException if the tag type is invalid.
*/
public static Class<? extends Tag> getTypeClass(int type) {
switch (type) {
case NBTConstants.TYPE_END:
return EndTag.class;
case NBTConstants.TYPE_BYTE:
return ByteTag.class;
case NBTConstants.TYPE_SHORT:
return ShortTag.class;
case NBTConstants.TYPE_INT:
return IntTag.class;
case NBTConstants.TYPE_LONG:
return LongTag.class;
case NBTConstants.TYPE_FLOAT:
return FloatTag.class;
case NBTConstants.TYPE_DOUBLE:
return DoubleTag.class;
case NBTConstants.TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case NBTConstants.TYPE_STRING:
return StringTag.class;
case NBTConstants.TYPE_LIST:
return ListTag.class;
case NBTConstants.TYPE_COMPOUND:
return CompoundTag.class;
case NBTConstants.TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Invalid tag type : " + type
+ ".");
}
}
/**
* Get child tag of a NBT structure.
*
* @param items the map to read from
* @param key the key to look for
* @param expected the expected NBT class type
* @return child tag
* @throws IllegalArgumentException
*/
public static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) throws IllegalArgumentException {
if (!items.containsKey(key)) {
throw new IllegalArgumentException("Missing a \"" + key + "\" tag");
}
Tag tag = items.get(key);
if (!expected.isInstance(tag)) {
throw new IllegalArgumentException(key + " tag is not of tag type " + expected.getName());
}
return expected.cast(tag);
}
}

View File

@ -0,0 +1,63 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A tag that has a name.
*/
public class NamedTag {
private final String name;
private final Tag tag;
/**
* Create a new named tag.
*
* @param name the name
* @param tag the tag
*/
public NamedTag(String name, Tag tag) {
checkNotNull(name);
checkNotNull(tag);
this.name = name;
this.tag = tag;
}
/**
* Get the name of the tag.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Get the tag.
*
* @return the tag
*/
public Tag getTag() {
return tag;
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* The {@code TAG_Short} tag.
*/
public final class ShortTag extends Tag {
private final short value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ShortTag(short value) {
super();
this.value = value;
}
@Override
public Short getValue() {
return value;
}
@Override
public String toString() {
return "TAG_Short(" + value + ")";
}
}

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_String} tag.
*/
public final class StringTag extends Tag {
private final String value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public StringTag(String value) {
super();
checkNotNull(value);
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public String toString() {
return "TAG_String(" + value + ")";
}
}

View File

@ -0,0 +1,34 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* 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. If not, see <http://www.gnu.org/licenses/>.
*/
package com.java.sk89q.jnbt;
/**
* Represents a NBT tag.
*/
public abstract class Tag {
/**
* Gets the value of this tag.
*
* @return the value
*/
public abstract Object getValue();
}

View File

@ -0,0 +1,62 @@
package mineplex.core.common.schematic;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
import net.minecraft.server.v1_7_R4.World;
public class Schematic
{
private final short _width;
private final short _height;
private final short _length;
private final byte[] _blocks;
private final byte[] _blockData;
public Schematic(short width, short height, short length, byte[] blocks, byte[] blockData)
{
_width = width;
_height = height;
_length = length;
_blocks = blocks;
_blockData = blockData;
}
public void paste(Location originLocation)
{
int startX = originLocation.getBlockX();
int startY = originLocation.getBlockY();
int startZ = originLocation.getBlockZ();
World nmsWorld = ((CraftWorld) originLocation.getWorld()).getHandle();
for (int x = 0; x < _width; x++)
{
for (int y = 0; y < _height; y++)
{
for (int z = 0; z < _length; z++)
{
int index = y * _width * _length + z * _width + x;
Block block = originLocation.getWorld().getBlockAt(startX + x, startY + y, startZ + z);
// some blocks were giving me negative id's in the schematic (like stairs)
// not sure why but the math.abs is my simple fix
int materialId = Math.abs(_blocks[index]);
Material material = Material.getMaterial(materialId);
if (material == null)
{
System.out.println(materialId + " data: " + _blockData[index]);
continue;
}
block.setTypeIdAndData(materialId, _blockData[index], false);
}
}
}
}
@Override
public String toString()
{
return String.format("width: %d, length: %d, height: %d, blockLength: %d, blockDataLength: %d", _width, _length, _height, _blocks.length, _blockData.length);
}
}

View File

@ -0,0 +1,55 @@
package mineplex.core.common.schematic;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import com.java.sk89q.jnbt.ByteArrayTag;
import com.java.sk89q.jnbt.CompoundTag;
import com.java.sk89q.jnbt.NBTInputStream;
import com.java.sk89q.jnbt.NamedTag;
import com.java.sk89q.jnbt.ShortTag;
import com.java.sk89q.jnbt.Tag;
public class UtilSchematic
{
public static Schematic loadSchematic(File file) throws IOException
{
FileInputStream fis = new FileInputStream(file);
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(fis));
NamedTag rootTag = nbtStream.readNamedTag();
nbtStream.close();
if (!rootTag.getName().equals("Schematic"))
return null;
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
Map<String, Tag> schematic = schematicTag.getValue();
short width = getChildTag(schematic, "Width", ShortTag.class).getValue();
short height = getChildTag(schematic, "Height", ShortTag.class).getValue();
short length = getChildTag(schematic, "Length", ShortTag.class).getValue();
byte[] blocks = getChildTag(schematic, "Blocks", ByteArrayTag.class).getValue();
byte[] blockData = getChildTag(schematic, "Data", ByteArrayTag.class).getValue();
return new Schematic(width, height, length, blocks, blockData);
}
private static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected)
{
Tag tag = items.get(key);
return expected.cast(tag);
}
public static void main(String[] args) throws IOException
{
File file = new File("test.schematic");
System.out.println(file.getAbsoluteFile());
Schematic m = UtilSchematic.loadSchematic(file);
System.out.println(m);
}
}

View File

@ -209,7 +209,7 @@ public class UtilParticle
} }
public static void PlayParticle(ParticleType type,Location location, float offsetX, float offsetY, float offsetZ, public static void PlayParticle(ParticleType type,Location location, float offsetX, float offsetY, float offsetZ,
float speed, int count, ViewDist dist, Player... players) float speed, int count, ViewDist dist, Player... players)
{ {
PlayParticle(type.particleName, location, offsetX, offsetY, offsetZ, speed, count, dist, players); PlayParticle(type.particleName, location, offsetX, offsetY, offsetZ, speed, count, dist, players);
} }

View File

@ -4,6 +4,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.UUID; import java.util.UUID;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -22,6 +23,8 @@ import net.minecraft.server.v1_7_R4.PlayerConnection;
public class UtilPlayer public class UtilPlayer
{ {
private static Random RANDOM = new Random();
private static boolean hasIntersection(Vector3D p1, Vector3D p2, Vector3D min, Vector3D max) private static boolean hasIntersection(Vector3D p1, Vector3D p2, Vector3D min, Vector3D max)
{ {
final double epsilon = 0.0001f; final double epsilon = 0.0001f;
@ -450,7 +453,7 @@ public class UtilPlayer
return best; return best;
} }
public static Player getClosest(Location loc, Entity ignore) public static Player getClosest(Location loc, Entity... ignore)
{ {
Player best = null; Player best = null;
double bestDist = 0; double bestDist = 0;
@ -463,8 +466,14 @@ public class UtilPlayer
if (cur.isDead()) if (cur.isDead())
continue; continue;
if (ignore != null && ignore.equals(cur)) if (ignore != null)
continue; {
for (int i = 0; i < ignore.length; i++)
{
if (cur.equals(ignore[i]))
continue;
}
}
double dist = UtilMath.offset(cur.getLocation(), loc); double dist = UtilMath.offset(cur.getLocation(), loc);
@ -524,7 +533,7 @@ public class UtilPlayer
continue; continue;
//Get lower offset (eye to eye, eye to feet) //Get lower offset (eye to eye, eye to feet)
double offset = Math.min(UtilMath.offset(player.getEyeLocation(), cur.getEyeLocation()), double offset = Math.min(UtilMath.offset(player.getEyeLocation(), cur.getEyeLocation()),
UtilMath.offset(player.getEyeLocation(), cur.getLocation())); UtilMath.offset(player.getEyeLocation(), cur.getLocation()));
if (offset < distance && UtilAlg.isTargetInPlayerPyramid(player, cur, angleLimit)) if (offset < distance && UtilAlg.isTargetInPlayerPyramid(player, cur, angleLimit))
@ -602,6 +611,18 @@ public class UtilPlayer
} }
} }
/**
* Get a random player within maxDist of the target location
* @param location The center location to look for the player
* @param maxDist The max distance from location that the player can be
* @return A random player that is within maxDist of location, or null if no players apply
*/
public static Player getRandomTarget(Location location, double maxDist)
{
List<Player> nearby = getNearby(location, maxDist);
return nearby.size() > 0 ? nearby.get(RANDOM.nextInt(nearby.size())) : null;
}
public static boolean isSpectator(Entity player) public static boolean isSpectator(Entity player)
{ {
if (player instanceof Player) if (player instanceof Player)

View File

@ -1,5 +1,7 @@
package mineplex.core.reward; package mineplex.core.reward;
import java.util.ArrayList;
public enum RewardType public enum RewardType
{ {
//% Chances Mythic Legend Rare Uncommon //% Chances Mythic Legend Rare Uncommon
@ -34,4 +36,43 @@ public enum RewardType
return rarity; return rarity;
} }
public static void main(String[] args)
{
int maxCount = Integer.MAX_VALUE;
int openCount = 0;
RewardType type = RewardType.MythicalChest;
ArrayList<RewardTest> data = new ArrayList<RewardTest>();
for (RewardRarity rarity : RewardRarity.values())
{
data.add(rarity.ordinal(), new RewardTest(rarity));
}
for (int i = 0; i < maxCount; i++)
{
RewardRarity rarity = type.generateRarity(false);
data.get(rarity.ordinal()).Count++;
openCount++;
if (rarity == RewardRarity.MYTHICAL) break;
}
System.out.printf("Opened %10d rewards using type " + type.name() + "\n", openCount);
for (RewardTest test : data)
{
System.out.printf("Opened %10d of reward type %10s", test.Count, test.Rarity.name());
System.out.println();
}
}
private static class RewardTest
{
public final RewardRarity Rarity;
public int Count;
public RewardTest(RewardRarity rare)
{
Rarity = rare;
}
}
} }

View File

@ -5,7 +5,6 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content> </content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="Mineplex.Core" /> <orderEntry type="module" module-name="Mineplex.Core" />
<orderEntry type="module" module-name="Mineplex.Core.Common" /> <orderEntry type="module" module-name="Mineplex.Core.Common" />
@ -15,5 +14,7 @@
<orderEntry type="library" name="craftbukkit" level="project" /> <orderEntry type="library" name="craftbukkit" level="project" />
<orderEntry type="module" module-name="Mineplex.Database" /> <orderEntry type="module" module-name="Mineplex.Database" />
<orderEntry type="library" name="jooq" level="project" /> <orderEntry type="library" name="jooq" level="project" />
<orderEntry type="inheritedJdk" />
<orderEntry type="library" name="gson" level="project" />
</component> </component>
</module> </module>

View File

@ -31,6 +31,7 @@ import mineplex.core.teleport.Teleport;
import mineplex.core.updater.FileUpdater; import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater; import mineplex.core.updater.Updater;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.items.GearManager; import mineplex.game.clans.items.GearManager;
import mineplex.game.clans.shop.building.BuildingShop; import mineplex.game.clans.shop.building.BuildingShop;
import mineplex.game.clans.shop.pvp.PvpShop; import mineplex.game.clans.shop.pvp.PvpShop;

View File

@ -46,6 +46,7 @@ import mineplex.game.clans.clans.repository.tokens.ClanTerritoryToken;
import mineplex.game.clans.clans.repository.tokens.ClanToken; import mineplex.game.clans.clans.repository.tokens.ClanToken;
import mineplex.game.clans.clans.war.WarManager; import mineplex.game.clans.clans.war.WarManager;
import mineplex.game.clans.economy.GoldManager; import mineplex.game.clans.economy.GoldManager;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.fields.Field; import mineplex.game.clans.fields.Field;
import mineplex.game.clans.gameplay.Gameplay; import mineplex.game.clans.gameplay.Gameplay;
import mineplex.game.clans.gameplay.safelog.LoggingManager; import mineplex.game.clans.gameplay.safelog.LoggingManager;
@ -89,6 +90,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan> implements IRelat
private ClassCombatShop _classShop; private ClassCombatShop _classShop;
private ClassManager _classManager; private ClassManager _classManager;
private WarManager _warManager; private WarManager _warManager;
private ProjectileManager _projectileManager;
private int _inviteExpire = 2; private int _inviteExpire = 2;
private int _nameMin = 3; private int _nameMin = 3;
@ -147,15 +149,15 @@ public class ClansManager extends MiniClientPlugin<ClientClan> implements IRelat
new Weapon(plugin, energy); new Weapon(plugin, energy);
new Gameplay(plugin, this, blockRestore, damageManager); new Gameplay(plugin, this, blockRestore, damageManager);
ProjectileManager throwManager = new ProjectileManager(plugin); _projectileManager = new ProjectileManager(plugin);
Fire fire = new Fire(plugin, _condition, damageManager); Fire fire = new Fire(plugin, _condition, damageManager);
HashSet<String> itemIgnore = new HashSet<String>(); HashSet<String> itemIgnore = new HashSet<String>();
itemIgnore.add("Proximity Explosive"); itemIgnore.add("Proximity Explosive");
itemIgnore.add("Proximity Zapper"); itemIgnore.add("Proximity Zapper");
ItemFactory itemFactory = new ItemFactory(plugin, blockRestore, _condition, damageManager, energy, fire, throwManager, webServerAddress, itemIgnore); ItemFactory itemFactory = new ItemFactory(plugin, blockRestore, _condition, damageManager, energy, fire, _projectileManager, webServerAddress, itemIgnore);
SkillFactory skillManager = new SkillFactory(plugin, damageManager, this, _combatManager, _condition, throwManager, disguiseManager, blockRestore, fire, new Movement(plugin), teleport, energy, webServerAddress); SkillFactory skillManager = new SkillFactory(plugin, damageManager, this, _combatManager, _condition, _projectileManager, disguiseManager, blockRestore, fire, new Movement(plugin), teleport, energy, webServerAddress);
skillManager.RemoveSkill("Dwarf Toss", "Block Toss"); skillManager.RemoveSkill("Dwarf Toss", "Block Toss");
_classManager = new ClassManager(plugin, _clientManager, donationManager, skillManager, itemFactory, webServerAddress); _classManager = new ClassManager(plugin, _clientManager, donationManager, skillManager, itemFactory, webServerAddress);
@ -167,6 +169,8 @@ public class ClansManager extends MiniClientPlugin<ClientClan> implements IRelat
_warManager = new WarManager(plugin, this); _warManager = new WarManager(plugin, this);
ClanEnergyManager clanEnergyManager = new ClanEnergyManager(plugin, this, clientManager, donationManager); ClanEnergyManager clanEnergyManager = new ClanEnergyManager(plugin, this, clientManager, donationManager);
new WorldEventManager(plugin, this, damageManager);
for (ClanToken token : _clanDataAccess.getRepository().retrieveClans()) for (ClanToken token : _clanDataAccess.getRepository().retrieveClans())
{ {
@ -553,6 +557,11 @@ public class ClansManager extends MiniClientPlugin<ClientClan> implements IRelat
return _warManager; return _warManager;
} }
public ProjectileManager getProjectile()
{
return _projectileManager;
}
public int convertGoldToEnergy(int gold) public int convertGoldToEnergy(int gold)
{ {
return gold * 4; return gold * 4;

View File

@ -0,0 +1,46 @@
package mineplex.game.clans.clans.worldevent;
import org.bukkit.Location;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.game.clans.clans.worldevent.event.WorldEventType;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimeBoss;
import mineplex.game.clans.clans.worldevent.event.kinghill.KingHill;
public class ConcreteWorldEventFactory implements WorldEventFactory
{
private WorldEventManager _eventManager;
public ConcreteWorldEventFactory(WorldEventManager eventManager)
{
_eventManager = eventManager;
}
@Override
public AbstractWorldEvent fromName(Location location, String name)
{
if (name.equalsIgnoreCase("slime"))
{
return new SlimeBoss(_eventManager, _eventManager.getDamage(), location);
} else if (name.equalsIgnoreCase("kinghill"))
{
return new KingHill(_eventManager, _eventManager.getDamage(), location);
}
else
{
return null;
}
}
@Override
public AbstractWorldEvent random(Location location)
{
return null;
}
@Override
public AbstractWorldEvent randomFromType(Location locationm, WorldEventType type)
{
return null;
}
}

View File

@ -0,0 +1,15 @@
package mineplex.game.clans.clans.worldevent;
import org.bukkit.Location;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.game.clans.clans.worldevent.event.WorldEventType;
public interface WorldEventFactory
{
public AbstractWorldEvent fromName(Location location, String name);
public AbstractWorldEvent random(Location location);
public AbstractWorldEvent randomFromType(Location locationm, WorldEventType type);
}

View File

@ -0,0 +1,8 @@
package mineplex.game.clans.clans.worldevent;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
public interface WorldEventListener
{
public void onComplete(AbstractWorldEvent event);
}

View File

@ -0,0 +1,99 @@
package mineplex.game.clans.clans.worldevent;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.worldevent.command.WorldEventCommand;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.minecraft.game.core.damage.DamageManager;
public class WorldEventManager extends MiniPlugin implements WorldEventListener
{
private final WorldEventFactory _factory;
private final Set<AbstractWorldEvent> _events;
private ClansManager _clansManager;
private DamageManager _damageManager;
public WorldEventManager(JavaPlugin plugin, ClansManager clansManager, DamageManager damageManager)
{
super("World Event", plugin);
_clansManager = clansManager;
_damageManager = damageManager;
_factory = new ConcreteWorldEventFactory(this);
_events = new HashSet<AbstractWorldEvent>();
}
@Override
public void disable()
{
for (AbstractWorldEvent event : _events)
{
event.cancel();
}
}
private void initializeEvent(AbstractWorldEvent event)
{
assert(event != null);
event.start();
event.addListener(this);
getPlugin().getServer().getPluginManager().registerEvents(event, getPlugin());
_events.add(event);
}
public AbstractWorldEvent startEventFromName(Location location, String name)
{
AbstractWorldEvent event = _factory.fromName(location, name);
if (event != null) initializeEvent(event);
return event;
}
public ClansManager getClans()
{
return _clansManager;
}
public DamageManager getDamage()
{
return _damageManager;
}
@Override
public void onComplete(AbstractWorldEvent event)
{
// TODO
Bukkit.broadcastMessage("World Event Manager On Complete");
HandlerList.unregisterAll(event);
_events.remove(event);
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK) return;
for (AbstractWorldEvent e : _events)
{
e.tick();
}
}
@Override
public void addCommands()
{
addCommand(new WorldEventCommand(this));
}
}

View File

@ -0,0 +1,34 @@
package mineplex.game.clans.clans.worldevent.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
public class StartCommand extends CommandBase<WorldEventManager>
{
public StartCommand(WorldEventManager plugin)
{
super(plugin, Rank.DEVELOPER, "start", "create");
}
@Override
public void Execute(Player caller, String[] args)
{
// start specific world event type
if (args != null && args.length == 1)
{
AbstractWorldEvent event = Plugin.startEventFromName(caller.getLocation(), args[0]);
if (event == null)
UtilPlayer.message(caller, F.main("WorldEvent", "Could not find a WorldEvent with the name " + F.elem(args[0])));
else
{
UtilPlayer.message(caller, F.main("worldEvent", "Started WorldEvent " + F.elem(args[0]) + " at your current location"));
}
}
}
}

View File

@ -0,0 +1,23 @@
package mineplex.game.clans.clans.worldevent.command;
import org.bukkit.entity.Player;
import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
public class WorldEventCommand extends MultiCommandBase<WorldEventManager>
{
public WorldEventCommand(WorldEventManager plugin)
{
super(plugin, Rank.DEVELOPER, "worldevent", "we", "event");
AddCommand(new StartCommand(Plugin));
}
@Override
protected void Help(Player caller, String[] args)
{
}
}

View File

@ -0,0 +1,26 @@
package mineplex.game.clans.clans.worldevent.creature;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Listener;
public abstract class EventCreature<T extends LivingEntity> implements Listener
{
private T _entity;
// Creature Data
private String _name;
private double _health;
private double _maxHealth;
public EventCreature(Location spawnLocation, Class<T> clazz)
{
_entity = spawnLocation.getWorld().spawn(spawnLocation, clazz);
}
}

View File

@ -0,0 +1,149 @@
package mineplex.game.clans.clans.worldevent.event;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.game.clans.clans.worldevent.WorldEventListener;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.minecraft.game.core.damage.DamageManager;
public abstract class AbstractWorldEvent implements Listener
{
private WorldEventManager _eventManager;
private DamageManager _damageManager;
private List<WorldEventListener> _listeners;
private String _name;
private Location _centerLocation;
private boolean _running;
private int _ticks;
private Random _random;
// Event States
private EventState _currentState;
public AbstractWorldEvent(WorldEventManager eventManager, DamageManager damageManager, String name, Location centerLocation)
{
_eventManager = eventManager;
_damageManager = damageManager;
_name = name;
_centerLocation = centerLocation;
_listeners = new ArrayList<WorldEventListener>();
_random = new Random();
}
public final void start()
{
_running = true;
customStart();
}
protected abstract void customStart();
public final void cancel()
{
_running = false;
customCancel();
}
protected abstract void customCancel();
protected abstract void customTick();
public final void tick()
{
_ticks++;
customTick();
if (_currentState != null) _currentState.tick();
}
public boolean isRunning()
{
return _running;
}
public void addListener(WorldEventListener listener)
{
_listeners.add(listener);
}
public void removeListener(WorldEventListener listener)
{
_listeners.remove(listener);
}
protected List<WorldEventListener> getListeners()
{
return _listeners;
}
public void clearListeners()
{
_listeners.clear();
}
public int getTicks()
{
return _ticks;
}
public WorldEventManager getEventManager()
{
return _eventManager;
}
public DamageManager getDamageManager()
{
return _damageManager;
}
public void setState(EventState state)
{
JavaPlugin plugin = _eventManager.getPlugin();
if (_currentState != null)
{
// Unregister old state listener
HandlerList.unregisterAll(_currentState);
_currentState.onStateStop();
}
if (state != null)
{
// Register new state listener
plugin.getServer().getPluginManager().registerEvents(state, plugin);
state.onStateStart();
}
_currentState = state;
}
public EventState getState()
{
return _currentState;
}
public String getName()
{
return _name;
}
protected Random getRandom()
{
return _random;
}
public Location getCenterLocation()
{
return _centerLocation;
}
}

View File

@ -0,0 +1,39 @@
package mineplex.game.clans.clans.worldevent.event;
import org.bukkit.event.Listener;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
public abstract class EventState implements Listener
{
private AbstractWorldEvent _event;
private int _ticks;
public EventState(AbstractWorldEvent event)
{
_event = event;
_ticks = 0;
}
public AbstractWorldEvent getEvent()
{
return _event;
}
public final void tick()
{
_ticks++;
onTick();
}
public int getTicks()
{
return _ticks;
}
public abstract void onTick();
public abstract void onStateStart();
public abstract void onStateStop();
}

View File

@ -0,0 +1,6 @@
package mineplex.game.clans.clans.worldevent.event;
public enum WorldEventType
{
BOSS_FIGHT;
}

View File

@ -0,0 +1,90 @@
package mineplex.game.clans.clans.worldevent.event.boss;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.game.clans.clans.worldevent.WorldEventListener;
import mineplex.minecraft.game.core.damage.DamageManager;
public abstract class AbstractBoss extends AbstractWorldEvent
{
private double _maxHealth;
private double _health;
private double _lastHealth;
// Action Bar Messages
private float _radiusSquared;
public AbstractBoss(WorldEventManager eventManager, DamageManager damageManager, String name, Location center, float radius, double maxHealth)
{
super(eventManager, damageManager, name, center);
_health = maxHealth;
_maxHealth = maxHealth;
setRadius(radius);
}
@Override
protected void customTick()
{
if (_lastHealth != _health || getTicks() % 20 == 0)
{
for (Player player : Bukkit.getServer().getOnlinePlayers())
{
if (player.getWorld().equals(getCenterLocation().getWorld()) && getCenterLocation().distanceSquared(player.getLocation()) < _radiusSquared)
{
UtilTextBottom.displayProgress(getName(), _health / _maxHealth, player);
}
}
}
_lastHealth = _health;
if (_health <= 0)
{
onDeath();
if (_health <= 0) // only finish if the health is still less than 0
for (WorldEventListener listener : getListeners()) listener.onComplete(this);
}
}
public void setRadius(float radius)
{
_radiusSquared = radius * radius;
}
protected abstract void onDeath();
protected void damage(double health)
{
_health -= health;
}
protected void setMaxHealth(double maxHealth)
{
_maxHealth = maxHealth;
}
public void setHealth(double health)
{
_health = health;
}
public double getHealth()
{
return _health;
}
public double getMaxHealth()
{
return _maxHealth;
}
public boolean inRange(Location loc)
{
return loc.distanceSquared(getCenterLocation()) <= _radiusSquared;
}
}

View File

@ -0,0 +1,20 @@
package mineplex.game.clans.clans.worldevent.event.boss;
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
import mineplex.game.clans.clans.worldevent.event.EventState;
public abstract class BossState extends EventState
{
private AbstractBoss _boss;
public BossState(AbstractBoss boss)
{
super(boss);
_boss = boss;
}
public AbstractBoss getBoss()
{
return _boss;
}
}

View File

@ -0,0 +1,27 @@
package mineplex.game.clans.clans.worldevent.event.boss;
public class IdleState extends BossState
{
public IdleState(AbstractBoss boss)
{
super(boss);
}
@Override
public void onTick()
{
}
@Override
public void onStateStart()
{
}
@Override
public void onStateStop()
{
}
}

View File

@ -0,0 +1,174 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.SlimeSplitEvent;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
import mineplex.minecraft.game.core.damage.DamageManager;
public class SlimeBoss extends AbstractBoss
{
private static final int MAX_SIZE = 10;
private static final int MIN_SIZE = 1;
private List<SlimePart> _slimes;
public SlimeBoss(WorldEventManager eventManager, DamageManager damageManager, Location center)
{
super(eventManager, damageManager, "Slime King", center, 100, 300);
_slimes = new LinkedList<SlimePart>();
spawnSlime(center, MAX_SIZE);
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage("Custom Start");
}
@Override
protected void customCancel()
{
Bukkit.broadcastMessage("Custom Cancel");
// Remove all the slime entities!
for (SlimePart slime : _slimes)
{
slime.getEntity().remove();
}
}
@Override
protected void customTick()
{
super.customTick();
for (SlimePart slimePart : _slimes)
{
slimePart.tick();
}
}
@EventHandler
public void onSlimeDamage(EntityDamageEvent event)
{
if (event.getEntity().getType() == EntityType.SLIME)
{
for (SlimePart slimePart : _slimes)
{
if (event.getEntity().equals(slimePart.getEntity()))
{
// slime.setHealth(slime.getMaxHealth());
// event.setDamage(0);
break;
}
}
}
}
@EventHandler
public void onSplit(SlimeSplitEvent event)
{
for (SlimePart slimeData : _slimes)
{
if (event.getEntity().equals(slimeData.getEntity()))
event.setCancelled(true);
}
}
@EventHandler
public void onDeath(EntityDeathEvent event)
{
if (event.getEntity().getType() == EntityType.SLIME)
{
Iterator<SlimePart> slimeIterator = _slimes.iterator();
while (slimeIterator.hasNext())
{
SlimePart slimePart = slimeIterator.next();
if (slimePart.getEntity().equals(event.getEntity()))
{
splitSlime(slimePart);
event.setDroppedExp(0);
slimeIterator.remove();
break;
}
}
// Check if our main boss died every time a slime entity dies
checkDeath();
}
}
/**
* Check if this slime boss has been defeated
*/
private void checkDeath()
{
if (_slimes.size() == 0)
{
// SLIME IS DEAD!
setHealth(0);
}
}
private int getSplitSize(int slimeSize)
{
return slimeSize / 2;
}
private int getSplitCount(int slimeSize)
{
return 4;
}
private double getMaxSlimeHealth(int slimeSize)
{
return slimeSize * 20;
}
private int getEnrageTicks(int slimeSize)
{
return 20 * slimeSize;
}
private void splitSlime(SlimePart slime)
{
int splitCount = getSplitCount(slime.getSize());
int splitSize = getSplitSize(slime.getSize());
if (splitSize >= MIN_SIZE)
{
for (int i = 0; i < splitCount; i++)
{
spawnSlime(slime.getEntity().getLocation(), splitSize);
}
}
}
private SlimePart spawnSlime(Location location, int size)
{
SlimePart slimePart = new SlimePart(this, location, size, getMaxSlimeHealth(size), getEnrageTicks(size));
_slimes.add(slimePart);
return slimePart;
}
@Override
protected void onDeath()
{
Bukkit.broadcastMessage("DEATH");
}
}

View File

@ -0,0 +1,122 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime;
import org.bukkit.Location;
import org.bukkit.entity.MagmaCube;
import org.bukkit.entity.Slime;
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.AbsorbAbility;
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.LeapAbility;
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.RocketAbility;
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.SlamAbility;
import mineplex.game.clans.clans.worldevent.event.boss.slime.ability.SlimeAbility;
public class SlimePart
{
private SlimeBoss _boss;
private Slime _slime;
private SlimeAbility _currentAbility;
private Location _spawnLocation;
private boolean _enraged;
// Storing size here incase one of the slime states decide to change the slime size
private int _size;
private double _maxHealth;
private int _ticksLived;
private int _enrageTicks;
public SlimePart(SlimeBoss boss, Location location, int size, double maxHealth, int enrageTicks)
{
_boss = boss;
_spawnLocation = location;
_enraged = false;
_size = size;
_maxHealth = maxHealth;
_ticksLived = 0;
_enrageTicks = enrageTicks;
spawn(location);
}
private void spawn(Location location)
{
double health = _maxHealth;
// Remove old slime
if (_slime != null)
{
health = _slime.getHealth();
_slime.remove();
}
_slime = location.getWorld().spawn(location, _enraged ? MagmaCube.class : Slime.class);
_slime.setMaxHealth(_maxHealth);
_slime.setHealth(health);
_slime.setSize(_size);
}
public void tick()
{
_ticksLived++;
if (_currentAbility == null || (_currentAbility.isIdle() && _currentAbility.getIdleTicks() > 80))
{
double rand = Math.random();
if (rand <= 0.25)
{
_currentAbility = new LeapAbility(this);
}
else if (rand <= 0.50)
{
_currentAbility = new AbsorbAbility(this);
}
else if (rand <= 0.75)
{
_currentAbility = new RocketAbility(this);
}
else
{
_currentAbility = new SlamAbility(this);
}
}
if (!_enraged && _ticksLived >= _enrageTicks)
{
setEnraged(true);
}
_currentAbility.tick();
}
public void setEnraged(boolean enraged)
{
if (enraged != _enraged)
{
_enraged = enraged;
spawn(_slime.getLocation());
}
}
public SlimeBoss getBoss()
{
return _boss;
}
public boolean isEnraged()
{
return _enraged;
}
public int getSize()
{
return _size;
}
public Location getSpawnLocation()
{
return _spawnLocation;
}
public Slime getEntity()
{
return _slime;
}
}

View File

@ -0,0 +1,71 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public class AbsorbAbility extends SlimeAbility
{
private int _ticksPerPulse;
private int _pulseMax;
private int _pulseCount;
private int _maxDistance;
public AbsorbAbility(SlimePart slime)
{
super(slime);
_ticksPerPulse = 20;
_pulseMax = 10;
_pulseCount = 0;
_maxDistance = 20;
}
@Override
public void tickCustom()
{
if (getTicks() % _ticksPerPulse == 0)
{
pulse();
_pulseCount++;
if (_pulseCount >= _pulseMax)
{
setIdle(true);
}
}
}
private void pulse()
{
Bukkit.broadcastMessage("Pulse");
HashMap<Player, Double> playerMap = UtilPlayer.getInRadius(getSlime().getEntity().getLocation(), _maxDistance);
for (Map.Entry<Player, Double> entry : playerMap.entrySet())
{
Player player = entry.getKey();
double distance = entry.getValue();
Vector dir = UtilAlg.getTrajectory2d(player, getSlime().getEntity());
dir.setY(0.4);
player.setVelocity(dir);
getSlime().getBoss().getDamageManager().NewDamageEvent(player, getSlime().getEntity(), null,
EntityDamageEvent.DamageCause.MAGIC, getDamage(distance), false, false, false, getSlime().getBoss().getName(), "Absorb");
}
}
private double getDamage(double distance)
{
double mult = _maxDistance - distance;
return mult * 0.25;
}
}

View File

@ -0,0 +1,64 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public class LeapAbility extends SlimeAbility
{
private Player _target;
private int _jumpTick;
public LeapAbility(SlimePart slime)
{
super(slime);
_target = UtilPlayer.getRandomTarget(slime.getEntity().getLocation(), 10);
_jumpTick = 20;
// Only attempt to find a target once for this ability!
if (_target == null)
{
setIdle(true);
}
}
@Override
public void tickCustom()
{
if (_target != null)
{
if (getTicks() == _jumpTick)
{
// Jump
Vector dir = UtilAlg.getTrajectory2d(getSlime().getEntity(), _target);
UtilAction.velocity(getSlime().getEntity(), dir, 1, false, 0, 1, 1, true);
}
else if (getTicks() > _jumpTick)
{
if (getSlime().getEntity().isOnGround())
{
setIdle(true);
}
else if (getSlime().isEnraged())
{
World world = getSlime().getEntity().getWorld();
Block block = world.getHighestBlockAt(getSlime().getEntity().getLocation()).getRelative(BlockFace.UP);
if (block.getType() == Material.AIR)
{
block.setType(Material.FIRE);
}
}
}
}
}
}

View File

@ -0,0 +1,149 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
import java.util.Iterator;
import java.util.LinkedList;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.projectile.ProjectileUser;
import mineplex.core.updater.UpdateType;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public class RocketAbility extends SlimeAbility implements IThrown
{
private int _rocketCount;
private int _rocketsFired;
private int _rocketsHit;
private LinkedList<ShotData> _shots;
public RocketAbility(SlimePart slime)
{
this(slime, 5);
}
public RocketAbility(SlimePart slime, int rocketCount)
{
super(slime);
_rocketCount = rocketCount;
_rocketsFired = 0;
_rocketsHit = 0;
_shots = new LinkedList<ShotData>();
}
@Override
public void tickCustom()
{
if (_rocketsHit >= _rocketCount)
{
// We're done here!
setIdle(true);
return;
}
if (_rocketsFired < _rocketCount && getTicks() % 20 == 0)
{
Player target = UtilPlayer.getRandomTarget(getSlime().getEntity().getLocation(), 20);
if (target == null && getTicks() > 20 * (_rocketCount + 10))
{
// Give up on firing more rockets
_rocketCount = _rocketsFired;
}
if (target != null) fireRocket(target);
}
tickRockets();
}
private void tickRockets()
{
Iterator<ShotData> it = _shots.iterator();
while (it.hasNext())
{
ShotData next = it.next();
if (next.getEntity().isDead())
{
it.remove();
}
else
{
Vector v = UtilAlg.getTrajectory(next.getEntity(), next.getTarget());
next.getEntity().setVelocity(v.multiply(new Vector(0.3, 0.1, 0.3)));
}
}
}
private void fireRocket(Player target)
{
Location loc = getSlime().getEntity().getLocation();
loc.add(loc.getDirection().normalize().multiply(2));
Slime projectile = loc.getWorld().spawn(loc, Slime.class);
projectile.setSize(2);
_shots.add(new ShotData(projectile, target));
ProjectileManager pm = getSlime().getBoss().getEventManager().getClans().getProjectile();
pm.AddThrow(projectile, getSlime().getEntity(), this, -1, true, true, true, null, 0, 0, UtilParticle.ParticleType.SLIME, UpdateType.FASTEST, 1F);
Bukkit.broadcastMessage("Shot Slime at target " + target);
_rocketsFired++;
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
Bukkit.broadcastMessage("COLLIDE " + target);
UtilParticle.PlayParticle(UtilParticle.ParticleType.LARGE_EXPLODE, data.GetThrown().getLocation(), 0, 0, 0, 0, 1, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
data.GetThrown().remove();
_rocketsHit++;
}
@Override
public void Idle(ProjectileUser data)
{
}
@Override
public void Expire(ProjectileUser data)
{
}
private static class ShotData
{
private LivingEntity _entity;
private LivingEntity _target;
public ShotData(LivingEntity entity, LivingEntity target)
{
_entity = entity;
_target = target;
}
public LivingEntity getEntity()
{
return _entity;
}
public LivingEntity getTarget()
{
return _target;
}
}
}

View File

@ -0,0 +1,157 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
import java.util.LinkedList;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public class SlamAbility extends SlimeAbility
{
private int _findAttempts;
private boolean _hasTarget;
private int _foundTicks;
private Player _target;
private Location _targetLocation;
// Timings
private final int _lockTick;
private final int _jumpTick;
private final int _diveTick;
public SlamAbility(SlimePart slime)
{
this(slime, 40, 60, 80);
}
public SlamAbility(SlimePart slime, int lockTick, int jumpTick, int diveTick)
{
super(slime);
_hasTarget = false;
_findAttempts = 0;
_foundTicks = 0;
assert (jumpTick > lockTick && diveTick > jumpTick);
_lockTick = lockTick;
_jumpTick = jumpTick;
_diveTick = diveTick;
}
@Override
public void tickCustom()
{
if (!_hasTarget)
{
if (getTicks() % 20 == 0)
{
searchForTarget();
}
}
else
{
int ticks = getTicks() - _foundTicks;
if (ticks < _lockTick)
{
// Follow Target
displayTarget(_target.getLocation());
}
else if (ticks == _lockTick)
{
// Lock on
Bukkit.broadcastMessage("Target Locked");
_targetLocation = _target.getLocation();
}
else if (ticks < _jumpTick)
{
// Target still locked
displayTarget(_targetLocation);
}
else if (ticks == _jumpTick)
{
// Target starts jump
Bukkit.broadcastMessage("Start Jump");
}
else if (ticks > _jumpTick)
{
// Target in air
displayTarget(_targetLocation);
Vector direction = UtilAlg.getTrajectory2d(getSlime().getEntity().getLocation(), _targetLocation);
direction.multiply(0.4);
direction.setY(2 * (1 - ((getTicks() - 100.0) / 60.0)));
getSlime().getEntity().setVelocity(direction);
}
else if (ticks == _diveTick)
{
displayTarget(_targetLocation);
// Time to go down!
getSlime().getEntity().setVelocity(new Vector(0, -3, 0));
getSlime().getEntity().setFallDistance(0);
}
else if (ticks > _diveTick)
{
displayTarget(_targetLocation);
// Check for hitting ground
if (getSlime().getEntity().isOnGround())
{
// We're done here!
setIdle(true);
damageArea(getSlime().getEntity().getLocation());
}
}
}
}
private void damageArea(Location location)
{
// TODO Deal more damage based on how close you are to the slime?
LinkedList<Player> nearPlayers = UtilPlayer.getNearby(location, 4);
for (Player player : nearPlayers)
{
player.damage(4);
player.setVelocity(UtilAlg.getTrajectory2d(location, player.getLocation()).setY(0.2));
}
UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, location, 2, 0.5F, 2, 0, 100, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
location.getWorld().playSound(location, Sound.ANVIL_LAND, 10, 0.5F);
}
private void displayTarget(Location location)
{
UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, location, 0, 0, 0, 0, 1, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers());
}
private void searchForTarget()
{
if (_findAttempts >= 10)
{
// Just give up! THERE'S NO HOPE
setIdle(true);
return;
}
Player target = UtilPlayer.getRandomTarget(getSlime().getEntity().getLocation(), 15);
if (target != null)
{
_target = target;
_hasTarget = true;
_foundTicks = getTicks();
Bukkit.broadcastMessage("Target placed on " + _target);
}
_findAttempts++;
}
}

View File

@ -0,0 +1,56 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.ability;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public abstract class SlimeAbility
{
private SlimePart _slime;
private boolean _idle;
private int _ticks;
private int _idleTicks;
public SlimeAbility(SlimePart slime)
{
_slime = slime;
}
public final void tick()
{
if (isIdle())
{
_idleTicks++;
}
else
{
_ticks++;
tickCustom();
}
}
public int getTicks()
{
return _ticks;
}
public int getIdleTicks()
{
return _idleTicks;
}
public boolean isIdle()
{
return _idle;
}
public SlimePart getSlime()
{
return _slime;
}
public abstract void tickCustom();
protected void setIdle(boolean idle)
{
_idle = idle;
}
}

View File

@ -0,0 +1,172 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.state;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
import mineplex.game.clans.clans.worldevent.event.boss.BossState;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimeBoss;
public class AbsorbState extends BossState
{
private Slime _entity;
private Player _rider;
private int _riderTickCount;
private int _ticksPerPulse;
private int _pulseCount;
private int _maxPulses;
private int _slimeSize;
public AbsorbState(SlimeBoss boss, Slime entity, int ticksPerPulse)
{
super(boss);
_entity = entity;
_pulseCount = 0;
_maxPulses = 10;
_riderTickCount = 0;
_ticksPerPulse = ticksPerPulse;
_slimeSize = entity.getSize();
}
@Override
public void onTick()
{
if (_rider == null)
{
int mod = getTicks() % _ticksPerPulse;
if (_pulseCount < _maxPulses)
{
if (mod == 0)
{
pulse();
_pulseCount++;
_entity.setSize(_slimeSize);
UtilParticle.PlayParticle(UtilParticle.ParticleType.SLIME, _entity.getLocation(), 2F, 2F, 2F, 0, 50, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
_entity.getWorld().playSound(_entity.getLocation(), Sound.SLIME_WALK, 0.5F, 1);
}
else if (mod > _ticksPerPulse - 10)
{
int ticksLeft = _ticksPerPulse - mod;
_entity.setSize(_entity.getSize() + 1);
int count = 20 + (10 - ticksLeft);
for (int i = 0; i < count; i++)
{
double radius = (10 - ticksLeft) * 2;
double q = i / 10.0 * Math.PI;
double x = radius * Math.sin(q);
double z = radius * Math.cos(q);
Location loc = _entity.getLocation().clone();
loc.add(x, 0.2, z);
UtilParticle.PlayParticle(UtilParticle.ParticleType.SLIME, loc, 0.5F, 0.5F, 0.5F, 0, 10, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
}
}
}
// Check rider
if (getTicks() % 5 == 0)
{
Player closest = UtilPlayer.getClosest(_entity.getLocation());
if (closest != null)
{
double dist = closest.getLocation().distance(_entity.getLocation());
if (dist < 5)
{
_entity.setPassenger(closest);
_rider = closest;
}
}
}
}
else
{
_riderTickCount++;
if (_riderTickCount % 20 == 0)
{
getBoss().getDamageManager().NewDamageEvent(_rider, _entity, null, EntityDamageEvent.DamageCause.MAGIC, 2.0,
false, false, false, getBoss().getName(), "Absorb");
}
if (shouldEjectRider())
{
Vector dir = _entity.getLocation().getDirection().normalize();
_entity.eject();
_rider.setVelocity(dir.add(new Vector(0, 0.5, 0)));
_rider = null;
}
}
}
private void pulse()
{
Bukkit.broadcastMessage("Pulse");
List<Player> nearby = UtilPlayer.getNearby(_entity.getLocation(), 20);
for (Player player : nearby)
{
Vector dir = UtilAlg.getTrajectory2d(player, _entity);
dir.setY(0.4);
player.setVelocity(dir);
getBoss().getDamageManager().NewDamageEvent(player, _entity, null, EntityDamageEvent.DamageCause.MAGIC, 1.0,
false, false, false, getBoss().getName(), "Absorb");
}
}
private boolean shouldEjectRider()
{
return _riderTickCount >= 20 * 10;
}
@EventHandler
public void onTarget(EntityTargetEvent event)
{
if (_rider != null)
{
if (event.getEntity().equals(_entity) && event.getTarget().equals(_rider))
event.setCancelled(true);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
if (event.getPlayer().equals(_rider))
_rider = null;
}
@EventHandler
public void onLeave(VehicleExitEvent event)
{
if (event.getExited().equals(_rider) && event.getVehicle().equals(_entity) && !shouldEjectRider())
event.setCancelled(true);
}
@Override
public void onStateStart()
{
}
@Override
public void onStateStop()
{
}
}

View File

@ -0,0 +1,124 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.state;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilServer;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.projectile.ProjectileUser;
import mineplex.core.updater.UpdateType;
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
import mineplex.game.clans.clans.worldevent.event.boss.BossState;
public class RocketState extends BossState implements IThrown
{
private Slime _shooter;
private LinkedList<ShotData> _shots;
private int _projectilesHit;
public RocketState(AbstractBoss boss, Slime shooter)
{
super(boss);
_shooter = shooter;
_shots = new LinkedList<ShotData>();
}
@Override
public void onTick()
{
if (getTicks() % 20 == 0 && getTicks() / 20 < 6)
{
List<Entity> entities = _shooter.getNearbyEntities(20, 20, 20);
for (Entity e : entities)
{
if (e instanceof Player)
{
// Vector v = UtilAlg.getTrajectory(_shooter.getEyeLocation(), e.getLocation());
fireProjectile(((Player) e));
}
}
// fireProjectile(new Vector(x, y, z));
}
if (_projectilesHit == 6)
{
// getBoss().setState(new AbsorbState(getBoss(), ((Slime) _shooter), 20 * 2));
}
}
@Override
public void onStateStart()
{
}
@Override
public void onStateStop()
{
}
private void fireProjectile(LivingEntity target)
{
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
Bukkit.broadcastMessage("COLLIDE " + target);
UtilParticle.PlayParticle(UtilParticle.ParticleType.LARGE_EXPLODE, data.GetThrown().getLocation(), 0, 0, 0, 0, 1, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
data.GetThrown().remove();
_projectilesHit++;
}
@Override
public void Idle(ProjectileUser data)
{
}
@Override
public void Expire(ProjectileUser data)
{
}
private static class ShotData
{
private LivingEntity _entity;
private LivingEntity _target;
public ShotData(LivingEntity entity, LivingEntity target)
{
_entity = entity;
_target = target;
}
public LivingEntity getEntity()
{
return _entity;
}
public LivingEntity getTarget()
{
return _target;
}
}
}

View File

@ -0,0 +1,101 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.state;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss;
import mineplex.game.clans.clans.worldevent.event.boss.BossState;
public class SlamState extends BossState
{
private static final int FOLLOW_TICKS = 60;
private static final int JUMP_TICKS = 80;
private static final int DIVE_TICKS = 20 * 5;
private LivingEntity _entity;
private Player _target;
private Location _targetLocation;
public SlamState(AbstractBoss boss, LivingEntity entity, Player target)
{
super(boss);
_entity = entity;
_target = target;
}
@Override
public void onTick()
{
if (getTicks() < FOLLOW_TICKS)
{
_targetLocation = _target.getLocation();
}
else if (getTicks() == FOLLOW_TICKS)
{
Bukkit.broadcastMessage("TARGET LOCKED");
}
else if (getTicks() == JUMP_TICKS)
{
Bukkit.broadcastMessage("SLIME BOSS JUMPED INTO THE AIR");
}
else if (getTicks() > JUMP_TICKS && getTicks() < DIVE_TICKS)
{
Location loc = _entity.getLocation();
loc.setDirection(loc.toVector().add(_targetLocation.toVector()).normalize());
Vector direction = UtilAlg.getTrajectory2d(_entity.getLocation(), _targetLocation);
direction.multiply(0.4);
direction.setY(2 * (1 - ((getTicks() - 100.0) / 60.0)));
_entity.setVelocity(direction);
}
else if (getTicks() == DIVE_TICKS)
{
_entity.setVelocity(new Vector(0, -3, 0));
}
if (_entity instanceof Creature) ((Creature) _entity).setTarget(_target);
// display particles X
double x = 0.5 * Math.sin(getTicks() / 10.0 * 2 * Math.PI);
double z = 0.5 * Math.cos(getTicks() / 10.0 * 2 * Math.PI);
Location loc = _targetLocation.clone().add(x, 0.1, z);
UtilParticle.PlayParticle(UtilParticle.ParticleType.FIREWORKS_SPARK, loc, 0, 0, 0, 0, 1, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
}
@Override
public void onStateStart()
{
Bukkit.broadcastMessage("Target placed on " + _target.getName());
}
@EventHandler
public void onDamage(EntityDamageEvent event)
{
if (event.getEntity().equals(_entity) && event.getCause() == EntityDamageEvent.DamageCause.FALL)
{
event.setCancelled(true);
}
}
@Override
public void onStateStop()
{
}
}

View File

@ -0,0 +1,51 @@
package mineplex.game.clans.clans.worldevent.event.boss.slime.state;
import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimePart;
public abstract class SlimeState
{
private SlimePart _slime;
private boolean _idle;
private int _ticks;
private int _idleTicks;
public SlimeState(SlimePart slime)
{
_slime = slime;
}
public final void tick()
{
if (isIdle())
{
_idleTicks++;
}
else
{
_ticks++;
tickCustom();
}
}
public int getTicks()
{
return _ticks;
}
public int getIdleTicks()
{
return _idleTicks;
}
public boolean isIdle()
{
return _idle;
}
public abstract void tickCustom();
protected void setIdle(boolean idle)
{
_idle = idle;
}
}

View File

@ -0,0 +1,65 @@
package mineplex.game.clans.clans.worldevent.event.kinghill;
import java.io.File;
import java.io.IOException;
import org.bukkit.Location;
import mineplex.core.common.schematic.Schematic;
import mineplex.core.common.schematic.UtilSchematic;
public class HillData
{
private Schematic _schematic;
private int _hillX;
private int _hillY;
private int _hillZ;
private int _lengthX;
private int _lengthY;
private int _lengthZ;
public HillData(String fileName, int hillX, int hillY, int hillZ, int lengthX, int lengthY, int lengthZ) throws IOException
{
File file = new File("schematic" + File.separator + fileName);
System.out.println(file.getAbsolutePath());
_schematic = UtilSchematic.loadSchematic(file);
_hillX = hillX;
_hillY = hillY;
_hillZ = hillZ;
_lengthX = lengthX;
_lengthY = lengthY;
_lengthZ = lengthZ;
}
public Schematic getSchematic()
{
return _schematic;
}
public boolean isOnHill(Location location, Location eventLocation)
{
if (!location.getWorld().equals(eventLocation.getWorld())) return false;
int minX = eventLocation.getBlockX() + _hillX;
int minY = eventLocation.getBlockY() + _hillY;
int minZ = eventLocation.getBlockZ() + _hillZ;
int maxX = minX + _lengthX;
int maxY = minY + _lengthY;
int maxZ = minZ + _lengthZ;
double x = location.getX();
double y = location.getY();
double z = location.getZ();
return x > minX && y > minY && z > minZ && x < maxX && y < maxY && z < maxZ;
}
public Location getHillCenter(Location eventLocation)
{
Location hill = eventLocation.clone();
hill.add(_hillX, _hillY, _hillZ);
hill.add(_lengthX / 2.0, _lengthY / 2.0, _lengthZ / 2.0);
return hill;
}
}

View File

@ -0,0 +1,111 @@
package mineplex.game.clans.clans.worldevent.event.kinghill;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import mineplex.core.common.schematic.Schematic;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.ClanInfo;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.event.AbstractWorldEvent;
import mineplex.game.clans.economy.GoldManager;
import mineplex.minecraft.game.core.damage.DamageManager;
public class KingHill extends AbstractWorldEvent
{
private static List<HillData> LOADED_HILLS = new ArrayList<HillData>();
static
{
// TODO load hills from schematic folder with extra hill data from a config file?
try
{
LOADED_HILLS.add(new HillData("hill.schematic", 28, 28, 28, 5, 5, 5));
}
catch (IOException e)
{
e.printStackTrace();
}
}
private ClansManager _clansManager;
private HashMap<ClanInfo, CaptureData> _scoreMap;
private HillData _hill;
public KingHill(WorldEventManager eventManager, DamageManager damageManager, Location centerLocation)
{
super(eventManager, damageManager, "King of the Hill", centerLocation);
_clansManager = eventManager.getClans();
_scoreMap = new HashMap<ClanInfo, CaptureData>();
_hill = LOADED_HILLS.get(0);
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage("attempting to spawn in hill... please wait!");
_hill.getSchematic().paste(getCenterLocation());
Bukkit.broadcastMessage("PASTED");
}
@Override
protected void customCancel()
{
}
@Override
protected void customTick()
{
if (getTicks() % 5 == 0)
tickHill();
}
private void tickHill()
{
int clanCount = 0;
ClanInfo lastClan = null;
for (Player player : UtilServer.getPlayers())
{
if (_hill.isOnHill(player.getLocation(), getCenterLocation()))
{
ClanInfo playerClan = _clansManager.getClan(player);
if (playerClan != null)
{
clanCount++;
lastClan = playerClan;
}
}
}
if (clanCount == 1 && lastClan != null)
{
Bukkit.broadcastMessage(lastClan.getName() + " owns the hill!");
CaptureData capData = _scoreMap.get(lastClan);
if (capData == null)
{
capData = new CaptureData();
_scoreMap.put(lastClan, capData);
}
capData.TicksOnHill++;
GoldManager.getInstance().dropGold(_hill.getHillCenter(getCenterLocation()), 20);
}
}
private static class CaptureData
{
public int TicksOnHill;
}
}

View File

@ -1,35 +1,36 @@
package mineplex.game.clans.economy; package mineplex.game.clans.economy;
import java.util.Random; import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.Material;
import org.bukkit.entity.Entity; import org.bukkit.Sound;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.items.economy.GoldToken; import mineplex.game.clans.items.economy.GoldToken;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager; import mineplex.core.account.CoreClientManager;
import mineplex.core.common.CurrencyType;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.creature.Creature;
import mineplex.core.donation.DonationManager; import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor; import mineplex.core.donation.Donor;
import mineplex.core.energy.Energy;
import mineplex.game.clans.Clans;
import mineplex.game.clans.clans.ClansManager; import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.fields.repository.FieldRepository;
import mineplex.game.clans.items.generation.WeightSet;
import mineplex.game.clans.shop.bank.BankShop; import mineplex.game.clans.shop.bank.BankShop;
import mineplex.game.clans.shop.farming.FarmingShop; import mineplex.game.clans.shop.farming.FarmingShop;
import mineplex.game.clans.spawn.travel.TravelButton; import mineplex.game.clans.spawn.travel.TravelButton;
@ -41,12 +42,14 @@ public class GoldManager extends MiniPlugin
{ {
public static final int GEM_CONVERSION_RATE = 50; // The number of gold coins when converted from a single gem public static final int GEM_CONVERSION_RATE = 50; // The number of gold coins when converted from a single gem
public static final double DEATH_TAX = 0.04d; // Percentage of gold lost on death public static final double DEATH_TAX = 0.04d; // Percentage of gold lost on death
public static final String META_STRING = "clans.goldAmount";
private static GoldManager _instance; private static GoldManager _instance;
public static GoldManager getInstance() { return _instance; } public static GoldManager getInstance() { return _instance; }
private DonationManager _donationManager; private DonationManager _donationManager;
private TransferTracker _transferTracker; private TransferTracker _transferTracker;
private Set<Item> _itemSet;
private BankShop _bankShop; private BankShop _bankShop;
public GoldManager(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager) public GoldManager(ClansManager plugin, CoreClientManager clientManager, DonationManager donationManager)
@ -56,6 +59,7 @@ public class GoldManager extends MiniPlugin
_instance = this; _instance = this;
_donationManager = donationManager; _donationManager = donationManager;
_transferTracker = new TransferTracker(); _transferTracker = new TransferTracker();
_itemSet = new HashSet<Item>();
_bankShop = new BankShop(plugin, clientManager, donationManager); _bankShop = new BankShop(plugin, clientManager, donationManager);
new FarmingShop(plugin, clientManager, donationManager); new FarmingShop(plugin, clientManager, donationManager);
new TravelShop(plugin, clientManager, donationManager); new TravelShop(plugin, clientManager, donationManager);
@ -88,10 +92,49 @@ public class GoldManager extends MiniPlugin
{ {
if (event.getMessage().startsWith("/gold")) if (event.getMessage().startsWith("/gold"))
{ {
notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g"); notify(event.getPlayer(), "Your Balance is " + C.cYellow + getGold(event.getPlayer()) + "g");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@EventHandler
public void onPickup(PlayerPickupItemEvent event)
{
if (_itemSet.contains(event.getItem()))
{
event.setCancelled(true);
int goldAmount = 1;
List<MetadataValue> meta = event.getItem().getMetadata(META_STRING);
if (meta != null && meta.size() == 1)
{
goldAmount = meta.get(0).asInt();
}
event.getItem().remove();
event.getPlayer().playSound(event.getPlayer().getEyeLocation(), Sound.ORB_PICKUP, 1F, 2F);
addGold(event.getPlayer(), goldAmount);
}
}
@EventHandler
public void cleanItems(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC) return;
Iterator<Item> itemIterator = _itemSet.iterator();
while (itemIterator.hasNext())
{
Item item = itemIterator.next();
if (!item.isValid() || item.getTicksLived() >= 12000) // 10 minutes
{
item.remove();
itemIterator.remove();
}
}
}
public int getGold(Player player) public int getGold(Player player)
{ {
@ -142,6 +185,28 @@ public class GoldManager extends MiniPlugin
addGold(player, value); addGold(player, value);
notify(player, String.format("You have cashed in a gold token worth %dg!", value)); notify(player, String.format("You have cashed in a gold token worth %dg!", value));
} }
public void dropGold(Location location, int amount)
{
dropGold(location, amount, true, 1);
}
public void dropGold(Location location, int amount, boolean stacking, double velMult)
{
// TODO Stacking
for (int i = 0; i < amount; i++)
{
Item item = location.getWorld().dropItem(location, new ItemStack(Material.GOLD_INGOT));
item.setPickupDelay(40);
item.setMetadata(META_STRING, new FixedMetadataValue(getPlugin(), 1));
// Velocity
double x = Math.random() * 2 * Math.PI;
Vector velocity = new Vector(Math.sin(x), 0, Math.cos(x));
UtilAction.velocity(item, velocity, velMult, false, 0, 0.2, 0.5, false);
}
}
public void purchaseToken(Player player, int tokenValue) public void purchaseToken(Player player, int tokenValue)
{ {

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="craftbukkit" level="project" />
<orderEntry type="module" module-name="Mineplex.Core" />
<orderEntry type="module" module-name="Mineplex.Core.Common" />
</component>
</module>