forked from 2009Scape/Server
Rebase with upstream
This commit is contained in:
commit
101b8314c9
2889 changed files with 481914 additions and 0 deletions
51
09HDscape-server/src/org/crandor/Main Frame.fxml
Normal file
51
09HDscape-server/src/org/crandor/Main Frame.fxml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.PasswordField?>
|
||||
<?import javafx.scene.control.TextArea?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="legendFrame" prefHeight="556.0" prefWidth="694.0" xmlns="http://javafx.com/javafx/8.0.91" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.crandor.tools.panel.Controller">
|
||||
<children>
|
||||
<AnchorPane fx:id="mainFrame" maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="670.0" VBox.vgrow="ALWAYS">
|
||||
<children>
|
||||
<Label layoutX="48.0" layoutY="21.0" prefHeight="26.0" prefWidth="55.0" text="Players">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextArea fx:id="systemLogger" editable="false" layoutX="147.0" layoutY="236.0" prefHeight="148.0" prefWidth="433.0" wrapText="true" />
|
||||
<ComboBox fx:id="punishmentBox" layoutX="149.0" layoutY="47.0" prefWidth="150.0" promptText="Punishments" />
|
||||
<ComboBox fx:id="toolsBox" layoutX="288.0" layoutY="175.0" prefWidth="150.0" promptText="Tools" />
|
||||
<ComboBox fx:id="ranksBox" layoutX="408.0" layoutY="47.0" prefWidth="150.0" promptText="Ranks" />
|
||||
<Label layoutX="338.0" layoutY="216.0" text="Console">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextArea fx:id="playersList" layoutX="14.0" layoutY="47.0" prefHeight="337.0" prefWidth="123.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
||||
<AnchorPane fx:id="vali" maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" VBox.vgrow="ALWAYS">
|
||||
<children>
|
||||
<PasswordField fx:id="validationKey" layoutX="199.0" layoutY="147.0" prefHeight="25.0" prefWidth="243.0" />
|
||||
<Label layoutX="232.0" layoutY="6.0" prefHeight="74.0" prefWidth="178.0" text="Staff Validation">
|
||||
<font>
|
||||
<Font name="Times New Roman" size="27.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="90.0" layoutY="151.0" text="Validation Key :">
|
||||
<font>
|
||||
<Font name="Times New Roman" size="15.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button fx:id="submitButton" layoutX="455.0" layoutY="147.0" mnemonicParsing="false" text="Submit" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</VBox>
|
||||
89
09HDscape-server/src/org/crandor/Main.java
Normal file
89
09HDscape-server/src/org/crandor/Main.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package org.crandor;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import org.crandor.game.system.SystemLogger;
|
||||
import org.crandor.game.system.SystemShutdownHook;
|
||||
import org.crandor.game.system.mysql.SQLManager;
|
||||
import org.crandor.game.world.GameSettings;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.net.NioReactor;
|
||||
import org.crandor.net.amsc.WorldCommunicator;
|
||||
import org.crandor.tools.TimeStamp;
|
||||
import org.crandor.tools.backup.AutoBackup;
|
||||
|
||||
/**
|
||||
* The main class, for those that are unable to read the class' name.
|
||||
* @author Emperor
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public final class Main extends Application {
|
||||
|
||||
/**
|
||||
* The time stamp of when the server started running.
|
||||
*/
|
||||
public static long startTime;
|
||||
|
||||
/**
|
||||
* The NIO reactor.
|
||||
*/
|
||||
public static NioReactor reactor;
|
||||
|
||||
private static AutoBackup backup;
|
||||
|
||||
/**
|
||||
* The main method, in this method we load background utilities such as
|
||||
* cache and our world, then end with starting networking.
|
||||
* @param args The arguments cast on runtime.
|
||||
* @throws Throwable When an exception occurs.
|
||||
*/
|
||||
public static void main(String... args) throws Throwable {
|
||||
if (args.length > 0) {
|
||||
GameWorld.setSettings(GameSettings.parse(args));
|
||||
}
|
||||
// if (GameWorld.getSettings().isGui()) {
|
||||
// KeldagrimFrame.getInstance().init();
|
||||
// }
|
||||
startTime = System.currentTimeMillis();
|
||||
final TimeStamp t = new TimeStamp();
|
||||
backup = new AutoBackup();
|
||||
GameWorld.prompt(true);
|
||||
SQLManager.init();
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(new SystemShutdownHook()));
|
||||
SystemLogger.log("Starting NIO reactor...");
|
||||
reactor = NioReactor.configure(43594 + GameWorld.getSettings().getWorldId());
|
||||
WorldCommunicator.connect();
|
||||
reactor.start();
|
||||
SystemLogger.log(GameWorld.getName() + " flags " + GameWorld.getSettings().toString());
|
||||
SystemLogger.log(GameWorld.getName() + " started in " + t.duration(false, "") + " milliseconds.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the startTime.
|
||||
* @return the startTime
|
||||
*/
|
||||
public static long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bastartTime.
|
||||
* @param startTime the startTime to set.
|
||||
*/
|
||||
public static void setStartTime(long startTime) {
|
||||
Main.startTime = startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Parent root = FXMLLoader.load(getClass().getResource("Main Frame.fxml"));
|
||||
primaryStage.setTitle("Management Panel");
|
||||
primaryStage.setScene(new Scene(root, 600, 450));
|
||||
primaryStage.show();
|
||||
}
|
||||
}
|
||||
98
09HDscape-server/src/org/crandor/ServerConstants.java
Normal file
98
09HDscape-server/src/org/crandor/ServerConstants.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
package org.crandor;
|
||||
|
||||
import org.crandor.game.system.mysql.SQLManager;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.tools.mysql.Database;
|
||||
|
||||
/**
|
||||
* A class holding constants of the server.
|
||||
* @author Emperor
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public final class ServerConstants {
|
||||
|
||||
/**
|
||||
* The administrators.
|
||||
*/
|
||||
public static final String[] ADMINISTRATORS = {
|
||||
"torv",
|
||||
"austin",
|
||||
};
|
||||
|
||||
/**
|
||||
* The cache path.
|
||||
*/
|
||||
public static final String CACHE_PATH = "data/cache/";
|
||||
|
||||
/**
|
||||
* The store path.
|
||||
*/
|
||||
public static final String STORE_PATH = "data/store/";
|
||||
|
||||
/**
|
||||
* The player account path.
|
||||
*/
|
||||
public static final String PLAYER_SAVE_PATH = "data/players/";
|
||||
|
||||
/**
|
||||
* The maximum amount of players.
|
||||
*/
|
||||
public static final int MAX_PLAYERS = (1 << 11) - 1;
|
||||
|
||||
/**
|
||||
* The maximum amount of NPCs.
|
||||
*/
|
||||
public static final int MAX_NPCS = (1 << 15) - 1;
|
||||
|
||||
/**
|
||||
* The start location for a fresh account.
|
||||
*/
|
||||
public static final Location START_LOCATION = Location.create(3088, 3491, 0);
|
||||
|
||||
/**
|
||||
* The main home teleport location.
|
||||
*/
|
||||
public static final Location HOME_LOCATION = Location.create(3088, 3491, 0);
|
||||
|
||||
/**
|
||||
* The teleport destinations.
|
||||
*/
|
||||
public static final Object[][] TELEPORT_DESTINATIONS = { { Location.create(2974, 4383, 2), "corp", "corporal", "corporeal" }, { Location.create(2659, 2649, 0), "pc", "pest control", "pest" }, { Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid" }, { Location.create(3222, 3217, 0), "lumbridge", "lumby" }, { Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards" }, { Location.create(3083, 3249, 0), "draynor", "draynor village" }, { Location.create(3019, 3244, 0), "port sarim", "sarim" }, { Location.create(2956, 3209, 0), "rimmington" }, { Location.create(2965, 3380, 0), "fally", "falador" }, { Location.create(2895, 3436, 0), "taverly" }, { Location.create(3080, 3423, 0), "barbarian village", "barb" }, { Location.create(3213, 3428, 0), "varrock" }, { Location.create(3164, 3485, 0), "grand exchange", "ge" }, { Location.create(2917, 3175, 0), "karamja" }, { Location.create(2450, 5165, 0), "tzhaar" }, { Location.create(2795, 3177, 0), "brimhaven" }, { Location.create(2849, 2961, 0), "shilo village", "shilo" }, { Location.create(2605, 3093, 0), "yanille" }, { Location.create(2663, 3305, 0), "ardougne", "ardy" }, { Location.create(2450, 3422, 0), "gnome stronghold", "gnome" }, { Location.create(2730, 3485, 0), "camelot", "cammy", "seers" }, { Location.create(2805, 3435, 0), "catherby" }, { Location.create(2659, 3657, 0), "rellekka" }, { Location.create(2890, 3676, 0), "trollheim" }, { Location.create(2914, 3746, 0), "godwars", "gwd", "god wars" }, { Location.create(3180, 3684, 0), "bounty hunter", "bh" }, { Location.create(3272, 3687, 0), "clan wars", "clw" }, { Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena" }, { Location.create(3069, 10257, 0), "king black dragon", "kbd" }, { Location.create(3359, 3416, 0), "digsite" }, { Location.create(3488, 3489, 0), "canifis" }, { Location.create(3428, 3526, 0), "slayer tower", "slayer" }, { Location.create(3502, 9483, 2), "kalphite queen", "kq", "kalphite hive", "kalphite" }, { Location.create(3233, 2913, 0), "pyramid" }, { Location.create(3419, 2917, 0), "nardah" }, { Location.create(3482, 3090, 0), "uzer" }, { Location.create(3358, 2970, 0), "pollnivneach", "poln" }, { Location.create(3305, 2788, 0), "sophanem" }, { Location.create(2898, 3544, 0), "burthorpe", "burthorp" }, { Location.create(3088, 3491, 0), "edge", "edgeville" }, { Location.create(3169, 3034, 0), "bedabin" }, { Location.create(3565, 3289, 0), "barrows" } };
|
||||
|
||||
/**
|
||||
* The teleport destinations, intended for Grandpa Jack.
|
||||
*/
|
||||
public static final Object[][] TELEPORT_DESTINATIONS_DONATOR = { {Location.create(2914, 3746, 0), "godwars", "gwd", "god wars"}, { Location.create(2659, 2649, 0), "pc", "pest control", "pest" }, { Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid" }, { Location.create(3222, 3217, 0), "lumbridge", "lumby" }, { Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards" }, { Location.create(3083, 3249, 0), "draynor", "draynor village" }, { Location.create(3019, 3244, 0), "port sarim", "sarim" }, { Location.create(2956, 3209, 0), "rimmington" }, { Location.create(2965, 3380, 0), "fally", "falador" }, { Location.create(2895, 3436, 0), "taverly" }, { Location.create(3080, 3423, 0), "barbarian village", "barb" }, { Location.create(3213, 3428, 0), "varrock" }, { Location.create(3164, 3485, 0), "grand exchange", "ge" }, { Location.create(2917, 3175, 0), "karamja" }, { Location.create(2450, 5165, 0), "tzhaar" }, { Location.create(2795, 3177, 0), "brimhaven" }, { Location.create(2849, 2961, 0), "shilo village", "shilo" }, { Location.create(2605, 3093, 0), "yanille" }, { Location.create(2663, 3305, 0), "ardougne", "ardy" }, { Location.create(2450, 3422, 0), "gnome stronghold", "gnome" }, { Location.create(2730, 3485, 0), "camelot", "cammy", "seers" }, { Location.create(2805, 3435, 0), "catherby" }, { Location.create(2659, 3657, 0), "rellekka" }, { Location.create(2890, 3676, 0), "trollheim" }, { Location.create(3180, 3684, 0), "bounty hunter", "bh" }, { Location.create(3272, 3687, 0), "clan wars", "clw" }, { Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena" }, { Location.create(3359, 3416, 0), "digsite" }, { Location.create(3488, 3489, 0), "canifis" }, { Location.create(3428, 3526, 0), "slayer tower", "slayer" }, { Location.create(3233, 2913, 0), "pyramid" }, { Location.create(3419, 2917, 0), "nardah" }, { Location.create(3482, 3090, 0), "uzer" }, { Location.create(3358, 2970, 0), "pollnivneach", "poln" }, { Location.create(3305, 2788, 0), "sophanem" }, { Location.create(2898, 3544, 0), "burthorpe", "burthorp" }, { Location.create(3088, 3491, 0), "edge", "edgeville" }, { Location.create(3169, 3034, 0), "bedabin" }, { Location.create(3565, 3311, 0), "barrows" } };
|
||||
|
||||
/**
|
||||
* The string of donation messages displayed on an interface.
|
||||
*/
|
||||
public static final String[] MESSAGES = new String[] {"Donations on Keldagrim are different than those elsewhere.", "Here we use a perk system.", "There are many different type of perks that can be bought to", "speed up efficiency, but nothing game breaking. By doing this", "we provide players with ways to support Keldagrim, in a manner" , "that doesn't ruin the economy or provide substantial advantages.", "If you would like to check out our perks please visit", "keldagrim.com/donate/." };
|
||||
|
||||
public static final String[] DATABASE_NAMES = {
|
||||
"keldagr1_server", "keldagr1_global"
|
||||
};
|
||||
|
||||
public static final Database[] DATABASES = {
|
||||
new Database((SQLManager.LOCAL ? "localhost" : "keldagrim.org"), (SQLManager.LOCAL ? "server" : DATABASE_NAMES[0]), (SQLManager.LOCAL ? "root" : "keldagr1_user"), (SQLManager.LOCAL ? "" : "2jf4wkz$")),
|
||||
new Database((SQLManager.LOCAL ? "localhost" : "keldagrim.org"), (SQLManager.LOCAL ? "global" : DATABASE_NAMES[1]), (SQLManager.LOCAL ? "root" : "keldagr1_user"), (SQLManager.LOCAL ? "" : "2jf4wkz$"))
|
||||
};
|
||||
|
||||
/**
|
||||
* If MySQL is enabled.
|
||||
*/
|
||||
public static boolean MYSQL = true;
|
||||
|
||||
public static boolean VALIDATED = false;
|
||||
|
||||
/**
|
||||
* Constructs a new {@Code ServerConstants} {@Code Object}
|
||||
*/
|
||||
private ServerConstants() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
218
09HDscape-server/src/org/crandor/cache/Cache.java
vendored
Normal file
218
09HDscape-server/src/org/crandor/cache/Cache.java
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
package org.crandor.cache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.crandor.ServerConstants;
|
||||
import org.crandor.cache.def.impl.AnimationDefinition;
|
||||
import org.crandor.cache.def.impl.GraphicDefinition;
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.cache.def.impl.NPCDefinition;
|
||||
import org.crandor.cache.def.impl.ObjectDefinition;
|
||||
import org.crandor.game.system.SystemLogger;
|
||||
|
||||
/**
|
||||
* A cache reader.
|
||||
* @author Emperor
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public final class Cache {
|
||||
|
||||
/**
|
||||
* The cache file manager.
|
||||
*/
|
||||
private static CacheFileManager[] cacheFileManagers;
|
||||
|
||||
/**
|
||||
* The container cache file informer.
|
||||
*/
|
||||
private static CacheFile referenceFile;
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*/
|
||||
private Cache(String location) {
|
||||
try {
|
||||
init(location);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cache reader.
|
||||
* @param path The cache path.x
|
||||
* @throws Throwable When an exception occurs.
|
||||
*/
|
||||
public static final void init(String path) throws Throwable {
|
||||
SystemLogger.log("Initializing cache...");
|
||||
byte[] cacheFileBuffer = new byte[520];
|
||||
RandomAccessFile containersInformFile = new RandomAccessFile(path + "/main_file_cache.idx255", "r");
|
||||
RandomAccessFile dataFile = new RandomAccessFile(path + "/main_file_cache.dat2", "r");
|
||||
referenceFile = new CacheFile(255, containersInformFile, dataFile, 500000, cacheFileBuffer);
|
||||
int length = (int) (containersInformFile.length() / 6);
|
||||
cacheFileManagers = new CacheFileManager[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
File f = new File(path + "/main_file_cache.idx" + i);
|
||||
if (f.exists() && f.length() > 0) {
|
||||
cacheFileManagers[i] = new CacheFileManager(new CacheFile(i, new RandomAccessFile(f, "r"), dataFile, 1000000, cacheFileBuffer), true);
|
||||
if (cacheFileManagers[i].getInformation() == null) {
|
||||
System.out.println("Error loading cache index " + i + ": no information.");
|
||||
cacheFileManagers[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemDefinition.parse();
|
||||
ObjectDefinition.parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cache.
|
||||
*/
|
||||
public static void init() {
|
||||
try {
|
||||
init(ServerConstants.CACHE_PATH);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the archive buffer for the grab requests.
|
||||
* @param index The index id.
|
||||
* @param archive The archive id.
|
||||
* @param priority The priority.
|
||||
* @param encryptionValue The current encryption value.
|
||||
* @return The byte buffer.
|
||||
*/
|
||||
public static ByteBuffer getArchiveData(int index, int archive, boolean priority, int encryptionValue) {
|
||||
byte[] data = index == 255 ? referenceFile.getContainerData(archive) : cacheFileManagers[index].getCacheFile().getContainerData(archive);
|
||||
if (data == null || data.length < 1) {
|
||||
System.err.println("Invalid JS-5 request - " + index + ", " + archive + ", " + priority + ", " + encryptionValue + "!");
|
||||
return null;
|
||||
}
|
||||
int compression = data[0] & 0xff;
|
||||
int length = ((data[1] & 0xff) << 24) + ((data[2] & 0xff) << 16) + ((data[3] & 0xff) << 8) + (data[4] & 0xff);
|
||||
int settings = compression;
|
||||
if (!priority) {
|
||||
settings |= 0x80;
|
||||
}
|
||||
int realLength = compression != 0 ? length + 4 : length;
|
||||
ByteBuffer buffer = ByteBuffer.allocate((realLength + 5) + (realLength / 512) + 10);
|
||||
buffer.put((byte) index);
|
||||
buffer.putShort((short) archive);
|
||||
buffer.put((byte) settings);
|
||||
buffer.putInt(length);
|
||||
for (int i = 5; i < realLength + 5; i++) {
|
||||
if (buffer.position() % 512 == 0) {
|
||||
buffer.put((byte) 255);
|
||||
}
|
||||
buffer.put(data[i]);
|
||||
}
|
||||
if (encryptionValue != 0) {
|
||||
for (int i = 0; i < buffer.position(); i++) {
|
||||
buffer.put(i, (byte) (buffer.get(i) ^ encryptionValue));
|
||||
}
|
||||
}
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the reference data for the cache files.
|
||||
* @return The reference data byte array.
|
||||
*/
|
||||
public static final byte[] generateReferenceData() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(cacheFileManagers.length * 8);
|
||||
for (int index = 0; index < cacheFileManagers.length; index++) {
|
||||
if (cacheFileManagers[index] == null) {
|
||||
buffer.putInt(index == 24 ? 609698396 : 0);
|
||||
buffer.putInt(0);
|
||||
continue;
|
||||
}
|
||||
buffer.putInt(cacheFileManagers[index].getInformation().getInformationContainer().getCrc());
|
||||
buffer.putInt(cacheFileManagers[index].getInformation().getRevision());
|
||||
}
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache file managers.
|
||||
* @return The cache file managers.
|
||||
*/
|
||||
public static final CacheFileManager[] getIndexes() {
|
||||
return cacheFileManagers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container cache file informer.
|
||||
* @return The container cache file informer.
|
||||
*/
|
||||
public static final CacheFile getReferenceFile() {
|
||||
return referenceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the component size of the interface.
|
||||
* @param interfaceId the interface.
|
||||
* @return the value.
|
||||
*/
|
||||
public static final int getInterfaceDefinitionsComponentsSize(int interfaceId) {
|
||||
return getIndexes()[3].getFilesSize(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the max size of the interface definitions.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getInterfaceDefinitionsSize() {
|
||||
return getIndexes()[3].getContainersSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the {@link NPCDefinition} size.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getNPCDefinitionsSize() {
|
||||
int lastContainerId = getIndexes()[18].getContainersSize() - 1;
|
||||
return lastContainerId * 128 + getIndexes()[18].getFilesSize(lastContainerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the {@link GraphicDefinition} size.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getGraphicDefinitionsSize() {
|
||||
int lastContainerId = getIndexes()[21].getContainersSize() - 1;
|
||||
return lastContainerId * 256 + getIndexes()[21].getFilesSize(lastContainerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the {@link AnimationDefinition} size.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getAnimationDefinitionsSize() {
|
||||
int lastContainerId = getIndexes()[20].getContainersSize() - 1;
|
||||
return lastContainerId * 128 + getIndexes()[20].getFilesSize(lastContainerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the {@link ObjectDefinition} size.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getObjectDefinitionsSize() {
|
||||
int lastContainerId = getIndexes()[16].getContainersSize() - 1;
|
||||
return lastContainerId * 256 + getIndexes()[16].getFilesSize(lastContainerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to return the item definition size.
|
||||
* @return the size.
|
||||
*/
|
||||
public static final int getItemDefinitionsSize() {
|
||||
int lastContainerId = getIndexes()[19].getContainersSize() - 1;
|
||||
return lastContainerId * 256 + getIndexes()[19].getFilesSize(lastContainerId);
|
||||
}
|
||||
|
||||
}
|
||||
148
09HDscape-server/src/org/crandor/cache/CacheFile.java
vendored
Normal file
148
09HDscape-server/src/org/crandor/cache/CacheFile.java
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package org.crandor.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.crandor.cache.crypto.XTEACryption;
|
||||
import org.crandor.cache.misc.ContainersInformation;
|
||||
|
||||
/**
|
||||
* A cache file.
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public final class CacheFile {
|
||||
|
||||
/**
|
||||
* The index file id.
|
||||
*/
|
||||
private int indexFileId;
|
||||
|
||||
/**
|
||||
* The cache file buffer.
|
||||
*/
|
||||
private byte[] cacheFileBuffer;
|
||||
|
||||
/**
|
||||
* The maximum container size.
|
||||
*/
|
||||
private int maxContainerSize;
|
||||
|
||||
/**
|
||||
* The index file.
|
||||
*/
|
||||
private RandomAccessFile indexFile;
|
||||
|
||||
/**
|
||||
* The data file.
|
||||
*/
|
||||
private RandomAccessFile dataFile;
|
||||
|
||||
/**
|
||||
* Construct a new cache file.
|
||||
* @param indexFileId The index file id.
|
||||
* @param indexFile The index file.
|
||||
* @param dataFile The data file.
|
||||
* @param maxContainerSize The maximum container size.
|
||||
* @param cacheFileBuffer The cache file buffer.
|
||||
*/
|
||||
public CacheFile(int indexFileId, RandomAccessFile indexFile, RandomAccessFile dataFile, int maxContainerSize, byte[] cacheFileBuffer) {
|
||||
this.cacheFileBuffer = cacheFileBuffer;
|
||||
this.indexFileId = indexFileId;
|
||||
this.maxContainerSize = maxContainerSize;
|
||||
this.indexFile = indexFile;
|
||||
this.dataFile = dataFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unpacked container data.
|
||||
* @param containerId The container id.
|
||||
* @param xteaKeys The container keys.
|
||||
* @return The unpacked container data.
|
||||
*/
|
||||
public final byte[] getContainerUnpackedData(int containerId, int[] xteaKeys) {
|
||||
byte[] packedData = getContainerData(containerId);
|
||||
if (packedData == null) {
|
||||
return null;
|
||||
}
|
||||
if (xteaKeys != null && (xteaKeys[0] != 0 || xteaKeys[1] != 0 || xteaKeys[2] != 0 || xteaKeys[3] != 0)) {
|
||||
packedData = XTEACryption.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array();
|
||||
}
|
||||
return ContainersInformation.unpackCacheContainer(packedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container data for the specified container id.
|
||||
* @param containerId The container id.
|
||||
* @return The container data.
|
||||
*/
|
||||
public final byte[] getContainerData(int containerId) {
|
||||
synchronized (dataFile) {
|
||||
try {
|
||||
if (indexFile.length() < (6 * containerId + 6)) {
|
||||
return null;
|
||||
}
|
||||
indexFile.seek(6 * containerId);
|
||||
indexFile.read(cacheFileBuffer, 0, 6);
|
||||
int containerSize = (cacheFileBuffer[2] & 0xff) + (((0xff & cacheFileBuffer[0]) << 16) + (cacheFileBuffer[1] << 8 & 0xff00));
|
||||
int sector = ((cacheFileBuffer[3] & 0xff) << 16) - (-(0xff00 & cacheFileBuffer[4] << 8) - (cacheFileBuffer[5] & 0xff));
|
||||
if (containerSize < 0 || containerSize > maxContainerSize) {
|
||||
return null;
|
||||
}
|
||||
if (sector <= 0 || dataFile.length() / 520L < sector) {
|
||||
return null;
|
||||
}
|
||||
byte data[] = new byte[containerSize];
|
||||
int dataReadCount = 0;
|
||||
int part = 0;
|
||||
while (containerSize > dataReadCount) {
|
||||
if (sector == 0) {
|
||||
return null;
|
||||
}
|
||||
dataFile.seek(520 * sector);
|
||||
int dataToReadCount = containerSize - dataReadCount;
|
||||
if (dataToReadCount > 512) {
|
||||
dataToReadCount = 512;
|
||||
}
|
||||
dataFile.read(cacheFileBuffer, 0, 8 + dataToReadCount);
|
||||
int currentContainerId = (0xff & cacheFileBuffer[1]) + (0xff00 & cacheFileBuffer[0] << 8);
|
||||
int currentPart = ((cacheFileBuffer[2] & 0xff) << 8) + (0xff & cacheFileBuffer[3]);
|
||||
int nextSector = (cacheFileBuffer[6] & 0xff) + (0xff00 & cacheFileBuffer[5] << 8) + ((0xff & cacheFileBuffer[4]) << 16);
|
||||
int currentIndexFileId = cacheFileBuffer[7] & 0xff;
|
||||
if (containerId != currentContainerId || currentPart != part || indexFileId != currentIndexFileId) {
|
||||
return null;
|
||||
}
|
||||
if (nextSector < 0 || (dataFile.length() / 520L) < nextSector) {
|
||||
return null;
|
||||
}
|
||||
for (int index = 0; dataToReadCount > index; index++) {
|
||||
data[dataReadCount++] = cacheFileBuffer[8 + index];
|
||||
}
|
||||
part++;
|
||||
sector = nextSector;
|
||||
}
|
||||
return data;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index file id.
|
||||
* @return
|
||||
*/
|
||||
public int getIndexFileId() {
|
||||
return indexFileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unpacked container data.
|
||||
* @param containerId The container id.
|
||||
* @return The unpacked container data.
|
||||
*/
|
||||
public final byte[] getContainerUnpackedData(int containerId) {
|
||||
return getContainerUnpackedData(containerId, null);
|
||||
}
|
||||
}
|
||||
293
09HDscape-server/src/org/crandor/cache/CacheFileManager.java
vendored
Normal file
293
09HDscape-server/src/org/crandor/cache/CacheFileManager.java
vendored
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
package org.crandor.cache;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.crandor.cache.misc.ContainersInformation;
|
||||
import org.crandor.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* A cache file manager.
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public final class CacheFileManager {
|
||||
|
||||
/**
|
||||
* The cache file.
|
||||
*/
|
||||
private CacheFile cacheFile;
|
||||
|
||||
/**
|
||||
* The containers information.
|
||||
*/
|
||||
private ContainersInformation information;
|
||||
|
||||
/**
|
||||
* Discard a files data.
|
||||
*/
|
||||
private boolean discardFilesData;
|
||||
|
||||
/**
|
||||
* A array holding file data.
|
||||
*/
|
||||
private byte[][][] filesData;
|
||||
|
||||
/**
|
||||
* Construct a new cache file manager.
|
||||
* @param cacheFile The cache file.
|
||||
* @param discardFilesData To discard a files data.
|
||||
*/
|
||||
public CacheFileManager(CacheFile cacheFile, boolean discardFilesData) {
|
||||
this.cacheFile = cacheFile;
|
||||
this.discardFilesData = discardFilesData;
|
||||
byte[] informContainerPackedData = Cache.getReferenceFile().getContainerData(cacheFile.getIndexFileId());
|
||||
if (informContainerPackedData == null) {
|
||||
return;
|
||||
}
|
||||
information = new ContainersInformation(informContainerPackedData);
|
||||
resetFilesData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache file.
|
||||
* @return The cache file.
|
||||
*/
|
||||
public CacheFile getCacheFile() {
|
||||
return cacheFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the containers size.
|
||||
* @return The containers size.
|
||||
*/
|
||||
public int getContainersSize() {
|
||||
return information.getContainers().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the files size.
|
||||
* @param containerId The container id.
|
||||
* @return The files size.
|
||||
*/
|
||||
public int getFilesSize(int containerId) {
|
||||
if (!validContainer(containerId)) {
|
||||
return -1;
|
||||
}
|
||||
return information.getContainers()[containerId].getFiles().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the file data.
|
||||
*/
|
||||
public void resetFilesData() {
|
||||
filesData = new byte[information.getContainers().length][][];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid.
|
||||
* @param containerId The container id.
|
||||
* @param fileId The file id.
|
||||
* @return If the file is valid {@code true}.
|
||||
*/
|
||||
public boolean validFile(int containerId, int fileId) {
|
||||
if (!validContainer(containerId)) {
|
||||
return false;
|
||||
}
|
||||
if (fileId < 0 || information.getContainers()[containerId] == null || information.getContainers()[containerId].getFiles().length <= fileId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* If a container is valid.
|
||||
* @param containerId The container id.
|
||||
* @return If the container is valid {@code true}.
|
||||
*/
|
||||
public boolean validContainer(int containerId) {
|
||||
if (containerId < 0 || information.getContainers().length <= containerId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file ids.
|
||||
* @param containerId The container id.
|
||||
* @return The file ids.
|
||||
*/
|
||||
public int[] getFileIds(int containerId) {
|
||||
if (!validContainer(containerId)) {
|
||||
return null;
|
||||
}
|
||||
return information.getContainers()[containerId].getFilesIndexes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the archive id.
|
||||
* @param name The archive name.
|
||||
* @return The archive id.
|
||||
*/
|
||||
public int getArchiveId(String name) {
|
||||
if (name == null) {
|
||||
return -1;
|
||||
}
|
||||
int hash = StringUtils.getNameHash(name);
|
||||
for (int containerIndex = 0; containerIndex < information.getContainersIndexes().length; containerIndex++) {
|
||||
if (information.getContainers()[information.getContainersIndexes()[containerIndex]].getNameHash() == hash) {
|
||||
return information.getContainersIndexes()[containerIndex];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file data.
|
||||
* @param containerId The container id.
|
||||
* @param fileId The file id.
|
||||
* @return The get file data.
|
||||
*/
|
||||
public byte[] getFileData(int containerId, int fileId) {
|
||||
return getFileData(containerId, fileId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the file data.
|
||||
* @param archiveId The container id.
|
||||
* @param keys The container keys.
|
||||
* @return If the file data is loaded {@code true}.
|
||||
*/
|
||||
public boolean loadFilesData(int archiveId, int[] keys) {
|
||||
byte[] data = cacheFile.getContainerUnpackedData(archiveId, keys);
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
if (filesData[archiveId] == null) {
|
||||
if (information.getContainers()[archiveId] == null) {
|
||||
return false; // container inform doesnt exist anymore
|
||||
}
|
||||
filesData[archiveId] = new byte[information.getContainers()[archiveId].getFiles().length][];
|
||||
}
|
||||
if (information.getContainers()[archiveId].getFilesIndexes().length == 1) {
|
||||
int fileId = information.getContainers()[archiveId].getFilesIndexes()[0];
|
||||
filesData[archiveId][fileId] = data;
|
||||
} else {
|
||||
int readPosition = data.length;
|
||||
int amtOfLoops = data[--readPosition] & 0xff;
|
||||
readPosition -= amtOfLoops * (information.getContainers()[archiveId].getFilesIndexes().length * 4);
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
int filesSize[] = new int[information.getContainers()[archiveId].getFilesIndexes().length];
|
||||
buffer.position(readPosition);
|
||||
for (int loop = 0; loop < amtOfLoops; loop++) {
|
||||
int offset = 0;
|
||||
for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) {
|
||||
filesSize[fileIndex] += offset += buffer.getInt();
|
||||
}
|
||||
}
|
||||
byte[][] filesBufferData = new byte[information.getContainers()[archiveId].getFilesIndexes().length][];
|
||||
for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) {
|
||||
filesBufferData[fileIndex] = new byte[filesSize[fileIndex]];
|
||||
filesSize[fileIndex] = 0;
|
||||
}
|
||||
buffer.position(readPosition);
|
||||
int sourceOffset = 0;
|
||||
for (int loop = 0; loop < amtOfLoops; loop++) {
|
||||
int dataRead = 0;
|
||||
for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) {
|
||||
dataRead += buffer.getInt();
|
||||
System.arraycopy(data, sourceOffset, filesBufferData[fileIndex], filesSize[fileIndex], dataRead);
|
||||
sourceOffset += dataRead;
|
||||
filesSize[fileIndex] += dataRead;
|
||||
}
|
||||
}
|
||||
for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) {
|
||||
filesData[archiveId][information.getContainers()[archiveId].getFilesIndexes()[fileIndex]] = filesBufferData[fileIndex];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file data.
|
||||
* @param containerId The container id.
|
||||
* @param fileId The file id.
|
||||
* @param xteaKeys The container keys.
|
||||
* @return The file data.
|
||||
*/
|
||||
public byte[] getFileData(int containerId, int fileId, int[] xteaKeys) {
|
||||
if (!validFile(containerId, fileId)) {
|
||||
return null;
|
||||
}
|
||||
if (filesData[containerId] == null || filesData[containerId][fileId] == null) {
|
||||
if (!loadFilesData(containerId, xteaKeys)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
byte[] data = filesData[containerId][fileId];
|
||||
if (discardFilesData) {
|
||||
if (filesData[containerId].length == 1) {
|
||||
filesData[containerId] = null;
|
||||
} else {
|
||||
filesData[containerId][fileId] = null;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the containers information.
|
||||
* @return The containers information.
|
||||
*/
|
||||
public ContainersInformation getInformation() {
|
||||
return information;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the discardFilesData.
|
||||
* @return the discardFilesData.
|
||||
*/
|
||||
public boolean isDiscardFilesData() {
|
||||
return discardFilesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the discardFilesData.
|
||||
* @param discardFilesData the discardFilesData to set
|
||||
*/
|
||||
public void setDiscardFilesData(boolean discardFilesData) {
|
||||
this.discardFilesData = discardFilesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filesData.
|
||||
* @return the filesData.
|
||||
*/
|
||||
public byte[][][] getFilesData() {
|
||||
return filesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filesData.
|
||||
* @param filesData the filesData to set
|
||||
*/
|
||||
public void setFilesData(byte[][][] filesData) {
|
||||
this.filesData = filesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cacheFile.
|
||||
* @param cacheFile the cacheFile to set
|
||||
*/
|
||||
public void setCacheFile(CacheFile cacheFile) {
|
||||
this.cacheFile = cacheFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the information.
|
||||
* @param information the information to set
|
||||
*/
|
||||
public void setInformation(ContainersInformation information) {
|
||||
this.information = information;
|
||||
}
|
||||
}
|
||||
193
09HDscape-server/src/org/crandor/cache/ServerStore.java
vendored
Normal file
193
09HDscape-server/src/org/crandor/cache/ServerStore.java
vendored
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
package org.crandor.cache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.cache.misc.buffer.ByteBufferUtils;
|
||||
|
||||
/**
|
||||
* The server data storage.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ServerStore {
|
||||
|
||||
/**
|
||||
* The storage.
|
||||
*/
|
||||
private static Map<String, StoreFile> storage = new HashMap<>();
|
||||
|
||||
/**
|
||||
* If the store has initialized.
|
||||
*/
|
||||
private static boolean initialized;
|
||||
|
||||
/**
|
||||
* Initializes the store.
|
||||
* @param path The file path.
|
||||
*/
|
||||
public static void init(String path) {
|
||||
storage = new HashMap<>();
|
||||
File file = new File(path + "/dynamic_cache.keldagrim");
|
||||
if (file.exists()) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
|
||||
FileChannel channel = raf.getChannel();
|
||||
ByteBuffer buffer = channel.map(MapMode.READ_WRITE, 0, channel.size());
|
||||
int size = buffer.getShort() & 0xFFFF;
|
||||
for (int i = 0; i < size; i++) {
|
||||
StoreFile store = new StoreFile();
|
||||
store.setDynamic(true);
|
||||
String archive = ByteBufferUtils.getString(buffer);
|
||||
byte[] data = new byte[buffer.getInt()];
|
||||
buffer.get(data);
|
||||
store.setData(data);
|
||||
storage.put(archive, store);
|
||||
}
|
||||
if (buffer.hasRemaining()) {
|
||||
throw new IllegalStateException("Unable to read all dynamic data (size=" + size + ")!");
|
||||
}
|
||||
channel.close();
|
||||
raf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for writing the static store.
|
||||
* @param path The path.
|
||||
*/
|
||||
public static void createStaticStore(String path) {
|
||||
write(path + "/static_cache.keldagrim", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes all the dynamic storage files (on server termination).
|
||||
* @param path The path.
|
||||
*/
|
||||
public static void dump(String path) {
|
||||
write(path + "/dynamic_cache.keldagrim", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the store file to the given file path.
|
||||
* @param filePath The file path.
|
||||
* @param dynamic If the dynamic store is being written.
|
||||
*/
|
||||
public static void write(String filePath, boolean dynamic) {
|
||||
if (!initialized) {
|
||||
throw new IllegalStateException("Server store has not been initialized!");
|
||||
}
|
||||
File f = new File(filePath);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1 << 28);
|
||||
buffer.putShort((short) 0);
|
||||
int size = 0;
|
||||
for (String archive : storage.keySet()) {
|
||||
StoreFile file = storage.get(archive);
|
||||
if (file.isDynamic() != dynamic) {
|
||||
continue;
|
||||
}
|
||||
size++;
|
||||
ByteBuffer buf = file.data();
|
||||
ByteBufferUtils.putString(archive, buffer);
|
||||
buffer.putInt(buf.remaining());
|
||||
buffer.put(buf);
|
||||
}
|
||||
buffer.putShort(0, (short) size);
|
||||
buffer.flip();
|
||||
try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
|
||||
FileChannel channel = raf.getChannel();
|
||||
channel.write(buffer);
|
||||
channel.close();
|
||||
raf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the archive data.
|
||||
* @param archive The archive id.
|
||||
* @param buffer The readable buffer.
|
||||
*/
|
||||
public static void setArchive(String archive, ByteBuffer buffer) {
|
||||
setArchive(archive, buffer, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the archive data.
|
||||
* @param archive The archive id.
|
||||
* @param buffer The readable buffer.
|
||||
* @param dynamic If the data changes during server runtime.
|
||||
*/
|
||||
public static void setArchive(String archive, ByteBuffer buffer, boolean dynamic) {
|
||||
byte[] data = new byte[buffer.remaining()];
|
||||
buffer.get(data);
|
||||
setArchive(archive, data, dynamic, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the archive data.
|
||||
* @param archive The archive index.
|
||||
* @param data The archive data.
|
||||
* @param dynamic If the data changes during server runtime.
|
||||
*/
|
||||
public static void setArchive(String archive, byte[] data, boolean dynamic) {
|
||||
setArchive(archive, data, dynamic, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the archive data.
|
||||
* @param archive The archive index.
|
||||
* @param data The archive data.
|
||||
* @param dynamic If the data changes during server runtime.
|
||||
* @param overwrite If the archive should be overwritten.
|
||||
*/
|
||||
public static void setArchive(String archive, byte[] data, boolean dynamic, boolean overwrite) {
|
||||
StoreFile file = storage.get(archive);
|
||||
if (file == null) {
|
||||
storage.put(archive, file = new StoreFile());
|
||||
} else if (!overwrite) {
|
||||
throw new IllegalStateException("Already contained archive " + archive + "!");
|
||||
}
|
||||
file.setDynamic(dynamic);
|
||||
file.setData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the archive data for the given archive id.
|
||||
* @param archive The archive index.
|
||||
* @return The archive data.
|
||||
*/
|
||||
public static ByteBuffer getArchive(String archive) {
|
||||
return get(archive).data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the archive file.
|
||||
* @param archive The archive.
|
||||
* @param file The file.
|
||||
*/
|
||||
public static void set(String archive, StoreFile file) {
|
||||
storage.put(archive, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the store file for the given archive.
|
||||
* @param archive The archive id.
|
||||
* @return The store file.
|
||||
*/
|
||||
public static StoreFile get(String archive) {
|
||||
return storage.get(archive);
|
||||
}
|
||||
}
|
||||
72
09HDscape-server/src/org/crandor/cache/StoreFile.java
vendored
Normal file
72
09HDscape-server/src/org/crandor/cache/StoreFile.java
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package org.crandor.cache;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Represents a file used in the server store.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class StoreFile {
|
||||
|
||||
/**
|
||||
* If the data can change during server runtime.
|
||||
*/
|
||||
private boolean dynamic;
|
||||
|
||||
/**
|
||||
* The file data.
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StoreFile} {@code Object}.
|
||||
*/
|
||||
public StoreFile() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the data on the buffer.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void put(ByteBuffer buffer) {
|
||||
byte[] data = new byte[buffer.remaining()];
|
||||
buffer.get(data);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a byte buffer containing the file data.
|
||||
* @return The buffer.
|
||||
*/
|
||||
public ByteBuffer data() {
|
||||
return ByteBuffer.wrap(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data.
|
||||
* @param data The data.
|
||||
*/
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dynamic.
|
||||
* @return The dynamic.
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dynamic.
|
||||
* @param dynamic The dynamic to set.
|
||||
*/
|
||||
public void setDynamic(boolean dynamic) {
|
||||
this.dynamic = dynamic;
|
||||
}
|
||||
|
||||
}
|
||||
56
09HDscape-server/src/org/crandor/cache/bzip2/BZip2BlockEntry.java
vendored
Normal file
56
09HDscape-server/src/org/crandor/cache/bzip2/BZip2BlockEntry.java
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
package org.crandor.cache.bzip2;
|
||||
|
||||
public class BZip2BlockEntry {
|
||||
|
||||
boolean aBooleanArray2205[];
|
||||
boolean aBooleanArray2213[];
|
||||
byte aByte2201;
|
||||
byte aByteArray2204[];
|
||||
byte aByteArray2211[];
|
||||
byte aByteArray2212[];
|
||||
byte aByteArray2214[];
|
||||
byte aByteArray2219[];
|
||||
byte aByteArray2224[];
|
||||
byte aByteArrayArray2229[][];
|
||||
int anInt2202;
|
||||
int anInt2203;
|
||||
int anInt2206;
|
||||
int anInt2207;
|
||||
int anInt2208;
|
||||
int anInt2209;
|
||||
int anInt2215;
|
||||
int anInt2216;
|
||||
int anInt2217;
|
||||
int anInt2221;
|
||||
int anInt2222;
|
||||
int anInt2223;
|
||||
int anInt2225;
|
||||
int anInt2227;
|
||||
int anInt2232;
|
||||
int anIntArray2200[];
|
||||
int anIntArray2220[];
|
||||
int anIntArray2226[];
|
||||
int anIntArray2228[];
|
||||
int anIntArrayArray2210[][];
|
||||
int anIntArrayArray2218[][];
|
||||
int anIntArrayArray2230[][];
|
||||
|
||||
public BZip2BlockEntry() {
|
||||
anIntArray2200 = new int[6];
|
||||
anInt2203 = 0;
|
||||
aByteArray2204 = new byte[4096];
|
||||
aByteArray2211 = new byte[256];
|
||||
aByteArray2214 = new byte[18002];
|
||||
aByteArray2219 = new byte[18002];
|
||||
anIntArray2220 = new int[257];
|
||||
anIntArrayArray2218 = new int[6][258];
|
||||
aBooleanArray2205 = new boolean[16];
|
||||
aBooleanArray2213 = new boolean[256];
|
||||
anInt2209 = 0;
|
||||
anIntArray2226 = new int[16];
|
||||
anIntArrayArray2210 = new int[6][258];
|
||||
aByteArrayArray2229 = new byte[6][258];
|
||||
anIntArrayArray2230 = new int[6][258];
|
||||
anIntArray2228 = new int[256];
|
||||
}
|
||||
}
|
||||
536
09HDscape-server/src/org/crandor/cache/bzip2/BZip2Decompressor.java
vendored
Normal file
536
09HDscape-server/src/org/crandor/cache/bzip2/BZip2Decompressor.java
vendored
Normal file
|
|
@ -0,0 +1,536 @@
|
|||
package org.crandor.cache.bzip2;
|
||||
|
||||
public class BZip2Decompressor {
|
||||
|
||||
private static int anIntArray257[];
|
||||
private static BZip2BlockEntry entryInstance = new BZip2BlockEntry();
|
||||
|
||||
public static final void decompress(byte decompressedData[], byte packedData[], int containerSize, int blockSize) {
|
||||
synchronized (entryInstance) {
|
||||
entryInstance.aByteArray2224 = packedData;
|
||||
entryInstance.anInt2209 = blockSize;
|
||||
entryInstance.aByteArray2212 = decompressedData;
|
||||
entryInstance.anInt2203 = 0;
|
||||
entryInstance.anInt2206 = decompressedData.length;
|
||||
entryInstance.anInt2232 = 0;
|
||||
entryInstance.anInt2207 = 0;
|
||||
entryInstance.anInt2217 = 0;
|
||||
entryInstance.anInt2216 = 0;
|
||||
method1793(entryInstance);
|
||||
entryInstance.aByteArray2224 = null;
|
||||
entryInstance.aByteArray2212 = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final void method1785(BZip2BlockEntry entry) {
|
||||
entry.anInt2215 = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (entry.aBooleanArray2213[i]) {
|
||||
entry.aByteArray2211[entry.anInt2215] = (byte) i;
|
||||
entry.anInt2215++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final void method1786(int ai[], int ai1[], int ai2[], byte abyte0[], int i, int j, int k) {
|
||||
int l = 0;
|
||||
for (int i1 = i; i1 <= j; i1++) {
|
||||
for (int l2 = 0; l2 < k; l2++) {
|
||||
if (abyte0[l2] == i1) {
|
||||
ai2[l] = l2;
|
||||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < 23; j1++) {
|
||||
ai1[j1] = 0;
|
||||
}
|
||||
|
||||
for (int k1 = 0; k1 < k; k1++) {
|
||||
ai1[abyte0[k1] + 1]++;
|
||||
}
|
||||
|
||||
for (int l1 = 1; l1 < 23; l1++) {
|
||||
ai1[l1] += ai1[l1 - 1];
|
||||
}
|
||||
|
||||
for (int i2 = 0; i2 < 23; i2++) {
|
||||
ai[i2] = 0;
|
||||
}
|
||||
|
||||
int i3 = 0;
|
||||
for (int j2 = i; j2 <= j; j2++) {
|
||||
i3 += ai1[j2 + 1] - ai1[j2];
|
||||
ai[j2] = i3 - 1;
|
||||
i3 <<= 1;
|
||||
}
|
||||
|
||||
for (int k2 = i + 1; k2 <= j; k2++) {
|
||||
ai1[k2] = (ai[k2 - 1] + 1 << 1) - ai1[k2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final void method1787(BZip2BlockEntry entry) {
|
||||
byte byte4 = entry.aByte2201;
|
||||
int i = entry.anInt2222;
|
||||
int j = entry.anInt2227;
|
||||
int k = entry.anInt2221;
|
||||
int ai[] = anIntArray257;
|
||||
int l = entry.anInt2208;
|
||||
byte abyte0[] = entry.aByteArray2212;
|
||||
int i1 = entry.anInt2203;
|
||||
int j1 = entry.anInt2206;
|
||||
int k1 = j1;
|
||||
int l1 = entry.anInt2225 + 1;
|
||||
label0: do {
|
||||
if (i > 0) {
|
||||
do {
|
||||
if (j1 == 0) {
|
||||
break label0;
|
||||
}
|
||||
if (i == 1) {
|
||||
break;
|
||||
}
|
||||
abyte0[i1] = byte4;
|
||||
i--;
|
||||
i1++;
|
||||
j1--;
|
||||
} while (true);
|
||||
if (j1 == 0) {
|
||||
i = 1;
|
||||
break;
|
||||
}
|
||||
abyte0[i1] = byte4;
|
||||
i1++;
|
||||
j1--;
|
||||
}
|
||||
boolean flag = true;
|
||||
while (flag) {
|
||||
flag = false;
|
||||
if (j == l1) {
|
||||
i = 0;
|
||||
break label0;
|
||||
}
|
||||
byte4 = (byte) k;
|
||||
l = ai[l];
|
||||
byte byte0 = (byte) (l & 0xff);
|
||||
l >>= 8;
|
||||
j++;
|
||||
if (byte0 != k) {
|
||||
k = byte0;
|
||||
if (j1 == 0) {
|
||||
i = 1;
|
||||
} else {
|
||||
abyte0[i1] = byte4;
|
||||
i1++;
|
||||
j1--;
|
||||
flag = true;
|
||||
continue;
|
||||
}
|
||||
break label0;
|
||||
}
|
||||
if (j != l1) {
|
||||
continue;
|
||||
}
|
||||
if (j1 == 0) {
|
||||
i = 1;
|
||||
break label0;
|
||||
}
|
||||
abyte0[i1] = byte4;
|
||||
i1++;
|
||||
j1--;
|
||||
flag = true;
|
||||
}
|
||||
i = 2;
|
||||
l = ai[l];
|
||||
byte byte1 = (byte) (l & 0xff);
|
||||
l >>= 8;
|
||||
if (++j != l1) {
|
||||
if (byte1 != k) {
|
||||
k = byte1;
|
||||
} else {
|
||||
i = 3;
|
||||
l = ai[l];
|
||||
byte byte2 = (byte) (l & 0xff);
|
||||
l >>= 8;
|
||||
if (++j != l1) {
|
||||
if (byte2 != k) {
|
||||
k = byte2;
|
||||
} else {
|
||||
l = ai[l];
|
||||
byte byte3 = (byte) (l & 0xff);
|
||||
l >>= 8;
|
||||
j++;
|
||||
i = (byte3 & 0xff) + 4;
|
||||
l = ai[l];
|
||||
k = (byte) (l & 0xff);
|
||||
l >>= 8;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
entry.anInt2216 += k1 - j1;
|
||||
entry.aByte2201 = byte4;
|
||||
entry.anInt2222 = i;
|
||||
entry.anInt2227 = j;
|
||||
entry.anInt2221 = k;
|
||||
anIntArray257 = ai;
|
||||
entry.anInt2208 = l;
|
||||
entry.aByteArray2212 = abyte0;
|
||||
entry.anInt2203 = i1;
|
||||
entry.anInt2206 = j1;
|
||||
}
|
||||
|
||||
private static final byte method1788(BZip2BlockEntry entry) {
|
||||
return (byte) method1790(1, entry);
|
||||
}
|
||||
|
||||
private static final byte method1789(BZip2BlockEntry entryInstance2) {
|
||||
return (byte) method1790(8, entryInstance2);
|
||||
}
|
||||
|
||||
private static final int method1790(int i, BZip2BlockEntry entry) {
|
||||
int j;
|
||||
do {
|
||||
if (entry.anInt2232 >= i) {
|
||||
int k = entry.anInt2207 >> entry.anInt2232 - i & (1 << i) - 1;
|
||||
entry.anInt2232 -= i;
|
||||
j = k;
|
||||
break;
|
||||
}
|
||||
entry.anInt2207 = entry.anInt2207 << 8 | entry.aByteArray2224[entry.anInt2209] & 0xff;
|
||||
entry.anInt2232 += 8;
|
||||
entry.anInt2209++;
|
||||
entry.anInt2217++;
|
||||
} while (true);
|
||||
return j;
|
||||
}
|
||||
|
||||
public static void clearBlockEntryInstance() {
|
||||
entryInstance = null;
|
||||
}
|
||||
|
||||
private static final void method1793(BZip2BlockEntry entryInstance2) {
|
||||
// unused
|
||||
/*
|
||||
* boolean flag = false; boolean flag1 = false; boolean flag2 = false;
|
||||
* boolean flag3 = false; boolean flag4 = false; boolean flag5 = false;
|
||||
* boolean flag6 = false; boolean flag7 = false; boolean flag8 = false;
|
||||
* boolean flag9 = false; boolean flag10 = false; boolean flag11 =
|
||||
* false; boolean flag12 = false; boolean flag13 = false; boolean flag14
|
||||
* = false; boolean flag15 = false; boolean flag16 = false; boolean
|
||||
* flag17 = false;
|
||||
*/
|
||||
int j8 = 0;
|
||||
int ai[] = null;
|
||||
int ai1[] = null;
|
||||
int ai2[] = null;
|
||||
entryInstance2.anInt2202 = 1;
|
||||
if (anIntArray257 == null) {
|
||||
anIntArray257 = new int[entryInstance2.anInt2202 * 0x186a0];
|
||||
}
|
||||
boolean flag18 = true;
|
||||
while (flag18) {
|
||||
byte byte0 = method1789(entryInstance2);
|
||||
if (byte0 == 23) {
|
||||
return;
|
||||
}
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1789(entryInstance2);
|
||||
byte0 = method1788(entryInstance2);
|
||||
entryInstance2.anInt2223 = 0;
|
||||
byte0 = method1789(entryInstance2);
|
||||
entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff;
|
||||
byte0 = method1789(entryInstance2);
|
||||
entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff;
|
||||
byte0 = method1789(entryInstance2);
|
||||
entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff;
|
||||
for (int j = 0; j < 16; j++) {
|
||||
byte byte1 = method1788(entryInstance2);
|
||||
if (byte1 == 1) {
|
||||
entryInstance2.aBooleanArray2205[j] = true;
|
||||
} else {
|
||||
entryInstance2.aBooleanArray2205[j] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < 256; k++) {
|
||||
entryInstance2.aBooleanArray2213[k] = false;
|
||||
}
|
||||
|
||||
for (int l = 0; l < 16; l++) {
|
||||
if (entryInstance2.aBooleanArray2205[l]) {
|
||||
for (int i3 = 0; i3 < 16; i3++) {
|
||||
byte byte2 = method1788(entryInstance2);
|
||||
if (byte2 == 1) {
|
||||
entryInstance2.aBooleanArray2213[l * 16 + i3] = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
method1785(entryInstance2);
|
||||
int i4 = entryInstance2.anInt2215 + 2;
|
||||
int j4 = method1790(3, entryInstance2);
|
||||
int k4 = method1790(15, entryInstance2);
|
||||
for (int i1 = 0; i1 < k4; i1++) {
|
||||
int j3 = 0;
|
||||
do {
|
||||
byte byte3 = method1788(entryInstance2);
|
||||
if (byte3 == 0) {
|
||||
break;
|
||||
}
|
||||
j3++;
|
||||
} while (true);
|
||||
entryInstance2.aByteArray2214[i1] = (byte) j3;
|
||||
}
|
||||
|
||||
byte abyte0[] = new byte[6];
|
||||
for (byte byte16 = 0; byte16 < j4; byte16++) {
|
||||
abyte0[byte16] = byte16;
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < k4; j1++) {
|
||||
byte byte17 = entryInstance2.aByteArray2214[j1];
|
||||
byte byte15 = abyte0[byte17];
|
||||
for (; byte17 > 0; byte17--) {
|
||||
abyte0[byte17] = abyte0[byte17 - 1];
|
||||
}
|
||||
|
||||
abyte0[0] = byte15;
|
||||
entryInstance2.aByteArray2219[j1] = byte15;
|
||||
}
|
||||
|
||||
for (int k3 = 0; k3 < j4; k3++) {
|
||||
int k6 = method1790(5, entryInstance2);
|
||||
for (int k1 = 0; k1 < i4; k1++) {
|
||||
do {
|
||||
byte byte4 = method1788(entryInstance2);
|
||||
if (byte4 == 0) {
|
||||
break;
|
||||
}
|
||||
byte4 = method1788(entryInstance2);
|
||||
if (byte4 == 0) {
|
||||
k6++;
|
||||
} else {
|
||||
k6--;
|
||||
}
|
||||
} while (true);
|
||||
entryInstance2.aByteArrayArray2229[k3][k1] = (byte) k6;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int l3 = 0; l3 < j4; l3++) {
|
||||
byte byte8 = 32;
|
||||
int i = 0;
|
||||
for (int l1 = 0; l1 < i4; l1++) {
|
||||
if (entryInstance2.aByteArrayArray2229[l3][l1] > i) {
|
||||
i = entryInstance2.aByteArrayArray2229[l3][l1];
|
||||
}
|
||||
if (entryInstance2.aByteArrayArray2229[l3][l1] < byte8) {
|
||||
byte8 = entryInstance2.aByteArrayArray2229[l3][l1];
|
||||
}
|
||||
}
|
||||
|
||||
method1786(entryInstance2.anIntArrayArray2230[l3], entryInstance2.anIntArrayArray2218[l3], entryInstance2.anIntArrayArray2210[l3], entryInstance2.aByteArrayArray2229[l3], byte8, i, i4);
|
||||
entryInstance2.anIntArray2200[l3] = byte8;
|
||||
}
|
||||
|
||||
int l4 = entryInstance2.anInt2215 + 1;
|
||||
int i5 = -1;
|
||||
int j5 = 0;
|
||||
for (int i2 = 0; i2 <= 255; i2++) {
|
||||
entryInstance2.anIntArray2228[i2] = 0;
|
||||
}
|
||||
|
||||
int i9 = 4095;
|
||||
for (int k8 = 15; k8 >= 0; k8--) {
|
||||
for (int l8 = 15; l8 >= 0; l8--) {
|
||||
entryInstance2.aByteArray2204[i9] = (byte) (k8 * 16 + l8);
|
||||
i9--;
|
||||
}
|
||||
|
||||
entryInstance2.anIntArray2226[k8] = i9 + 1;
|
||||
}
|
||||
|
||||
int l5 = 0;
|
||||
if (j5 == 0) {
|
||||
i5++;
|
||||
j5 = 50;
|
||||
byte byte12 = entryInstance2.aByteArray2219[i5];
|
||||
j8 = entryInstance2.anIntArray2200[byte12];
|
||||
ai = entryInstance2.anIntArrayArray2230[byte12];
|
||||
ai2 = entryInstance2.anIntArrayArray2210[byte12];
|
||||
ai1 = entryInstance2.anIntArrayArray2218[byte12];
|
||||
}
|
||||
j5--;
|
||||
int l6 = j8;
|
||||
int k7;
|
||||
byte byte9;
|
||||
for (k7 = method1790(l6, entryInstance2); k7 > ai[l6]; k7 = k7 << 1 | byte9) {
|
||||
l6++;
|
||||
byte9 = method1788(entryInstance2);
|
||||
}
|
||||
|
||||
for (int k5 = ai2[k7 - ai1[l6]]; k5 != l4;) {
|
||||
if (k5 == 0 || k5 == 1) {
|
||||
int i6 = -1;
|
||||
int j6 = 1;
|
||||
do {
|
||||
if (k5 == 0) {
|
||||
i6 += j6;
|
||||
} else if (k5 == 1) {
|
||||
i6 += 2 * j6;
|
||||
}
|
||||
j6 *= 2;
|
||||
if (j5 == 0) {
|
||||
i5++;
|
||||
j5 = 50;
|
||||
byte byte13 = entryInstance2.aByteArray2219[i5];
|
||||
j8 = entryInstance2.anIntArray2200[byte13];
|
||||
ai = entryInstance2.anIntArrayArray2230[byte13];
|
||||
ai2 = entryInstance2.anIntArrayArray2210[byte13];
|
||||
ai1 = entryInstance2.anIntArrayArray2218[byte13];
|
||||
}
|
||||
j5--;
|
||||
int i7 = j8;
|
||||
int l7;
|
||||
byte byte10;
|
||||
for (l7 = method1790(i7, entryInstance2); l7 > ai[i7]; l7 = l7 << 1 | byte10) {
|
||||
i7++;
|
||||
byte10 = method1788(entryInstance2);
|
||||
}
|
||||
|
||||
k5 = ai2[l7 - ai1[i7]];
|
||||
} while (k5 == 0 || k5 == 1);
|
||||
i6++;
|
||||
byte byte5 = entryInstance2.aByteArray2211[entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[0]] & 0xff];
|
||||
entryInstance2.anIntArray2228[byte5 & 0xff] += i6;
|
||||
for (; i6 > 0; i6--) {
|
||||
anIntArray257[l5] = byte5 & 0xff;
|
||||
l5++;
|
||||
}
|
||||
|
||||
} else {
|
||||
int i11 = k5 - 1;
|
||||
byte byte6;
|
||||
if (i11 < 16) {
|
||||
int i10 = entryInstance2.anIntArray2226[0];
|
||||
byte6 = entryInstance2.aByteArray2204[i10 + i11];
|
||||
for (; i11 > 3; i11 -= 4) {
|
||||
int j11 = i10 + i11;
|
||||
entryInstance2.aByteArray2204[j11] = entryInstance2.aByteArray2204[j11 - 1];
|
||||
entryInstance2.aByteArray2204[j11 - 1] = entryInstance2.aByteArray2204[j11 - 2];
|
||||
entryInstance2.aByteArray2204[j11 - 2] = entryInstance2.aByteArray2204[j11 - 3];
|
||||
entryInstance2.aByteArray2204[j11 - 3] = entryInstance2.aByteArray2204[j11 - 4];
|
||||
}
|
||||
|
||||
for (; i11 > 0; i11--) {
|
||||
entryInstance2.aByteArray2204[i10 + i11] = entryInstance2.aByteArray2204[(i10 + i11) - 1];
|
||||
}
|
||||
|
||||
entryInstance2.aByteArray2204[i10] = byte6;
|
||||
} else {
|
||||
int k10 = i11 / 16;
|
||||
int l10 = i11 % 16;
|
||||
int j10 = entryInstance2.anIntArray2226[k10] + l10;
|
||||
byte6 = entryInstance2.aByteArray2204[j10];
|
||||
for (; j10 > entryInstance2.anIntArray2226[k10]; j10--) {
|
||||
entryInstance2.aByteArray2204[j10] = entryInstance2.aByteArray2204[j10 - 1];
|
||||
}
|
||||
|
||||
entryInstance2.anIntArray2226[k10]++;
|
||||
for (; k10 > 0; k10--) {
|
||||
entryInstance2.anIntArray2226[k10]--;
|
||||
entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[k10]] = entryInstance2.aByteArray2204[(entryInstance2.anIntArray2226[k10 - 1] + 16) - 1];
|
||||
}
|
||||
|
||||
entryInstance2.anIntArray2226[0]--;
|
||||
entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[0]] = byte6;
|
||||
if (entryInstance2.anIntArray2226[0] == 0) {
|
||||
int l9 = 4095;
|
||||
for (int j9 = 15; j9 >= 0; j9--) {
|
||||
for (int k9 = 15; k9 >= 0; k9--) {
|
||||
entryInstance2.aByteArray2204[l9] = entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[j9] + k9];
|
||||
l9--;
|
||||
}
|
||||
|
||||
entryInstance2.anIntArray2226[j9] = l9 + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
entryInstance2.anIntArray2228[entryInstance2.aByteArray2211[byte6 & 0xff] & 0xff]++;
|
||||
anIntArray257[l5] = entryInstance2.aByteArray2211[byte6 & 0xff] & 0xff;
|
||||
l5++;
|
||||
if (j5 == 0) {
|
||||
i5++;
|
||||
j5 = 50;
|
||||
byte byte14 = entryInstance2.aByteArray2219[i5];
|
||||
j8 = entryInstance2.anIntArray2200[byte14];
|
||||
ai = entryInstance2.anIntArrayArray2230[byte14];
|
||||
ai2 = entryInstance2.anIntArrayArray2210[byte14];
|
||||
ai1 = entryInstance2.anIntArrayArray2218[byte14];
|
||||
}
|
||||
j5--;
|
||||
int j7 = j8;
|
||||
int i8;
|
||||
byte byte11;
|
||||
for (i8 = method1790(j7, entryInstance2); i8 > ai[j7]; i8 = i8 << 1 | byte11) {
|
||||
j7++;
|
||||
byte11 = method1788(entryInstance2);
|
||||
}
|
||||
|
||||
k5 = ai2[i8 - ai1[j7]];
|
||||
}
|
||||
}
|
||||
|
||||
entryInstance2.anInt2222 = 0;
|
||||
entryInstance2.aByte2201 = 0;
|
||||
entryInstance2.anIntArray2220[0] = 0;
|
||||
for (int j2 = 1; j2 <= 256; j2++) {
|
||||
entryInstance2.anIntArray2220[j2] = entryInstance2.anIntArray2228[j2 - 1];
|
||||
}
|
||||
|
||||
for (int k2 = 1; k2 <= 256; k2++) {
|
||||
entryInstance2.anIntArray2220[k2] += entryInstance2.anIntArray2220[k2 - 1];
|
||||
}
|
||||
|
||||
for (int l2 = 0; l2 < l5; l2++) {
|
||||
byte byte7 = (byte) (anIntArray257[l2] & 0xff);
|
||||
anIntArray257[entryInstance2.anIntArray2220[byte7 & 0xff]] |= l2 << 8;
|
||||
entryInstance2.anIntArray2220[byte7 & 0xff]++;
|
||||
}
|
||||
|
||||
entryInstance2.anInt2208 = anIntArray257[entryInstance2.anInt2223] >> 8;
|
||||
entryInstance2.anInt2227 = 0;
|
||||
entryInstance2.anInt2208 = anIntArray257[entryInstance2.anInt2208];
|
||||
entryInstance2.anInt2221 = (byte) (entryInstance2.anInt2208 & 0xff);
|
||||
entryInstance2.anInt2208 >>= 8;
|
||||
entryInstance2.anInt2227++;
|
||||
entryInstance2.anInt2225 = l5;
|
||||
method1787(entryInstance2);
|
||||
if (entryInstance2.anInt2227 == entryInstance2.anInt2225 + 1 && entryInstance2.anInt2222 == 0) {
|
||||
flag18 = true;
|
||||
} else {
|
||||
flag18 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
271
09HDscape-server/src/org/crandor/cache/crypto/ISAACCipher.java
vendored
Normal file
271
09HDscape-server/src/org/crandor/cache/crypto/ISAACCipher.java
vendored
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
package org.crandor.cache.crypto;
|
||||
|
||||
/**
|
||||
* <p> An implementation of an ISAAC cipher. See <a
|
||||
* href="http://en.wikipedia.org/wiki/ISAAC_(cipher)">
|
||||
* http://en.wikipedia.org/wiki/ISAAC_(cipher)</a> for more information. </p>
|
||||
* <p> This implementation is based on the one written by Bob Jenkins, which is
|
||||
* available at <a href="http://www.burtleburtle.net/bob/java/rand/Rand.java">
|
||||
* http://www.burtleburtle.net/bob/java/rand/Rand.java</a>. </p>
|
||||
* @author Graham Edgecombe
|
||||
*/
|
||||
public class ISAACCipher {
|
||||
|
||||
/**
|
||||
* The golden ratio.
|
||||
*/
|
||||
public static final int RATIO = 0x9e3779b9;
|
||||
|
||||
/**
|
||||
* The log of the size of the results and memory arrays.
|
||||
*/
|
||||
public static final int SIZE_LOG = 8;
|
||||
|
||||
/**
|
||||
* The size of the results and memory arrays.
|
||||
*/
|
||||
public static final int SIZE = 1 << SIZE_LOG;
|
||||
|
||||
/**
|
||||
* For pseudorandom lookup.
|
||||
*/
|
||||
public static final int MASK = (SIZE - 1) << 2;
|
||||
|
||||
/**
|
||||
* The count through the results.
|
||||
*/
|
||||
private int count = 0;
|
||||
|
||||
/**
|
||||
* The results.
|
||||
*/
|
||||
private int results[] = new int[SIZE];
|
||||
|
||||
/**
|
||||
* The internal memory state.
|
||||
*/
|
||||
private int memory[] = new int[SIZE];
|
||||
|
||||
/**
|
||||
* The accumulator.
|
||||
*/
|
||||
private int a;
|
||||
|
||||
/**
|
||||
* The last result.
|
||||
*/
|
||||
private int b;
|
||||
|
||||
/**
|
||||
* The counter.
|
||||
*/
|
||||
private int c;
|
||||
|
||||
/**
|
||||
* Creates the ISAAC cipher.
|
||||
* @param seed The seed.
|
||||
*/
|
||||
public ISAACCipher(int[] seed) {
|
||||
for (int i = 0; i < seed.length; i++) {
|
||||
results[i] = seed[i];
|
||||
}
|
||||
init(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next value.
|
||||
* @return The next value.
|
||||
*/
|
||||
public int getNextValue() {
|
||||
if (count-- == 0) {
|
||||
isaac();
|
||||
count = SIZE - 1;
|
||||
}
|
||||
return results[count];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates 256 results.
|
||||
*/
|
||||
public void isaac() {
|
||||
int i, j, x, y;
|
||||
b += ++c;
|
||||
for (i = 0, j = SIZE / 2; i < SIZE / 2;) {
|
||||
x = memory[i];
|
||||
a ^= a << 13;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a >>> 6;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a << 2;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a >>> 16;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
}
|
||||
for (j = 0; j < SIZE / 2;) {
|
||||
x = memory[i];
|
||||
a ^= a << 13;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a >>> 6;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a << 2;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
|
||||
x = memory[i];
|
||||
a ^= a >>> 16;
|
||||
a += memory[j++];
|
||||
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
|
||||
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the ISAAC.
|
||||
* @param flag Flag indicating if we should perform a second pass.
|
||||
*/
|
||||
public void init(boolean flag) {
|
||||
int i;
|
||||
int a, b, c, d, e, f, g, h;
|
||||
a = b = c = d = e = f = g = h = RATIO;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a ^= b << 11;
|
||||
d += a;
|
||||
b += c;
|
||||
b ^= c >>> 2;
|
||||
e += b;
|
||||
c += d;
|
||||
c ^= d << 8;
|
||||
f += c;
|
||||
d += e;
|
||||
d ^= e >>> 16;
|
||||
g += d;
|
||||
e += f;
|
||||
e ^= f << 10;
|
||||
h += e;
|
||||
f += g;
|
||||
f ^= g >>> 4;
|
||||
a += f;
|
||||
g += h;
|
||||
g ^= h << 8;
|
||||
b += g;
|
||||
h += a;
|
||||
h ^= a >>> 9;
|
||||
c += h;
|
||||
a += b;
|
||||
}
|
||||
for (i = 0; i < SIZE; i += 8) {
|
||||
if (flag) {
|
||||
a += results[i];
|
||||
b += results[i + 1];
|
||||
c += results[i + 2];
|
||||
d += results[i + 3];
|
||||
e += results[i + 4];
|
||||
f += results[i + 5];
|
||||
g += results[i + 6];
|
||||
h += results[i + 7];
|
||||
}
|
||||
a ^= b << 11;
|
||||
d += a;
|
||||
b += c;
|
||||
b ^= c >>> 2;
|
||||
e += b;
|
||||
c += d;
|
||||
c ^= d << 8;
|
||||
f += c;
|
||||
d += e;
|
||||
d ^= e >>> 16;
|
||||
g += d;
|
||||
e += f;
|
||||
e ^= f << 10;
|
||||
h += e;
|
||||
f += g;
|
||||
f ^= g >>> 4;
|
||||
a += f;
|
||||
g += h;
|
||||
g ^= h << 8;
|
||||
b += g;
|
||||
h += a;
|
||||
h ^= a >>> 9;
|
||||
c += h;
|
||||
a += b;
|
||||
memory[i] = a;
|
||||
memory[i + 1] = b;
|
||||
memory[i + 2] = c;
|
||||
memory[i + 3] = d;
|
||||
memory[i + 4] = e;
|
||||
memory[i + 5] = f;
|
||||
memory[i + 6] = g;
|
||||
memory[i + 7] = h;
|
||||
}
|
||||
if (flag) {
|
||||
for (i = 0; i < SIZE; i += 8) {
|
||||
a += memory[i];
|
||||
b += memory[i + 1];
|
||||
c += memory[i + 2];
|
||||
d += memory[i + 3];
|
||||
e += memory[i + 4];
|
||||
f += memory[i + 5];
|
||||
g += memory[i + 6];
|
||||
h += memory[i + 7];
|
||||
a ^= b << 11;
|
||||
d += a;
|
||||
b += c;
|
||||
b ^= c >>> 2;
|
||||
e += b;
|
||||
c += d;
|
||||
c ^= d << 8;
|
||||
f += c;
|
||||
d += e;
|
||||
d ^= e >>> 16;
|
||||
g += d;
|
||||
e += f;
|
||||
e ^= f << 10;
|
||||
h += e;
|
||||
f += g;
|
||||
f ^= g >>> 4;
|
||||
a += f;
|
||||
g += h;
|
||||
g ^= h << 8;
|
||||
b += g;
|
||||
h += a;
|
||||
h ^= a >>> 9;
|
||||
c += h;
|
||||
a += b;
|
||||
memory[i] = a;
|
||||
memory[i + 1] = b;
|
||||
memory[i + 2] = c;
|
||||
memory[i + 3] = d;
|
||||
memory[i + 4] = e;
|
||||
memory[i + 5] = f;
|
||||
memory[i + 6] = g;
|
||||
memory[i + 7] = h;
|
||||
}
|
||||
}
|
||||
isaac();
|
||||
count = SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
45
09HDscape-server/src/org/crandor/cache/crypto/ISAACPair.java
vendored
Normal file
45
09HDscape-server/src/org/crandor/cache/crypto/ISAACPair.java
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package org.crandor.cache.crypto;
|
||||
|
||||
/**
|
||||
* Represents a ISAAC key pair, for both input and output.
|
||||
* @author `Discardedx2
|
||||
*/
|
||||
public final class ISAACPair {
|
||||
|
||||
/**
|
||||
* The input cipher.
|
||||
*/
|
||||
private ISAACCipher input;
|
||||
|
||||
/**
|
||||
* The output cipher.
|
||||
*/
|
||||
private ISAACCipher output;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ISAACPair} {@code Object}.
|
||||
* @param input The input cipher.
|
||||
* @param output The output cipher.
|
||||
*/
|
||||
public ISAACPair(ISAACCipher input, ISAACCipher output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input cipher.
|
||||
* @return The input cipher.
|
||||
*/
|
||||
public ISAACCipher getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the output cipher.
|
||||
* @return The output cipher.
|
||||
*/
|
||||
public ISAACCipher getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
124
09HDscape-server/src/org/crandor/cache/crypto/XTEACryption.java
vendored
Normal file
124
09HDscape-server/src/org/crandor/cache/crypto/XTEACryption.java
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package org.crandor.cache.crypto;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Holds XTEA cryption methods.
|
||||
* @author ?
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class XTEACryption {
|
||||
|
||||
/**
|
||||
* The delta value
|
||||
*/
|
||||
private static final int DELTA = -1640531527;
|
||||
|
||||
/**
|
||||
* The sum.
|
||||
*/
|
||||
private static final int SUM = -957401312;
|
||||
|
||||
/**
|
||||
* The amount of "cryption cycles".
|
||||
*/
|
||||
private static final int NUM_ROUNDS = 32;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code XTEACryption}.
|
||||
*/
|
||||
private XTEACryption() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the contents of the buffer.
|
||||
* @param keys The cryption keys.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer) {
|
||||
return decrypt(keys, buffer, buffer.position(), buffer.limit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the buffer data.
|
||||
* @param keys The keys.
|
||||
* @param buffer The buffer to decrypt.
|
||||
* @param offset The offset of the data to decrypt.
|
||||
* @param length The length.
|
||||
* @return The decrypted data.
|
||||
*/
|
||||
public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer, int offset, int length) {
|
||||
int numBlocks = (length - offset) / 8;
|
||||
int[] block = new int[2];
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
int index = i * 8 + offset;
|
||||
block[0] = buffer.getInt(index);
|
||||
block[1] = buffer.getInt(index + 4);
|
||||
decipher(keys, block);
|
||||
buffer.putInt(index, block[0]);
|
||||
buffer.putInt(index + 4, block[1]);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deciphers the values.
|
||||
* @param keys The cryption key.
|
||||
* @param block The values to decipher.
|
||||
*/
|
||||
private static void decipher(int[] keys, int[] block) {
|
||||
long sum = SUM;
|
||||
for (int i = 0; i < NUM_ROUNDS; i++) {
|
||||
block[1] -= (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5));
|
||||
sum -= DELTA;
|
||||
block[0] -= ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the contents of the byte buffer.
|
||||
* @param keys The cryption keys.
|
||||
* @param buffer The buffer to encrypt.
|
||||
*/
|
||||
public static void encrypt(int[] keys, ByteBuffer buffer) {
|
||||
encrypt(keys, buffer, buffer.position(), buffer.limit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the buffer data.
|
||||
* @param keys The keys.
|
||||
* @param buffer The buffer to encrypt.
|
||||
* @param offset The offset of the data to encrypt.
|
||||
* @param length The length.
|
||||
* @return The encrypted data.
|
||||
*/
|
||||
public static void encrypt(int[] keys, ByteBuffer buffer, int offset, int length) {
|
||||
int numBlocks = (length - offset) / 8;
|
||||
int[] block = new int[2];
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
int index = i * 8 + offset;
|
||||
block[0] = buffer.getInt(index);
|
||||
block[1] = buffer.getInt(index + 4);
|
||||
encipher(keys, block);
|
||||
buffer.putInt(index, block[0]);
|
||||
buffer.putInt(index + 4, block[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enciphers the values of the block.
|
||||
* @param keys The cryption keys.
|
||||
* @param block The block to encipher.
|
||||
*/
|
||||
private static void encipher(int[] keys, int[] block) {
|
||||
long sum = 0;
|
||||
for (int i = 0; i < NUM_ROUNDS; i++) {
|
||||
block[0] += ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum);
|
||||
sum += DELTA;
|
||||
block[1] += (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
178
09HDscape-server/src/org/crandor/cache/def/Definition.java
vendored
Normal file
178
09HDscape-server/src/org/crandor/cache/def/Definition.java
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
package org.crandor.cache.def;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.tools.StringUtils;
|
||||
import org.crandor.game.node.Node;
|
||||
|
||||
/**
|
||||
* Represent's a node's definitions.
|
||||
* @author Emperor
|
||||
* @param <T> The node type.
|
||||
*/
|
||||
public class Definition<T extends Node> {
|
||||
|
||||
/**
|
||||
* The node id.
|
||||
*/
|
||||
protected int id;
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*/
|
||||
protected String name = "null";
|
||||
|
||||
/**
|
||||
* The examine info.
|
||||
*/
|
||||
protected String examine;
|
||||
|
||||
/**
|
||||
* The options.
|
||||
*/
|
||||
protected String[] options;
|
||||
|
||||
/**
|
||||
* The configurations.
|
||||
*/
|
||||
protected final Map<String, Object> configurations = new HashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Definition} {@code Object}.
|
||||
*/
|
||||
public Definition() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this node has options.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasOptions() {
|
||||
return hasOptions(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this node has options.
|
||||
* @param examine If examine should be treated as an option.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasOptions(boolean examine) {
|
||||
if (name.equals("null") || options == null) {
|
||||
return false;
|
||||
}
|
||||
for (String option : options) {
|
||||
if (option != null && !option.equals("null")) {
|
||||
if (examine || !option.equals("Examine")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a configuration of this item's definitions.
|
||||
* @param key The key.
|
||||
* @return The configuration value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V> V getConfiguration(String key) {
|
||||
return (V) configurations.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a configuration from this item's definitions.
|
||||
* @param key The key.
|
||||
* @param fail The object to return if there was no value found for this
|
||||
* key.
|
||||
* @return The value, or the fail object.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V> V getConfiguration(String key, V fail) {
|
||||
V object = (V) configurations.get(key);
|
||||
if (object == null) {
|
||||
return fail;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id.
|
||||
* @param id The id to set.
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name.
|
||||
* @param name The name to set.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the examine.
|
||||
* @return The examine.
|
||||
*/
|
||||
public String getExamine() {
|
||||
if (examine == null) {
|
||||
examine = "It's a" + (StringUtils.isPlusN(name) ? "n " : " ") + name + ".";
|
||||
}
|
||||
return examine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the examine.
|
||||
* @param examine The examine to set.
|
||||
*/
|
||||
public void setExamine(String examine) {
|
||||
this.examine = examine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the options.
|
||||
* @return The options.
|
||||
*/
|
||||
public String[] getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options.
|
||||
* @param options The options to set.
|
||||
*/
|
||||
public void setOptions(String[] options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configurations.
|
||||
* @return The configurations.
|
||||
*/
|
||||
public Map<String, Object> getConfigurations() {
|
||||
return configurations;
|
||||
}
|
||||
|
||||
}
|
||||
200
09HDscape-server/src/org/crandor/cache/def/impl/AnimationDefinition.java
vendored
Normal file
200
09HDscape-server/src/org/crandor/cache/def/impl/AnimationDefinition.java
vendored
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.cache.Cache;
|
||||
import org.crandor.cache.misc.buffer.ByteBufferUtils;
|
||||
|
||||
/**
|
||||
* Represents an animation's definitions.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class AnimationDefinition {
|
||||
|
||||
public int anInt2136;
|
||||
public int anInt2137;
|
||||
public int[] anIntArray2139;
|
||||
public int anInt2140;
|
||||
public boolean aBoolean2141 = false;
|
||||
public int anInt2142;
|
||||
public int emoteItem;
|
||||
public int anInt2144 = -1;
|
||||
public int[][] handledSounds;
|
||||
public boolean[] aBooleanArray2149;
|
||||
public int[] anIntArray2151;
|
||||
public boolean aBoolean2152;
|
||||
public int[] durations;
|
||||
public int anInt2155;
|
||||
public boolean aBoolean2158;
|
||||
public boolean aBoolean2159;
|
||||
public int anInt2162;
|
||||
public int anInt2163;
|
||||
boolean newHeader;
|
||||
|
||||
// added
|
||||
public int[] soundMinDelay;
|
||||
public int[] soundMaxDelay;
|
||||
public int[] anIntArray1362;
|
||||
public boolean effect2Sound;
|
||||
|
||||
private static final Map<Integer, AnimationDefinition> animDefs = new HashMap<>();
|
||||
|
||||
public static final AnimationDefinition forId(int emoteId) {
|
||||
try {
|
||||
AnimationDefinition defs = animDefs.get(emoteId);
|
||||
if (defs != null) {
|
||||
return defs;
|
||||
}
|
||||
byte[] data = Cache.getIndexes()[20].getFileData(emoteId >>> 7, emoteId & 0x7f);
|
||||
defs = new AnimationDefinition();
|
||||
if (data != null) {
|
||||
defs.readValueLoop(ByteBuffer.wrap(data));
|
||||
}
|
||||
defs.method2394();
|
||||
animDefs.put(emoteId, defs);
|
||||
return defs;
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void readValueLoop(ByteBuffer buffer) {
|
||||
for (;;) {
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
if (opcode == 0) {
|
||||
break;
|
||||
}
|
||||
readValues(buffer, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration of this animation in milliseconds.
|
||||
* @return The duration.
|
||||
*/
|
||||
public int getDuration() {
|
||||
if (durations == null) {
|
||||
return 0;
|
||||
}
|
||||
int duration = 0;
|
||||
for (int i : durations) {
|
||||
if (i > 100) {
|
||||
continue;
|
||||
}
|
||||
duration += i * 20;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration of this animation in (600ms) ticks.
|
||||
* @return The duration in ticks.
|
||||
*/
|
||||
public int getDurationTicks() {
|
||||
int ticks = getDuration() / 600;
|
||||
return ticks < 1 ? 1 : ticks;
|
||||
}
|
||||
|
||||
private void readValues(ByteBuffer buffer, int opcode) {
|
||||
if (opcode == 1) {
|
||||
int length = buffer.getShort() & 0xFFFF;
|
||||
durations = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
durations[i] = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
anIntArray2139 = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
anIntArray2139[i] = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
anIntArray2139[i] = ((buffer.getShort() & 0xFFFF << 16) + anIntArray2139[i]);
|
||||
}
|
||||
} else if (opcode != 2) {
|
||||
if (opcode != 3) {
|
||||
if (opcode == 4)
|
||||
aBoolean2152 = true;
|
||||
else if (opcode == 5)
|
||||
anInt2142 = buffer.get() & 0xFF;
|
||||
else if (opcode != 6) {
|
||||
if (opcode == 7)
|
||||
emoteItem = buffer.getShort() & 0xFFFF;
|
||||
else if ((opcode ^ 0xffffffff) != -9) {
|
||||
if (opcode != 9) {
|
||||
if (opcode != 10) {
|
||||
if (opcode == 11)
|
||||
anInt2155 = buffer.get() & 0xFF;
|
||||
else if (opcode == 12) {
|
||||
int i = buffer.get() & 0xFF;
|
||||
anIntArray2151 = new int[i];
|
||||
for (int i_19_ = 0; ((i_19_ ^ 0xffffffff) > (i ^ 0xffffffff)); i_19_++)
|
||||
anIntArray2151[i_19_] = buffer.getShort() & 0xFFFF;
|
||||
for (int i_20_ = 0; i > i_20_; i_20_++)
|
||||
anIntArray2151[i_20_] = ((buffer.getShort() & 0xFFFF << 16) + anIntArray2151[i_20_]);
|
||||
} else if (opcode == 13) {
|
||||
// opcode 13
|
||||
int i = buffer.getShort() & 0xFFFF;
|
||||
handledSounds = new int[i][];
|
||||
for (int i_21_ = 0; i_21_ < i; i_21_++) {
|
||||
int i_22_ = buffer.get() & 0xFF;
|
||||
if ((i_22_ ^ 0xffffffff) < -1) {
|
||||
handledSounds[i_21_] = new int[i_22_];
|
||||
handledSounds[i_21_][0] = ByteBufferUtils.getTriByte(buffer);
|
||||
for (int i_23_ = 1; ((i_22_ ^ 0xffffffff) < (i_23_ ^ 0xffffffff)); i_23_++) {
|
||||
handledSounds[i_21_][i_23_] = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (opcode == 14) {
|
||||
aBoolean2141 = true;
|
||||
} else {
|
||||
System.out.println("Unhandled animation opcode " + opcode);
|
||||
}
|
||||
} else
|
||||
anInt2162 = buffer.get() & 0xFF;
|
||||
} else
|
||||
anInt2140 = buffer.get() & 0xFF;
|
||||
} else
|
||||
anInt2136 = buffer.get() & 0xFF;
|
||||
} else
|
||||
anInt2144 = buffer.getShort() & 0xFFFF;
|
||||
} else {
|
||||
aBooleanArray2149 = new boolean[256];
|
||||
int length = buffer.get() & 0xFF;
|
||||
for (int i = 0; i < length; i++) {
|
||||
aBooleanArray2149[buffer.get() & 0xFF] = true;
|
||||
}
|
||||
}
|
||||
} else
|
||||
anInt2163 = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
|
||||
public void method2394() {
|
||||
if (anInt2140 == -1) {
|
||||
if (aBooleanArray2149 == null)
|
||||
anInt2140 = 0;
|
||||
else
|
||||
anInt2140 = 2;
|
||||
}
|
||||
if (anInt2162 == -1) {
|
||||
if (aBooleanArray2149 == null)
|
||||
anInt2162 = 0;
|
||||
else
|
||||
anInt2162 = 2;
|
||||
}
|
||||
}
|
||||
|
||||
public AnimationDefinition() {
|
||||
anInt2136 = 99;
|
||||
emoteItem = -1;
|
||||
anInt2140 = -1;
|
||||
aBoolean2152 = false;
|
||||
anInt2142 = 5;
|
||||
aBoolean2159 = false;
|
||||
anInt2163 = -1;
|
||||
anInt2155 = 2;
|
||||
aBoolean2158 = false;
|
||||
anInt2162 = -1;
|
||||
}
|
||||
}
|
||||
255
09HDscape-server/src/org/crandor/cache/def/impl/CS2Mapping.java
vendored
Normal file
255
09HDscape-server/src/org/crandor/cache/def/impl/CS2Mapping.java
vendored
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.cache.Cache;
|
||||
import org.crandor.cache.misc.buffer.ByteBufferUtils;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* The CS2 mapping.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class CS2Mapping {
|
||||
|
||||
/**
|
||||
* The CS2 mappings.
|
||||
*/
|
||||
private static final Map<Integer, CS2Mapping> maps = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The script id.
|
||||
*/
|
||||
private final int scriptId;
|
||||
|
||||
/**
|
||||
* Unknown value.
|
||||
*/
|
||||
private int unknown;
|
||||
|
||||
/**
|
||||
* Second unknown value.
|
||||
*/
|
||||
private int unknown1;
|
||||
|
||||
/**
|
||||
* The default string value.
|
||||
*/
|
||||
private String defaultString;
|
||||
|
||||
/**
|
||||
* The default integer value.
|
||||
*/
|
||||
private int defaultInt;
|
||||
|
||||
/**
|
||||
* The mapping.
|
||||
*/
|
||||
private HashMap<Integer, Object> map;
|
||||
|
||||
/**
|
||||
* The array of the objects.
|
||||
*/
|
||||
private Object[] array;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CS2Mapping} {@code Object}.
|
||||
* @param scriptId The script id.
|
||||
*/
|
||||
public CS2Mapping(int scriptId) {
|
||||
this.scriptId = scriptId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
* @param args The arguments cast on runtime.
|
||||
* @throws Throwable When an exception occurs.
|
||||
*/
|
||||
public static void main(String... args) throws Throwable {
|
||||
GameWorld.prompt(false);
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter("./cs2.txt"));
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
CS2Mapping mapping = forId(i);
|
||||
if (mapping == null) {
|
||||
continue;
|
||||
}
|
||||
if (mapping.map == null) {
|
||||
continue;
|
||||
}
|
||||
bw.append("Script - " + i + " [");
|
||||
for (int index : mapping.map.keySet()) {
|
||||
bw.append(mapping.map.get(index) + ": " + index + " ");
|
||||
}
|
||||
bw.append("]");
|
||||
bw.newLine();
|
||||
}
|
||||
bw.flush();
|
||||
bw.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mapping for the given script id.
|
||||
* @param scriptId The script id.
|
||||
* @return The mapping.
|
||||
*/
|
||||
public static CS2Mapping forId(int scriptId) {
|
||||
CS2Mapping mapping = maps.get(scriptId);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
mapping = new CS2Mapping(scriptId);
|
||||
byte[] bs = Cache.getIndexes()[17].getFileData(scriptId >>> 8, scriptId & 0xFF);
|
||||
if (bs != null) {
|
||||
mapping.load(ByteBuffer.wrap(bs));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
maps.put(scriptId, mapping);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the mapping data.
|
||||
* @param stream The buffer to read the data from.
|
||||
*/
|
||||
private void load(ByteBuffer buffer) {
|
||||
int opcode;
|
||||
while ((opcode = buffer.get() & 0xFF) != 0) {
|
||||
switch (opcode) {
|
||||
case 1:
|
||||
unknown = buffer.get() & 0xFF;
|
||||
break;
|
||||
case 2:
|
||||
unknown1 = buffer.get() & 0xFF;
|
||||
break;
|
||||
case 3:
|
||||
defaultString = ByteBufferUtils.getString(buffer);
|
||||
break;
|
||||
case 4:
|
||||
defaultInt = buffer.getInt();
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
int size = buffer.getShort() & 0xFFFF;
|
||||
String string = null;
|
||||
int val = 0;
|
||||
map = new HashMap<>(size);
|
||||
array = new Object[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
int key = buffer.getInt();
|
||||
if (opcode == 5) {
|
||||
string = ByteBufferUtils.getString(buffer);
|
||||
array[i] = string;
|
||||
map.put(key, string);
|
||||
} else {
|
||||
val = buffer.getInt();
|
||||
array[i] = val;
|
||||
map.put(key, val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of objects.
|
||||
* @return the objects.
|
||||
*/
|
||||
public Object[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scriptId.
|
||||
* @return The scriptId.
|
||||
*/
|
||||
public int getScriptId() {
|
||||
return scriptId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unknown.
|
||||
* @return The unknown.
|
||||
*/
|
||||
public int getUnknown() {
|
||||
return unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unknown.
|
||||
* @param unknown The unknown to set.
|
||||
*/
|
||||
public void setUnknown(int unknown) {
|
||||
this.unknown = unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unknown1.
|
||||
* @return The unknown1.
|
||||
*/
|
||||
public int getUnknown1() {
|
||||
return unknown1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unknown1.
|
||||
* @param unknown1 The unknown1 to set.
|
||||
*/
|
||||
public void setUnknown1(int unknown1) {
|
||||
this.unknown1 = unknown1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the defaultString.
|
||||
* @return The defaultString.
|
||||
*/
|
||||
public String getDefaultString() {
|
||||
return defaultString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the defaultString.
|
||||
* @param defaultString The defaultString to set.
|
||||
*/
|
||||
public void setDefaultString(String defaultString) {
|
||||
this.defaultString = defaultString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the defaultInt.
|
||||
* @return The defaultInt.
|
||||
*/
|
||||
public int getDefaultInt() {
|
||||
return defaultInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the defaultInt.
|
||||
* @param defaultInt The defaultInt to set.
|
||||
*/
|
||||
public void setDefaultInt(int defaultInt) {
|
||||
this.defaultInt = defaultInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map.
|
||||
* @return The map.
|
||||
*/
|
||||
public HashMap<Integer, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the map.
|
||||
* @param map The map to set.
|
||||
*/
|
||||
public void setMap(HashMap<Integer, Object> map) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
208
09HDscape-server/src/org/crandor/cache/def/impl/ClothDefinition.java
vendored
Normal file
208
09HDscape-server/src/org/crandor/cache/def/impl/ClothDefinition.java
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.crandor.ServerConstants;
|
||||
import org.crandor.cache.Cache;
|
||||
|
||||
/**
|
||||
* The definitions for player clothing/look.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ClothDefinition {
|
||||
|
||||
/**
|
||||
* The equipment slot.
|
||||
*/
|
||||
private int equipmentSlot;
|
||||
|
||||
/**
|
||||
* The model ids.
|
||||
*/
|
||||
private int[] modelIds;
|
||||
|
||||
/**
|
||||
* Unknown boolean.
|
||||
*/
|
||||
private boolean unknownBool;
|
||||
|
||||
/**
|
||||
* Original colors.
|
||||
*/
|
||||
private int[] originalColors;
|
||||
|
||||
/**
|
||||
* The colors to change to.
|
||||
*/
|
||||
private int[] modifiedColors;
|
||||
|
||||
/**
|
||||
* Original texture colors.
|
||||
*/
|
||||
private int[] originalTextureColors;
|
||||
|
||||
/**
|
||||
* Texture colors to change to.
|
||||
*/
|
||||
private int[] modifiedTextureColors;
|
||||
|
||||
/**
|
||||
* Other model ids(?)
|
||||
*/
|
||||
private int[] models = { -1, -1, -1, -1, -1 };
|
||||
|
||||
/**
|
||||
* Gets the definitions for the given cloth id.
|
||||
* @param clothId The clothing id.
|
||||
* @return The definition.
|
||||
*/
|
||||
public static ClothDefinition forId(int clothId) {
|
||||
ClothDefinition def = new ClothDefinition();
|
||||
byte[] bs = Cache.getIndexes()[2].getFileData(3, clothId);
|
||||
if (bs != null) {
|
||||
def.load(ByteBuffer.wrap(bs));
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
* @param args The arguments cast on runtime.
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
try {
|
||||
Cache.init(ServerConstants.CACHE_PATH);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int length = Cache.getIndexes()[2].getFilesSize(3);
|
||||
System.out.println("Definition size: " + length + ".");
|
||||
for (int i = 0; i < length; i++) {
|
||||
ClothDefinition def = forId(i);
|
||||
if (def.unknownBool)
|
||||
System.out.println("Clothing " + i + ": " + def.equipmentSlot + ", " + def.unknownBool + ", " + Arrays.toString(def.modelIds) + ", " + Arrays.toString(def.models));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the definitions.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public void load(ByteBuffer buffer) {
|
||||
int opcode;
|
||||
while ((opcode = buffer.get() & 0xFF) != 0) {
|
||||
parse(opcode, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an opcode.
|
||||
* @param opcode The opcode.
|
||||
* @param buffer The buffer to read the data from.
|
||||
*/
|
||||
private void parse(int opcode, ByteBuffer buffer) {
|
||||
switch (opcode) {
|
||||
case 1:
|
||||
equipmentSlot = buffer.get() & 0xFF;
|
||||
break;
|
||||
case 2:
|
||||
int length = buffer.get() & 0xFF;
|
||||
modelIds = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
modelIds[i] = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
unknownBool = true;
|
||||
break;
|
||||
case 40:
|
||||
length = buffer.get() & 0xFF;
|
||||
originalColors = new int[length];
|
||||
modifiedColors = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
originalColors[i] = buffer.getShort();
|
||||
modifiedColors[i] = buffer.getShort();
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
length = buffer.get() & 0xFF;
|
||||
originalTextureColors = new int[length];
|
||||
modifiedTextureColors = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
originalTextureColors[i] = buffer.getShort();
|
||||
modifiedTextureColors[i] = buffer.getShort();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (opcode >= 60 && opcode < 70) {
|
||||
models[opcode - 60] = buffer.getShort() & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unknown.
|
||||
* @return The unknown.
|
||||
*/
|
||||
public int getUnknown() {
|
||||
return equipmentSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modelIds.
|
||||
* @return The modelIds.
|
||||
*/
|
||||
public int[] getModelIds() {
|
||||
return modelIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unknownBool.
|
||||
* @return The unknownBool.
|
||||
*/
|
||||
public boolean isUnknownBool() {
|
||||
return unknownBool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the originalColors.
|
||||
* @return The originalColors.
|
||||
*/
|
||||
public int[] getOriginalColors() {
|
||||
return originalColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modifiedColors.
|
||||
* @return The modifiedColors.
|
||||
*/
|
||||
public int[] getModifiedColors() {
|
||||
return modifiedColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the originalTextureColors.
|
||||
* @return The originalTextureColors.
|
||||
*/
|
||||
public int[] getOriginalTextureColors() {
|
||||
return originalTextureColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modifiedTextureColors.
|
||||
* @return The modifiedTextureColors.
|
||||
*/
|
||||
public int[] getModifiedTextureColors() {
|
||||
return modifiedTextureColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the models.
|
||||
* @return The models.
|
||||
*/
|
||||
public int[] getModels() {
|
||||
return models;
|
||||
}
|
||||
}
|
||||
157
09HDscape-server/src/org/crandor/cache/def/impl/ConfigFileDefinition.java
vendored
Normal file
157
09HDscape-server/src/org/crandor/cache/def/impl/ConfigFileDefinition.java
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.cache.Cache;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Handles config definition reading.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ConfigFileDefinition {
|
||||
|
||||
/**
|
||||
* The config definitions mapping.
|
||||
*/
|
||||
private static final Map<Integer, ConfigFileDefinition> MAPPING = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The bit size flags.
|
||||
*/
|
||||
private static final int[] BITS = new int[32];
|
||||
|
||||
/**
|
||||
* The file id.
|
||||
*/
|
||||
private final int id;
|
||||
|
||||
/**
|
||||
* The config id.
|
||||
*/
|
||||
private int configId;
|
||||
|
||||
/**
|
||||
* The bit shift amount.
|
||||
*/
|
||||
private int bitShift;
|
||||
|
||||
/**
|
||||
* The bit amount.
|
||||
*/
|
||||
private int bitSize;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ConfigFileDefinition} {@code Object}.
|
||||
* @param id The file id.
|
||||
*/
|
||||
public ConfigFileDefinition(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the bit flags.
|
||||
*/
|
||||
static {
|
||||
int flag = 2;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
BITS[i] = flag - 1;
|
||||
flag += flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the config file definitions for the given file id.
|
||||
* @param id The file id.
|
||||
* @return The definition.
|
||||
*/
|
||||
public static ConfigFileDefinition forId(int id) {
|
||||
ConfigFileDefinition def = MAPPING.get(id);
|
||||
if (def != null) {
|
||||
return def;
|
||||
}
|
||||
def = new ConfigFileDefinition(id);
|
||||
byte[] bs = Cache.getIndexes()[22].getFileData(id >>> 1416501898, id & 0x3ff);
|
||||
if (bs != null) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bs);
|
||||
int opcode = 0;
|
||||
while ((opcode = buffer.get() & 0xFF) != 0) {
|
||||
if (opcode == 1) {
|
||||
def.configId = buffer.getShort() & 0xFFFF;
|
||||
def.bitShift = buffer.get() & 0xFF;
|
||||
def.bitSize = buffer.get() & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
MAPPING.put(id, def);
|
||||
return def;
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
GameWorld.prompt(false);
|
||||
for (int i = 0; i < 15000; i++) {
|
||||
ConfigFileDefinition def = forId(i);
|
||||
if (def != null && def.configId == 33) {
|
||||
System.out.println("Config file [id=" + i + ", shift=" + def.bitShift + "]!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current config value for this file.
|
||||
* @param player The player.
|
||||
* @return The config value.
|
||||
*/
|
||||
public int getValue(Player player) {
|
||||
int size = BITS[bitSize - bitShift];
|
||||
return size & player.getConfigManager().get(configId) >> bitShift;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mapping.
|
||||
* @return The mapping.
|
||||
*/
|
||||
public static Map<Integer, ConfigFileDefinition> getMapping() {
|
||||
return MAPPING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configId.
|
||||
* @return The configId.
|
||||
*/
|
||||
public int getConfigId() {
|
||||
return configId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bitShift.
|
||||
* @return The bitShift.
|
||||
*/
|
||||
public int getBitShift() {
|
||||
return bitShift;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bitSize.
|
||||
* @return The bitSize.
|
||||
*/
|
||||
public int getBitSize() {
|
||||
return bitSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfigFileDefinition [id=" + id + ", configId=" + configId + ", bitShift=" + bitShift + ", bitSize=" + bitSize + "]";
|
||||
}
|
||||
}
|
||||
189
09HDscape-server/src/org/crandor/cache/def/impl/GraphicDefinition.java
vendored
Normal file
189
09HDscape-server/src/org/crandor/cache/def/impl/GraphicDefinition.java
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.crandor.ServerConstants;
|
||||
import org.crandor.cache.Cache;
|
||||
|
||||
/**
|
||||
* Represents a Graphic's definition.
|
||||
* @author Jagex
|
||||
*/
|
||||
public class GraphicDefinition {
|
||||
|
||||
public short[] aShortArray1435;
|
||||
public short[] aShortArray1438;
|
||||
public int anInt1440;
|
||||
public boolean aBoolean1442;
|
||||
public int defaultModel;
|
||||
public int anInt1446;
|
||||
public boolean aBoolean1448 = false;
|
||||
public int anInt1449;
|
||||
public int animationId;
|
||||
public int anInt1451;
|
||||
public int graphicsId;
|
||||
public int anInt1454;
|
||||
public short[] aShortArray1455;
|
||||
public short[] aShortArray1456;
|
||||
|
||||
// added
|
||||
public byte byteValue;
|
||||
// added
|
||||
public int intValue;
|
||||
|
||||
/**
|
||||
* The definitions mapping.
|
||||
*/
|
||||
private static final Map<Integer, GraphicDefinition> graphicDefinitions = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the graphic definition for the given graphic id.
|
||||
* @param gfxId The graphic id.
|
||||
* @return The definition.
|
||||
*/
|
||||
public static final GraphicDefinition forId(int gfxId) {
|
||||
GraphicDefinition def = graphicDefinitions.get(gfxId);
|
||||
if (def != null) {
|
||||
return def;
|
||||
}
|
||||
byte[] data = Cache.getIndexes()[21].getFileData(gfxId >>> 735411752, gfxId & 0xff);
|
||||
def = new GraphicDefinition();
|
||||
def.graphicsId = gfxId;
|
||||
if (data != null) {
|
||||
def.readValueLoop(ByteBuffer.wrap(data));
|
||||
}
|
||||
graphicDefinitions.put(gfxId, def);
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method, used for running a graphic definition search.
|
||||
* @param s The arguments cast on runtime.
|
||||
*/
|
||||
public static final void main(String... s) {
|
||||
try {
|
||||
Cache.init(ServerConstants.CACHE_PATH);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 5046 - 5050 are related anims & 2148
|
||||
GraphicDefinition d = GraphicDefinition.forId(803);
|
||||
System.out.println("Graphic " + d.graphicsId + " anim id = " + d.animationId + ", " + d.defaultModel + ".");
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
GraphicDefinition def = GraphicDefinition.forId(i);
|
||||
if (def == null) {
|
||||
continue;
|
||||
}
|
||||
if ((def.animationId > 2000 && def.animationId < 2200) || (def.defaultModel >= 1300 && def.defaultModel < 1500)) {
|
||||
System.out.println("Possible match [id=" + i + ", anim=" + def.animationId + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and handles all data from the input stream.
|
||||
* @param buffer The input stream.
|
||||
*/
|
||||
private void readValueLoop(ByteBuffer buffer) {
|
||||
for (;;) {
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
if (opcode == 0) {
|
||||
break;
|
||||
}
|
||||
readValues(buffer, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the opcode values from the input stream.
|
||||
* @param buffer The input stream.
|
||||
* @param opcode The opcode to handle.
|
||||
*/
|
||||
public void readValues(ByteBuffer buffer, int opcode) {
|
||||
if (opcode != 1) {
|
||||
if (opcode == 2)
|
||||
animationId = buffer.getShort();
|
||||
else if (opcode == 4)
|
||||
anInt1446 = buffer.getShort() & 0xFFFF;
|
||||
else if (opcode != 5) {
|
||||
if ((opcode ^ 0xffffffff) != -7) {
|
||||
if (opcode == 7)
|
||||
anInt1440 = buffer.get() & 0xFF;
|
||||
else if ((opcode ^ 0xffffffff) == -9)
|
||||
anInt1451 = buffer.get() & 0xFF;
|
||||
else if (opcode != 9) {
|
||||
if (opcode != 10) {
|
||||
if (opcode == 11) { // added opcode
|
||||
// aBoolean1442 = true;
|
||||
byteValue = (byte) 1;
|
||||
} else if (opcode == 12) { // added opcode
|
||||
// aBoolean1442 = true;
|
||||
byteValue = (byte) 4;
|
||||
} else if (opcode == 13) { // added opcode
|
||||
// aBoolean1442 = true;
|
||||
byteValue = (byte) 5;
|
||||
} else if (opcode == 14) { // added opcode
|
||||
// aBoolean1442 = true;
|
||||
// aByte2856 = 2;
|
||||
byteValue = (byte) 2;
|
||||
intValue = (buffer.get() & 0xFF) * 256;
|
||||
} else if (opcode == 15) {
|
||||
// aByte2856 = 3;
|
||||
byteValue = (byte) 3;
|
||||
intValue = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 16) {
|
||||
// aByte2856 = 3;
|
||||
byteValue = (byte) 3;
|
||||
intValue = buffer.getInt();
|
||||
} else if (opcode != 40) {
|
||||
if ((opcode ^ 0xffffffff) == -42) {
|
||||
int i = buffer.get() & 0xFF;
|
||||
aShortArray1455 = new short[i];
|
||||
aShortArray1435 = new short[i];
|
||||
for (int i_0_ = 0; i > i_0_; i_0_++) {
|
||||
aShortArray1455[i_0_] = (short) (buffer.getShort() & 0xFFFF);
|
||||
aShortArray1435[i_0_] = (short) (buffer.getShort() & 0xFFFF);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int i = buffer.get() & 0xFF;
|
||||
aShortArray1438 = new short[i];
|
||||
aShortArray1456 = new short[i];
|
||||
for (int i_1_ = 0; ((i ^ 0xffffffff) < (i_1_ ^ 0xffffffff)); i_1_++) {
|
||||
aShortArray1438[i_1_] = (short) (buffer.getShort() & 0xFFFF);
|
||||
aShortArray1456[i_1_] = (short) (buffer.getShort() & 0xFFFF);
|
||||
}
|
||||
}
|
||||
} else
|
||||
aBoolean1448 = true;
|
||||
} else {
|
||||
// aBoolean1442 = true;
|
||||
byteValue = (byte) 3;
|
||||
intValue = 8224;
|
||||
}
|
||||
} else
|
||||
anInt1454 = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt1449 = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
defaultModel = buffer.getShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GraphicDefinition} {@code Object}.
|
||||
*/
|
||||
public GraphicDefinition() {
|
||||
byteValue = 0;
|
||||
intValue = -1;
|
||||
anInt1446 = 128;
|
||||
aBoolean1442 = false;
|
||||
anInt1449 = 128;
|
||||
anInt1451 = 0;
|
||||
animationId = -1;
|
||||
anInt1454 = 0;
|
||||
anInt1440 = 0;
|
||||
}
|
||||
|
||||
}
|
||||
1662
09HDscape-server/src/org/crandor/cache/def/impl/ItemDefinition.java
vendored
Normal file
1662
09HDscape-server/src/org/crandor/cache/def/impl/ItemDefinition.java
vendored
Normal file
File diff suppressed because it is too large
Load diff
1121
09HDscape-server/src/org/crandor/cache/def/impl/NPCDefinition.java
vendored
Normal file
1121
09HDscape-server/src/org/crandor/cache/def/impl/NPCDefinition.java
vendored
Normal file
File diff suppressed because it is too large
Load diff
1673
09HDscape-server/src/org/crandor/cache/def/impl/ObjectDefinition.java
vendored
Normal file
1673
09HDscape-server/src/org/crandor/cache/def/impl/ObjectDefinition.java
vendored
Normal file
File diff suppressed because it is too large
Load diff
364
09HDscape-server/src/org/crandor/cache/def/impl/RenderAnimationDefinition.java
vendored
Normal file
364
09HDscape-server/src/org/crandor/cache/def/impl/RenderAnimationDefinition.java
vendored
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
package org.crandor.cache.def.impl;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.crandor.cache.Cache;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Holds definitions for render animations.
|
||||
* @author Jagex
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class RenderAnimationDefinition {
|
||||
|
||||
public int turn180Animation;
|
||||
public int anInt951 = -1;
|
||||
public int anInt952;
|
||||
public int turnCWAnimation = -1;
|
||||
public int anInt954;
|
||||
public int anInt955;
|
||||
public int anInt956;
|
||||
public int anInt957;
|
||||
public int anInt958;
|
||||
public int[] anIntArray959 = null;
|
||||
public int anInt960;
|
||||
public int anInt961 = 0;
|
||||
public int anInt962;
|
||||
public int walkAnimationId;
|
||||
public int anInt964;
|
||||
public int anInt965;
|
||||
public int anInt966;
|
||||
public int[] standAnimationIds;
|
||||
public int anInt969;
|
||||
public int[] anIntArray971;
|
||||
public int standAnimationId;
|
||||
public int anInt973;
|
||||
public int anInt974;
|
||||
public int anInt975;
|
||||
public int runAnimationId;
|
||||
public int anInt977;
|
||||
public boolean aBoolean978;
|
||||
public int[][] anIntArrayArray979;
|
||||
public int anInt980;
|
||||
public int turnCCWAnimation;
|
||||
public int anInt983;
|
||||
public int anInt985;
|
||||
public int anInt986;
|
||||
public int anInt987;
|
||||
public int anInt988;
|
||||
public int anInt989;
|
||||
public int anInt990;
|
||||
public int anInt992;
|
||||
public int anInt993;
|
||||
public int anInt994;
|
||||
|
||||
/**
|
||||
* Gets the render animation definitions for the given id.
|
||||
* @param animId The render animation id.
|
||||
* @return The render animation definitions.
|
||||
*/
|
||||
public static RenderAnimationDefinition forId(int animId) {
|
||||
RenderAnimationDefinition defs = new RenderAnimationDefinition();
|
||||
if (animId == -1) {
|
||||
return null;
|
||||
}
|
||||
byte[] data = Cache.getIndexes()[2].getFileData(32, animId);
|
||||
defs = new RenderAnimationDefinition();
|
||||
if (data != null) {
|
||||
defs.parse(ByteBuffer.wrap(data));
|
||||
} else {
|
||||
System.err.println("No definitions found for render animation " + animId + ", size=" + Cache.getIndexes()[2].getFilesSize(32) + "!");
|
||||
}
|
||||
return defs;
|
||||
}
|
||||
|
||||
private void parse(ByteBuffer buffer) {
|
||||
for (;;) {
|
||||
int opcode = buffer.get() & 0xFF;
|
||||
if (opcode == 0) {
|
||||
break;
|
||||
}
|
||||
parseOpcode(buffer, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseOpcode(ByteBuffer buffer, int opcode) {
|
||||
if (opcode == 54) {
|
||||
@SuppressWarnings("unused")
|
||||
int anInt1260 = (buffer.get() & 0xFF) << 6;
|
||||
@SuppressWarnings("unused")
|
||||
int anInt1227 = (buffer.get() & 0xFF) << 6;
|
||||
} else if (opcode == 55) {
|
||||
int[] anIntArray1246 = new int[12];
|
||||
int i_14_ = buffer.get() & 0xFF;
|
||||
anIntArray1246[i_14_] = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 56) {
|
||||
int[][] anIntArrayArray1217 = new int[12][];
|
||||
int i_12_ = buffer.get() & 0xFF;
|
||||
anIntArrayArray1217[i_12_] = new int[3];
|
||||
for (int i_13_ = 0; i_13_ < 3; i_13_++)
|
||||
anIntArrayArray1217[i_12_][i_13_] = buffer.getShort();
|
||||
} else if ((opcode ^ 0xffffffff) != -2) {
|
||||
if ((opcode ^ 0xffffffff) != -3) {
|
||||
if (opcode != 3) {
|
||||
if ((opcode ^ 0xffffffff) != -5) {
|
||||
if (opcode == 5)
|
||||
anInt977 = buffer.getShort() & 0xFFFF;
|
||||
else if ((opcode ^ 0xffffffff) != -7) {
|
||||
if (opcode == 7)
|
||||
anInt960 = buffer.getShort() & 0xFFFF;
|
||||
else if ((opcode ^ 0xffffffff) == -9)
|
||||
anInt985 = buffer.getShort() & 0xFFFF;
|
||||
else if (opcode == 9)
|
||||
anInt957 = buffer.getShort() & 0xFFFF;
|
||||
else if (opcode == 26) {
|
||||
anInt973 = (short) (4 * buffer
|
||||
.get() & 0xFF);
|
||||
anInt975 = (short) (buffer.get() & 0xFF * 4);
|
||||
} else if ((opcode ^ 0xffffffff) == -28) {
|
||||
if (anIntArrayArray979 == null)
|
||||
anIntArrayArray979 = new int[12][];
|
||||
int i = buffer.get() & 0xFF;
|
||||
anIntArrayArray979[i] = new int[6];
|
||||
for (int i_1_ = 0; (i_1_ ^ 0xffffffff) > -7; i_1_++)
|
||||
anIntArrayArray979[i][i_1_] = buffer
|
||||
.getShort();
|
||||
} else if ((opcode ^ 0xffffffff) == -29) {
|
||||
anIntArray971 = new int[12];
|
||||
for (int i = 0; i < 12; i++) {
|
||||
anIntArray971[i] = buffer
|
||||
.get() & 0xFF;
|
||||
if (anIntArray971[i] == 255)
|
||||
anIntArray971[i] = -1;
|
||||
}
|
||||
} else if (opcode != 29) {
|
||||
if (opcode != 30) {
|
||||
if ((opcode ^ 0xffffffff) != -32) {
|
||||
if (opcode != 32) {
|
||||
if ((opcode ^ 0xffffffff) != -34) {
|
||||
if (opcode != 34) {
|
||||
if (opcode != 35) {
|
||||
if ((opcode ^ 0xffffffff) != -37) {
|
||||
if ((opcode ^ 0xffffffff) != -38) {
|
||||
if (opcode != 38) {
|
||||
if ((opcode ^ 0xffffffff) != -40) {
|
||||
if ((opcode ^ 0xffffffff) != -41) {
|
||||
if ((opcode ^ 0xffffffff) == -42)
|
||||
turnCWAnimation = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
else if (opcode != 42) {
|
||||
if ((opcode ^ 0xffffffff) == -44)
|
||||
buffer.getShort();
|
||||
else if ((opcode ^ 0xffffffff) != -45) {
|
||||
if ((opcode ^ 0xffffffff) == -46)
|
||||
anInt964 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
else if ((opcode ^ 0xffffffff) != -47) {
|
||||
if (opcode == 47)
|
||||
anInt966 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
else if (opcode == 48)
|
||||
anInt989 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
else if (opcode != 49) {
|
||||
if ((opcode ^ 0xffffffff) != -51) {
|
||||
if (opcode != 51) {
|
||||
if (opcode == 52) {
|
||||
int i = buffer
|
||||
.get() & 0xFF;
|
||||
anIntArray959 = new int[i];
|
||||
standAnimationIds = new int[i];
|
||||
for (int i_2_ = 0; i_2_ < i; i_2_++) {
|
||||
standAnimationIds[i_2_] = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
int i_3_ = buffer
|
||||
.get() & 0xFF;
|
||||
anIntArray959[i_2_] = i_3_;
|
||||
anInt994 += i_3_;
|
||||
}
|
||||
} else if (opcode == 53)
|
||||
aBoolean978 = false;
|
||||
} else
|
||||
anInt962 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt990 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt952 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt983 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt955 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
turnCCWAnimation = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
turn180Animation = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt954 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt958 = (buffer
|
||||
.getShort() & 0xFFFF);
|
||||
} else
|
||||
anInt951 = (buffer
|
||||
.get() & 0xFF);
|
||||
} else
|
||||
anInt965 = (buffer
|
||||
.getShort());
|
||||
} else
|
||||
anInt969 = (buffer
|
||||
.getShort() & 0xFFFF);
|
||||
} else
|
||||
anInt993 = buffer
|
||||
.get() & 0xFF;
|
||||
} else
|
||||
anInt956 = (buffer.getShort());
|
||||
} else
|
||||
anInt961 = buffer
|
||||
.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt988 = buffer.get() & 0xFF;
|
||||
} else
|
||||
anInt980 = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt992 = buffer.get() & 0xFF;
|
||||
} else
|
||||
runAnimationId = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt986 = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt987 = buffer.getShort() & 0xFFFF;
|
||||
} else
|
||||
anInt974 = buffer.getShort() & 0xFFFF;
|
||||
} else {
|
||||
standAnimationId = buffer.getShort() & 0xFFFF;
|
||||
walkAnimationId = buffer.getShort() & 0xFFFF;
|
||||
if ((standAnimationId ^ 0xffffffff) == -65536)
|
||||
standAnimationId = -1;
|
||||
if ((walkAnimationId ^ 0xffffffff) == -65536)
|
||||
walkAnimationId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public RenderAnimationDefinition() {
|
||||
anInt957 = -1;
|
||||
anInt954 = -1;
|
||||
anInt960 = -1;
|
||||
anInt958 = -1;
|
||||
anInt965 = 0;
|
||||
anInt973 = 0;
|
||||
turn180Animation = -1;
|
||||
anInt956 = 0;
|
||||
standAnimationId = -1;
|
||||
standAnimationIds = null;
|
||||
anInt952 = -1;
|
||||
anInt983 = -1;
|
||||
anInt985 = -1;
|
||||
anInt962 = -1;
|
||||
anInt966 = -1;
|
||||
anInt977 = -1;
|
||||
anInt975 = 0;
|
||||
runAnimationId = -1;
|
||||
anInt988 = 0;
|
||||
turnCCWAnimation = -1;
|
||||
anInt987 = -1;
|
||||
anInt980 = 0;
|
||||
anInt964 = -1;
|
||||
walkAnimationId = -1;
|
||||
anInt986 = -1;
|
||||
aBoolean978 = true;
|
||||
anInt992 = 0;
|
||||
anInt955 = -1;
|
||||
anInt989 = -1;
|
||||
anInt974 = -1;
|
||||
anInt969 = 0;
|
||||
anInt994 = 0;
|
||||
anInt990 = -1;
|
||||
anInt993 = 0;
|
||||
}
|
||||
|
||||
public static void main(String...args) throws Throwable {
|
||||
GameWorld.prompt(false);
|
||||
RenderAnimationDefinition def = RenderAnimationDefinition.forId(1426);
|
||||
System.out.println("size: " + def.getClass().getDeclaredFields().length);
|
||||
for (Field f : def.getClass().getDeclaredFields()) {
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
if (f.getType().isArray()) {
|
||||
Object object = f.get(def);
|
||||
if (object != null) {
|
||||
int length = Array.getLength(object);
|
||||
System.out.print(f.getName() + ", [");
|
||||
for (int i = 0; i < length; i++) {
|
||||
System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]"));
|
||||
}
|
||||
System.out.println();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
System.out.println(f.getName() + ", " + f.get(def));
|
||||
}
|
||||
}
|
||||
for (Field f : def.getClass().getSuperclass().getDeclaredFields()) {
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
if (f.getType().isArray()) {
|
||||
Object object = f.get(def);
|
||||
if (object != null) {
|
||||
int length = Array.getLength(object);
|
||||
System.out.print(f.getName() + ", [");
|
||||
for (int i = 0; i < length; i++) {
|
||||
System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]"));
|
||||
}
|
||||
System.out.println();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
System.out.println(f.getName() + ", " + f.get(def));
|
||||
}
|
||||
}
|
||||
//Link arios editor source to this project on eclipse!
|
||||
// org.arioseditor.workspace.WorkSpace.getWorkSpace().getSettings().setCachePath(System.getProperty("user.home") + "/Dropbox/Arios V2/Source/data/cache");
|
||||
// org.arioseditor.workspace.WorkSpace.getWorkSpace().getSettings().setStorePath(System.getProperty("user.home") + "/Dropbox/Arios V2/Arios 530/data/store");
|
||||
// org.arioseditor.workspace.WorkSpace.getWorkSpace().init();
|
||||
//
|
||||
// roar:
|
||||
// for (int itemId = 0; itemId < ItemDefinition.getDefinitions().size(); itemId++) {
|
||||
// Item item = (Item) EditorType.ITEM.getTab().getNodes().get(itemId);
|
||||
// if (item == null) {
|
||||
// continue;
|
||||
// }
|
||||
// Integer standAnimation = (Integer) item.getConfigValue(ItemConfiguration.STAND_ANIM);
|
||||
// Integer walkAnimation = (Integer) item.getConfigValue(ItemConfiguration.WALK_ANIM);
|
||||
// Integer runAnimation = (Integer) item.getConfigValue(ItemConfiguration.RUN_ANIM);
|
||||
// if (standAnimation != null) {
|
||||
// for (int id = 0; id < 1431; id++) {
|
||||
// RenderAnimationDefinition def = RenderAnimationDefinition.forId(id);
|
||||
// if (def.walkAnimationId == walkAnimation && def.runAnimationId == runAnimation && def.standAnimationId == standAnimation) {
|
||||
// if (id != 1428) {
|
||||
// System.out.println("Item " + itemId + " has render animation " + id + "!");
|
||||
// item.setConfig("render_anim", (short) id);
|
||||
// }
|
||||
// continue roar;
|
||||
// }
|
||||
// }
|
||||
// item.setConfig("render_anim", (short) 1426);
|
||||
// System.out.println("Could not find render animation for item " + itemId + "!");
|
||||
// }
|
||||
// }
|
||||
// EditorType.ITEM.getTab().preSave();
|
||||
// EditorType.ITEM.getTab().save();
|
||||
// WorkSpace.getWorkSpace().save(true);
|
||||
// System.out.println("Done!");
|
||||
// System.exit(0);
|
||||
}
|
||||
}
|
||||
365
09HDscape-server/src/org/crandor/cache/def/impl/test.txt
vendored
Normal file
365
09HDscape-server/src/org/crandor/cache/def/impl/test.txt
vendored
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
private void readValues(int i, InputStream stream, int opcode) {
|
||||
if (opcode != 1 && opcode != 5) {
|
||||
if (opcode != 2) {
|
||||
if (opcode != 14) {
|
||||
if (opcode != 15) {
|
||||
if (opcode == 17) {
|
||||
projectileCliped = false;
|
||||
clipType = 0;
|
||||
} else if (opcode != 18) {
|
||||
if (opcode == 19)
|
||||
secondInt = stream.readUnsignedByte();
|
||||
else if (opcode == 21)
|
||||
aByte3912 = (byte) 1;
|
||||
else if (opcode != 22) {
|
||||
if (opcode != 23) {
|
||||
if (opcode != 24) {
|
||||
if (opcode == 27)
|
||||
clipType = 1;
|
||||
else if (opcode == 28)
|
||||
anInt3892 = (stream
|
||||
.readUnsignedByte() << 2);
|
||||
else if (opcode != 29) {
|
||||
if (opcode != 39) {
|
||||
if (opcode < 30 || opcode >= 35) {
|
||||
if (opcode == 40) {
|
||||
int i_53_ = (stream
|
||||
.readUnsignedByte());
|
||||
originalColors = new short[i_53_];
|
||||
modifiedColors = new short[i_53_];
|
||||
for (int i_54_ = 0; i_53_ > i_54_; i_54_++) {
|
||||
originalColors[i_54_] = (short) (stream
|
||||
.readUnsignedShort());
|
||||
modifiedColors[i_54_] = (short) (stream
|
||||
.readUnsignedShort());
|
||||
}
|
||||
} else if (opcode != 41) {
|
||||
if (opcode != 42) {
|
||||
if (opcode != 62) {
|
||||
if (opcode != 64) {
|
||||
if (opcode == 65)
|
||||
anInt3902 = stream
|
||||
.readUnsignedShort();
|
||||
else if (opcode != 66) {
|
||||
if (opcode != 67) {
|
||||
if (opcode == 69)
|
||||
anInt3925 = stream
|
||||
.readUnsignedByte();
|
||||
else if (opcode != 70) {
|
||||
if (opcode == 71)
|
||||
anInt3889 = stream
|
||||
.readShort() << 2;
|
||||
else if (opcode != 72) {
|
||||
if (opcode == 73)
|
||||
secondBool = true;
|
||||
else if (opcode == 74)
|
||||
notCliped = true;
|
||||
else if (opcode != 75) {
|
||||
if (opcode != 77
|
||||
&& opcode != 92) {
|
||||
if (opcode == 78) {
|
||||
anInt3860 = stream
|
||||
.readUnsignedShort();
|
||||
anInt3904 = stream
|
||||
.readUnsignedByte();
|
||||
} else if (opcode != 79) {
|
||||
if (opcode == 81) {
|
||||
aByte3912 = (byte) 2;
|
||||
anInt3882 = 256 * stream
|
||||
.readUnsignedByte();
|
||||
} else if (opcode != 82) {
|
||||
if (opcode == 88)
|
||||
aBoolean3853 = false;
|
||||
else if (opcode != 89) {
|
||||
if (opcode == 90)
|
||||
aBoolean3870 = true;
|
||||
else if (opcode != 91) {
|
||||
if (opcode != 93) {
|
||||
if (opcode == 94)
|
||||
aByte3912 = (byte) 4;
|
||||
else if (opcode != 95) {
|
||||
if (opcode != 96) {
|
||||
if (opcode == 97)
|
||||
aBoolean3866 = true;
|
||||
else if (opcode == 98)
|
||||
aBoolean3923 = true;
|
||||
else if (opcode == 99) {
|
||||
anInt3857 = stream
|
||||
.readUnsignedByte();
|
||||
anInt3835 = stream
|
||||
.readUnsignedShort();
|
||||
} else if (opcode == 100) {
|
||||
anInt3844 = stream
|
||||
.readUnsignedByte();
|
||||
anInt3913 = stream
|
||||
.readUnsignedShort();
|
||||
} else if (opcode != 101) {
|
||||
if (opcode == 102)
|
||||
anInt3838 = stream
|
||||
.readUnsignedShort();
|
||||
else if (opcode == 103)
|
||||
thirdInt = 0;
|
||||
else if (opcode != 104) {
|
||||
if (opcode == 105)
|
||||
aBoolean3906 = true;
|
||||
else if (opcode == 106) {
|
||||
int i_55_ = stream
|
||||
.readUnsignedByte();
|
||||
anIntArray3869 = new int[i_55_];
|
||||
anIntArray3833 = new int[i_55_];
|
||||
for (int i_56_ = 0; i_56_ < i_55_; i_56_++) {
|
||||
anIntArray3833[i_56_] = stream
|
||||
.readUnsignedShort();
|
||||
int i_57_ = stream
|
||||
.readUnsignedByte();
|
||||
anIntArray3869[i_56_] = i_57_;
|
||||
anInt3881 += i_57_;
|
||||
}
|
||||
} else if (opcode == 107)
|
||||
anInt3851 = stream
|
||||
.readUnsignedShort();
|
||||
else if (opcode >= 150
|
||||
&& opcode < 155) {
|
||||
options[opcode
|
||||
+ -150] = stream
|
||||
.readString();
|
||||
/*if (!loader.showOptions)
|
||||
options[opcode + -150] = null;*/
|
||||
} else if (opcode != 160) {
|
||||
if (opcode == 162) {
|
||||
aByte3912 = (byte) 3;
|
||||
anInt3882 = stream
|
||||
.readInt();
|
||||
} else if (opcode == 163) {
|
||||
aByte3847 = (byte) stream
|
||||
.readByte();
|
||||
aByte3849 = (byte) stream
|
||||
.readByte();
|
||||
aByte3837 = (byte) stream
|
||||
.readByte();
|
||||
aByte3914 = (byte) stream
|
||||
.readByte();
|
||||
} else if (opcode != 164) {
|
||||
if (opcode != 165) {
|
||||
if (opcode != 166) {
|
||||
if (opcode == 167)
|
||||
anInt3921 = stream
|
||||
.readUnsignedShort();
|
||||
else if (opcode != 168) {
|
||||
if (opcode == 169) {
|
||||
aBoolean3845 = true;
|
||||
//added opcode
|
||||
}else if (opcode == 170) {
|
||||
int anInt3383 = stream.readUnsignedSmart();
|
||||
//added opcode
|
||||
}else if (opcode == 171) {
|
||||
int anInt3362 = stream.readUnsignedSmart();
|
||||
//added opcode
|
||||
}else if (opcode == 173) {
|
||||
int anInt3302 = stream.readUnsignedShort();
|
||||
int anInt3336 = stream.readUnsignedShort();
|
||||
//added opcode
|
||||
}else if (opcode == 177) {
|
||||
boolean ub = true;
|
||||
//added opcode
|
||||
}else if (opcode == 178) {
|
||||
int db = stream.readUnsignedByte();
|
||||
} else if (opcode == 249) {
|
||||
int i_58_ = stream
|
||||
.readUnsignedByte();
|
||||
if (aClass194_3922 == null) {
|
||||
/*int i_59_ = Class307
|
||||
.method3331(
|
||||
(byte) -117,
|
||||
i_58_);
|
||||
aClass194_3922 = new HashTable(
|
||||
i_59_);*/
|
||||
}
|
||||
for (int i_60_ = 0; i_60_ < i_58_; i_60_++) {
|
||||
boolean bool = stream
|
||||
.readUnsignedByte() == 1;
|
||||
int i_61_ = stream.read24BitInt();
|
||||
Object class279;
|
||||
if (!bool)
|
||||
/*class279 = new IntegerNode(*/
|
||||
stream
|
||||
.readInt();//);
|
||||
else
|
||||
/*class279 = new Class279_Sub4(*/
|
||||
stream
|
||||
.readString();//);
|
||||
/*aClass194_3922
|
||||
.method1598(
|
||||
(long) i_61_,
|
||||
-125,
|
||||
class279);*/
|
||||
}
|
||||
}
|
||||
} else
|
||||
aBoolean3894 = true;
|
||||
} else
|
||||
anInt3877 = stream
|
||||
.readShort();
|
||||
} else
|
||||
anInt3875 = stream
|
||||
.readShort();
|
||||
} else
|
||||
anInt3834 = stream
|
||||
.readShort();
|
||||
} else {
|
||||
int i_62_ = stream
|
||||
.readUnsignedByte();
|
||||
anIntArray3908 = new int[i_62_];
|
||||
for (int i_63_ = 0; i_62_ > i_63_; i_63_++)
|
||||
anIntArray3908[i_63_] = stream
|
||||
.readUnsignedShort();
|
||||
}
|
||||
} else
|
||||
anInt3865 = stream
|
||||
.readUnsignedByte();
|
||||
} else
|
||||
anInt3850 = stream
|
||||
.readUnsignedByte();
|
||||
} else
|
||||
aBoolean3924 = true;
|
||||
} else {
|
||||
aByte3912 = (byte) 5;
|
||||
anInt3882 = stream
|
||||
.readShort();
|
||||
}
|
||||
} else {
|
||||
aByte3912 = (byte) 3;
|
||||
anInt3882 = stream
|
||||
.readUnsignedShort();
|
||||
}
|
||||
} else
|
||||
aBoolean3873 = true;
|
||||
} else
|
||||
aBoolean3895 = false;
|
||||
} else
|
||||
aBoolean3891 = true;
|
||||
} else {
|
||||
anInt3900 = stream
|
||||
.readUnsignedShort();
|
||||
anInt3905 = stream
|
||||
.readUnsignedShort();
|
||||
anInt3904 = stream
|
||||
.readUnsignedByte();
|
||||
int i_64_ = stream
|
||||
.readUnsignedByte();
|
||||
anIntArray3859 = new int[i_64_];
|
||||
for (int i_65_ = 0; i_65_ < i_64_; i_65_++)
|
||||
anIntArray3859[i_65_] = stream
|
||||
.readUnsignedShort();
|
||||
}
|
||||
} else {
|
||||
configFileId = stream
|
||||
.readUnsignedShort();
|
||||
if (configFileId == 65535)
|
||||
configFileId = -1;
|
||||
configId = stream
|
||||
.readUnsignedShort();
|
||||
if (configId == 65535)
|
||||
configId = -1;
|
||||
int i_66_ = -1;
|
||||
if (opcode == 92) {
|
||||
i_66_ = stream
|
||||
.readUnsignedShort();
|
||||
if (i_66_ == 65535)
|
||||
i_66_ = -1;
|
||||
}
|
||||
int i_67_ = stream
|
||||
.readUnsignedByte();
|
||||
childrenIds = new int[i_67_
|
||||
- -2];
|
||||
for (int i_68_ = 0; i_67_ >= i_68_; i_68_++) {
|
||||
childrenIds[i_68_] = stream
|
||||
.readUnsignedShort();
|
||||
if (childrenIds[i_68_] == 65535)
|
||||
childrenIds[i_68_] = -1;
|
||||
}
|
||||
childrenIds[i_67_ + 1] = i_66_;
|
||||
}
|
||||
} else
|
||||
anInt3855 = stream
|
||||
.readUnsignedByte();
|
||||
} else
|
||||
anInt3915 = stream
|
||||
.readShort() << 2;
|
||||
} else
|
||||
anInt3883 = stream
|
||||
.readShort() << 2;
|
||||
} else
|
||||
anInt3917 = stream
|
||||
.readUnsignedShort();
|
||||
} else
|
||||
anInt3841 = stream
|
||||
.readUnsignedShort();
|
||||
} else
|
||||
aBoolean3872 = false;
|
||||
} else
|
||||
aBoolean3839 = true;
|
||||
} else {
|
||||
int i_69_ = (stream
|
||||
.readUnsignedByte());
|
||||
aByteArray3858 = (new byte[i_69_]);
|
||||
for (int i_70_ = 0; i_70_ < i_69_; i_70_++)
|
||||
aByteArray3858[i_70_] = (byte) (stream
|
||||
.readByte());
|
||||
}
|
||||
} else {
|
||||
int i_71_ = (stream
|
||||
.readUnsignedByte());
|
||||
aShortArray3920 = new short[i_71_];
|
||||
aShortArray3919 = new short[i_71_];
|
||||
for (int i_72_ = 0; i_71_ > i_72_; i_72_++) {
|
||||
aShortArray3920[i_72_] = (short) (stream
|
||||
.readUnsignedShort());
|
||||
aShortArray3919[i_72_] = (short) (stream
|
||||
.readUnsignedShort());
|
||||
}
|
||||
}
|
||||
} else
|
||||
options[-30
|
||||
+ opcode] = (stream
|
||||
.readString());
|
||||
} else
|
||||
anInt3840 = (stream.readByte() * 5);
|
||||
} else
|
||||
anInt3878 = stream.readByte();
|
||||
} else {
|
||||
anInt3876 = stream.readUnsignedShort();
|
||||
if (anInt3876 == 65535)
|
||||
anInt3876 = -1;
|
||||
}
|
||||
} else
|
||||
thirdInt = 1;
|
||||
} else
|
||||
aBoolean3867 = true;
|
||||
} else
|
||||
projectileCliped = false;
|
||||
} else
|
||||
sizeY = stream.readUnsignedByte();
|
||||
} else
|
||||
sizeX = stream.readUnsignedByte();
|
||||
} else
|
||||
name = stream.readString();
|
||||
} else {
|
||||
boolean aBoolean1162 = false;
|
||||
if (opcode == 5 && aBoolean1162)
|
||||
method3297(stream);
|
||||
int i_73_ = stream.readUnsignedByte();
|
||||
anIntArrayArray3916 = new int[i_73_][];
|
||||
aByteArray3899 = new byte[i_73_];
|
||||
for (int i_74_ = 0; i_74_ < i_73_; i_74_++) {
|
||||
aByteArray3899[i_74_] = (byte) stream.readByte();
|
||||
int i_75_ = stream.readUnsignedByte();
|
||||
anIntArrayArray3916[i_74_] = new int[i_75_];
|
||||
for (int i_76_ = 0; i_75_ > i_76_; i_76_++)
|
||||
anIntArrayArray3916[i_74_][i_76_] = stream
|
||||
.readUnsignedShort();
|
||||
}
|
||||
if (opcode == 5 && !aBoolean1162)
|
||||
method3297(stream);
|
||||
}
|
||||
}
|
||||
47
09HDscape-server/src/org/crandor/cache/gzip/GZipDecompressor.java
vendored
Normal file
47
09HDscape-server/src/org/crandor/cache/gzip/GZipDecompressor.java
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package org.crandor.cache.gzip;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
public class GZipDecompressor {
|
||||
|
||||
private static final Inflater inflaterInstance = new Inflater(true);
|
||||
|
||||
public static final void decompress(ByteBuffer buffer, byte data[]) {
|
||||
synchronized (inflaterInstance) {
|
||||
if (~buffer.get(buffer.position()) != -32 || buffer.get(buffer.position() + 1) != -117) {
|
||||
data = null;
|
||||
// throw new RuntimeException("Invalid GZIP header!");
|
||||
}
|
||||
try {
|
||||
inflaterInstance.setInput(buffer.array(), buffer.position() + 10, -buffer.position() - 18 + buffer.limit());
|
||||
inflaterInstance.inflate(data);
|
||||
} catch (Exception e) {
|
||||
// inflaterInstance.reset();
|
||||
data = null;
|
||||
// throw new RuntimeException("Invalid GZIP compressed data!");
|
||||
}
|
||||
inflaterInstance.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean decompress(byte[] compressed, byte data[], int offset, int length) {
|
||||
synchronized (inflaterInstance) {
|
||||
if (data[offset] != 31 || data[offset + 1] != -117)
|
||||
return false;
|
||||
// throw new RuntimeException("Invalid GZIP header!");
|
||||
try {
|
||||
inflaterInstance.setInput(data, offset + 10, -offset - 18 + length);
|
||||
inflaterInstance.inflate(compressed);
|
||||
} catch (Exception e) {
|
||||
inflaterInstance.reset();
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
// throw new RuntimeException("Invalid GZIP compressed data!");
|
||||
}
|
||||
inflaterInstance.reset();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
109
09HDscape-server/src/org/crandor/cache/misc/Container.java
vendored
Normal file
109
09HDscape-server/src/org/crandor/cache/misc/Container.java
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
package org.crandor.cache.misc;
|
||||
|
||||
/**
|
||||
* A container.
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public class Container {
|
||||
|
||||
/**
|
||||
* The version.
|
||||
*/
|
||||
private int version;
|
||||
|
||||
/**
|
||||
* The CRC.
|
||||
*/
|
||||
private int crc;
|
||||
|
||||
/**
|
||||
* The name hash.
|
||||
*/
|
||||
private int nameHash;
|
||||
|
||||
/**
|
||||
* If updated.
|
||||
*/
|
||||
private boolean updated;
|
||||
|
||||
/**
|
||||
* Construct a new container.
|
||||
*/
|
||||
public Container() {
|
||||
nameHash = -1;
|
||||
version = -1;
|
||||
crc = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version.
|
||||
* @param version
|
||||
*/
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the version.
|
||||
*/
|
||||
public void updateVersion() {
|
||||
version++;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version.
|
||||
* @return The version.
|
||||
*/
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next version.
|
||||
* @return The next version.
|
||||
*/
|
||||
public int getNextVersion() {
|
||||
return updated ? version : version + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CRC.
|
||||
* @param crc The cRC.
|
||||
*/
|
||||
public void setCrc(int crc) {
|
||||
this.crc = crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CRC.
|
||||
* @return The CRC.
|
||||
*/
|
||||
public int getCrc() {
|
||||
return crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name hash.
|
||||
* @param nameHash The name hash.
|
||||
*/
|
||||
public void setNameHash(int nameHash) {
|
||||
this.nameHash = nameHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name hash.
|
||||
* @return The name hash.
|
||||
*/
|
||||
public int getNameHash() {
|
||||
return nameHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* If is updated.
|
||||
* @return If is updated.
|
||||
*/
|
||||
public boolean isUpdated() {
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
228
09HDscape-server/src/org/crandor/cache/misc/ContainersInformation.java
vendored
Normal file
228
09HDscape-server/src/org/crandor/cache/misc/ContainersInformation.java
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
package org.crandor.cache.misc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.crandor.cache.bzip2.BZip2Decompressor;
|
||||
import org.crandor.cache.gzip.GZipDecompressor;
|
||||
|
||||
/**
|
||||
* A class holding the containers information.
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public final class ContainersInformation {
|
||||
|
||||
/**
|
||||
* The information container.
|
||||
*/
|
||||
private Container informationContainer;
|
||||
|
||||
/**
|
||||
* The protocol.
|
||||
*/
|
||||
private int protocol;
|
||||
|
||||
/**
|
||||
* The revision.
|
||||
*/
|
||||
private int revision;
|
||||
|
||||
/**
|
||||
* The container indexes.
|
||||
*/
|
||||
private int[] containersIndexes;
|
||||
|
||||
/**
|
||||
* The containers.
|
||||
*/
|
||||
private FilesContainer[] containers;
|
||||
|
||||
/**
|
||||
* If files have to be named.
|
||||
*/
|
||||
private boolean filesNamed;
|
||||
|
||||
/**
|
||||
* If it has to be whirpool.
|
||||
*/
|
||||
private boolean whirpool;
|
||||
|
||||
/**
|
||||
* The data.
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
/**
|
||||
* Construct a new containers information.
|
||||
* @param informationContainerPackedData The information container data
|
||||
* packed.
|
||||
*/
|
||||
public ContainersInformation(byte[] informationContainerPackedData) {
|
||||
this.data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.length);
|
||||
informationContainer = new Container();
|
||||
informationContainer.setVersion((informationContainerPackedData[informationContainerPackedData.length - 2] << 8 & 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.length] & 0xff));
|
||||
CRC32 crc32 = new CRC32();
|
||||
crc32.update(informationContainerPackedData);
|
||||
informationContainer.setCrc((int) crc32.getValue());
|
||||
decodeContainersInformation(unpackCacheContainer(informationContainerPackedData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks a container.
|
||||
* @param packedData The packed container data.
|
||||
* @return The unpacked data.
|
||||
*/
|
||||
public static final byte[] unpackCacheContainer(byte[] packedData) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(packedData);
|
||||
int compression = buffer.get() & 0xFF;
|
||||
int containerSize = buffer.getInt();
|
||||
if (containerSize < 0 || containerSize > 5000000) {
|
||||
return null;
|
||||
// throw new RuntimeException();
|
||||
}
|
||||
if (compression == 0) {
|
||||
byte unpacked[] = new byte[containerSize];
|
||||
buffer.get(unpacked, 0, containerSize);
|
||||
return unpacked;
|
||||
}
|
||||
int decompressedSize = buffer.getInt();
|
||||
if (decompressedSize < 0 || decompressedSize > 20000000) {
|
||||
return null;
|
||||
// throw new RuntimeException();
|
||||
}
|
||||
byte decompressedData[] = new byte[decompressedSize];
|
||||
if (compression == 1) {
|
||||
BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9);
|
||||
} else {
|
||||
GZipDecompressor.decompress(buffer, decompressedData);
|
||||
}
|
||||
return decompressedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container indexes.
|
||||
* @return The container indexes.
|
||||
*/
|
||||
public int[] getContainersIndexes() {
|
||||
return containersIndexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the containers.
|
||||
* @return The containers.
|
||||
*/
|
||||
public FilesContainer[] getContainers() {
|
||||
return containers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information container.
|
||||
* @return The information container.
|
||||
*/
|
||||
public Container getInformationContainer() {
|
||||
return informationContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the revision.
|
||||
* @return The revision.
|
||||
*/
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the containers information.
|
||||
* @param data The data.
|
||||
*/
|
||||
public void decodeContainersInformation(byte[] data) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
protocol = buffer.get() & 0xFF;
|
||||
if (protocol != 5 && protocol != 6) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
revision = protocol < 6 ? 0 : buffer.getInt();
|
||||
int nameHash = buffer.get() & 0xFF;
|
||||
filesNamed = (0x1 & nameHash) != 0;
|
||||
whirpool = (0x2 & nameHash) != 0;
|
||||
containersIndexes = new int[buffer.getShort() & 0xFFFF];
|
||||
int lastIndex = -1;
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containersIndexes[index] = (buffer.getShort() & 0xFFFF) + (index == 0 ? 0 : containersIndexes[index - 1]);
|
||||
if (containersIndexes[index] > lastIndex) {
|
||||
lastIndex = containersIndexes[index];
|
||||
}
|
||||
}
|
||||
containers = new FilesContainer[lastIndex + 1];
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containers[containersIndexes[index]] = new FilesContainer();
|
||||
}
|
||||
if (filesNamed) {
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containers[containersIndexes[index]].setNameHash(buffer.getInt());
|
||||
}
|
||||
}
|
||||
byte[][] filesHashes = null;
|
||||
if (whirpool) {
|
||||
filesHashes = new byte[containers.length][];
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
filesHashes[containersIndexes[index]] = new byte[64];
|
||||
buffer.get(filesHashes[containersIndexes[index]], 0, 64);
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containers[containersIndexes[index]].setCrc(buffer.getInt());
|
||||
}
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containers[containersIndexes[index]].setVersion(buffer.getInt());
|
||||
}
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
containers[containersIndexes[index]].setFilesIndexes(new int[buffer.getShort() & 0xFFFF]);
|
||||
}
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
int lastFileIndex = -1;
|
||||
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
|
||||
containers[containersIndexes[index]].getFilesIndexes()[fileIndex] = (buffer.getShort() & 0xFFFF) + (fileIndex == 0 ? 0 : containers[containersIndexes[index]].getFilesIndexes()[fileIndex - 1]);
|
||||
if (containers[containersIndexes[index]].getFilesIndexes()[fileIndex] > lastFileIndex) {
|
||||
lastFileIndex = containers[containersIndexes[index]].getFilesIndexes()[fileIndex];
|
||||
}
|
||||
}
|
||||
containers[containersIndexes[index]].setFiles(new Container[lastFileIndex + 1]);
|
||||
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
|
||||
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]] = new Container();
|
||||
}
|
||||
}
|
||||
if (whirpool) {
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
|
||||
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setVersion(filesHashes[containersIndexes[index]][containers[containersIndexes[index]].getFilesIndexes()[fileIndex]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filesNamed) {
|
||||
for (int index = 0; index < containersIndexes.length; index++) {
|
||||
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
|
||||
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setNameHash(buffer.getInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If is whirpool.
|
||||
* @return If is whirpool {@code true}.
|
||||
*/
|
||||
public boolean isWhirpool() {
|
||||
return whirpool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data.
|
||||
* @return The data.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
57
09HDscape-server/src/org/crandor/cache/misc/FilesContainer.java
vendored
Normal file
57
09HDscape-server/src/org/crandor/cache/misc/FilesContainer.java
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package org.crandor.cache.misc;
|
||||
|
||||
/**
|
||||
* A class holding the file containers.
|
||||
* @author Dragonkk
|
||||
*/
|
||||
public final class FilesContainer extends Container {
|
||||
|
||||
/**
|
||||
* The file indexes.
|
||||
*/
|
||||
private int[] filesIndexes;
|
||||
|
||||
/**
|
||||
* The files.
|
||||
*/
|
||||
private Container[] files;
|
||||
|
||||
/**
|
||||
* Construct a new files container.
|
||||
*/
|
||||
public FilesContainer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the files.
|
||||
* @param containers The files.
|
||||
*/
|
||||
public void setFiles(Container[] containers) {
|
||||
this.files = containers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the files.
|
||||
* @return The files.
|
||||
*/
|
||||
public Container[] getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file indexes.
|
||||
* @param containersIndexes The file indexes.
|
||||
*/
|
||||
public void setFilesIndexes(int[] containersIndexes) {
|
||||
this.filesIndexes = containersIndexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file indexes.
|
||||
* @return The file indexes.
|
||||
*/
|
||||
public int[] getFilesIndexes() {
|
||||
return filesIndexes;
|
||||
}
|
||||
}
|
||||
39
09HDscape-server/src/org/crandor/cache/misc/buffer/BufferInputStream.java
vendored
Normal file
39
09HDscape-server/src/org/crandor/cache/misc/buffer/BufferInputStream.java
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package org.crandor.cache.misc.buffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Handles the reading of data from a byte buffer.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BufferInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* The buffer to write on.
|
||||
*/
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
/**
|
||||
* The buffer input stream.
|
||||
* @param buffer The buffer.
|
||||
*/
|
||||
public BufferInputStream(ByteBuffer buffer) throws IOException {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return buffer.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the buffer.
|
||||
* @return The buffer.
|
||||
*/
|
||||
public ByteBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
57
09HDscape-server/src/org/crandor/cache/misc/buffer/BufferOutputStream.java
vendored
Normal file
57
09HDscape-server/src/org/crandor/cache/misc/buffer/BufferOutputStream.java
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package org.crandor.cache.misc.buffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Handles the writing of data on a byte buffer.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BufferOutputStream extends OutputStream {
|
||||
|
||||
/**
|
||||
* The buffer to write on.
|
||||
*/
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BufferOutputStream} {@code Object}.
|
||||
* @param buffer The buffer to write on.
|
||||
* @throws IOException When an I/O exception occurs.
|
||||
* @throws SecurityException If a security manager exists and its
|
||||
* checkPermission method denies enabling subclassing.
|
||||
*/
|
||||
public BufferOutputStream(ByteBuffer buffer) throws IOException, SecurityException {
|
||||
super();
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
buffer.put((byte) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the buffer.
|
||||
* @return The buffer.
|
||||
*/
|
||||
public ByteBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
181
09HDscape-server/src/org/crandor/cache/misc/buffer/ByteBufferUtils.java
vendored
Normal file
181
09HDscape-server/src/org/crandor/cache/misc/buffer/ByteBufferUtils.java
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
package org.crandor.cache.misc.buffer;
|
||||
|
||||
import java.io.ObjectInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Holds utility methods for reading/writing a byte buffer.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ByteBufferUtils {
|
||||
|
||||
/**
|
||||
* Gets a string from the byte buffer.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The string.
|
||||
*/
|
||||
public static String getString(ByteBuffer buffer) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte b;
|
||||
while ((b = buffer.get()) != 0) {
|
||||
sb.append((char) b);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a string on the byte buffer.
|
||||
* @param s The string to put.
|
||||
* @param buffer The byte buffer.
|
||||
*/
|
||||
public static void putString(String s, ByteBuffer buffer) {
|
||||
buffer.put(s.getBytes()).put((byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string from the byte buffer.
|
||||
* @param s The string.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The string.
|
||||
*/
|
||||
public static ByteBuffer putGJ2String(String s, ByteBuffer buffer) {
|
||||
byte[] packed = new byte[256];
|
||||
int length = packGJString2(0, packed, s);
|
||||
return buffer.put((byte) 0).put(packed, 0, length).put((byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the XTEA encryption.
|
||||
* @param keys The keys.
|
||||
* @param start The start index.
|
||||
* @param end The end index.
|
||||
* @param buffer The byte buffer.
|
||||
*/
|
||||
public static void decodeXTEA(int[] keys, int start, int end, ByteBuffer buffer) {
|
||||
int l = buffer.position();
|
||||
buffer.position(start);
|
||||
int length = (end - start) / 8;
|
||||
for (int i = 0; i < length; i++) {
|
||||
int firstInt = buffer.getInt();
|
||||
int secondInt = buffer.getInt();
|
||||
int sum = 0xc6ef3720;
|
||||
int delta = 0x9e3779b9;
|
||||
for (int j = 32; j-- > 0;) {
|
||||
secondInt -= keys[(sum & 0x1c84) >>> 11] + sum ^ (firstInt >>> 5 ^ firstInt << 4) + firstInt;
|
||||
sum -= delta;
|
||||
firstInt -= (secondInt >>> 5 ^ secondInt << 4) + secondInt ^ keys[sum & 3] + sum;
|
||||
}
|
||||
buffer.position(buffer.position() - 8);
|
||||
buffer.putInt(firstInt);
|
||||
buffer.putInt(secondInt);
|
||||
}
|
||||
buffer.position(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a String to an Integer?
|
||||
* @param position The position.
|
||||
* @param buffer The buffer used.
|
||||
* @param string The String to convert.
|
||||
* @return The Integer.
|
||||
*/
|
||||
public static int packGJString2(int position, byte[] buffer, String string) {
|
||||
int length = string.length();
|
||||
int offset = position;
|
||||
for (int i = 0; length > i; i++) {
|
||||
int character = string.charAt(i);
|
||||
if (character > 127) {
|
||||
if (character > 2047) {
|
||||
buffer[offset++] = (byte) ((character | 919275) >> 12);
|
||||
buffer[offset++] = (byte) (128 | ((character >> 6) & 63));
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
} else {
|
||||
buffer[offset++] = (byte) ((character | 12309) >> 6);
|
||||
buffer[offset++] = (byte) (128 | (character & 63));
|
||||
}
|
||||
} else
|
||||
buffer[offset++] = (byte) character;
|
||||
}
|
||||
return offset - position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a tri-byte from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getTriByte(ByteBuffer buffer) {
|
||||
return ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a smart from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getSmart(ByteBuffer buffer) {
|
||||
int peek = buffer.get() & 0xFF;
|
||||
if (peek <= Byte.MAX_VALUE) {
|
||||
return peek;
|
||||
}
|
||||
return ((peek << 8) | (buffer.get() & 0xFF)) - 32768;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a smart from the buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
public static int getBigSmart(ByteBuffer buffer) {
|
||||
int value = 0;
|
||||
int current = getSmart(buffer);
|
||||
while (current == 32767) {
|
||||
current = getSmart(buffer);
|
||||
value += 32767;
|
||||
}
|
||||
value += current;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* *//**
|
||||
* Writes an object on the buffer.
|
||||
* @param buffer The buffer to write on.
|
||||
* @param o The object.
|
||||
*/
|
||||
/*
|
||||
* public static void putObject(ByteBuffer buffer, Object o) { ByteBuffer b;
|
||||
* try (ObjectOutputStream out = new ObjectOutputStream(new
|
||||
* BufferOutputStream(b = ByteBuffer.allocate(99999)))) {
|
||||
* out.writeObject(o); b.flip(); } catch (Throwable e) {
|
||||
* e.printStackTrace(); b = (ByteBuffer) ByteBuffer.allocate(0).flip(); }
|
||||
* buffer.putInt(b.remaining()); if (b.remaining() > 0) { buffer.put(b); } }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets an object from the byte buffer.
|
||||
* @param buffer The buffer.
|
||||
* @return The object.
|
||||
*/
|
||||
public static Object getObject(ByteBuffer buffer) {
|
||||
int length = buffer.getInt();
|
||||
if (length > 0) {
|
||||
byte[] bytes = new byte[length];
|
||||
buffer.get(bytes);
|
||||
try (ObjectInputStream str = new ObjectInputStream(new BufferInputStream(ByteBuffer.wrap(bytes)))) {
|
||||
return (Object) str.readObject();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ByteBufferUtils} {@code Object}.
|
||||
*/
|
||||
private ByteBufferUtils() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
/**
|
||||
* Used to generate component option settings.
|
||||
* @author Mangis
|
||||
*/
|
||||
public final class AccessMaskBuilder {
|
||||
|
||||
/**
|
||||
* Contains the value which should be sent in access mask packet.
|
||||
*/
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Sets default option setting.
|
||||
* @param allowed If the packet for the default option should be sent to the
|
||||
* server.
|
||||
*/
|
||||
public void allowDefaultOption(boolean allowed) {
|
||||
value &= ~(0x1);
|
||||
if (allowed) {
|
||||
value |= 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets right click option settings. If specified option is not allowed, it
|
||||
* will not appear in right click menu and the packet will not be send to
|
||||
* server when clicked.
|
||||
* @param optionId The option index.
|
||||
* @param show If the option is allowed.
|
||||
*/
|
||||
public void showMenuOption(int optionId, boolean show) {
|
||||
if (optionId < 0 || optionId > 9) {
|
||||
throw new IllegalArgumentException("Option index must be 0-9.");
|
||||
}
|
||||
value &= ~(0x1 << (optionId + 1));
|
||||
if (show) {
|
||||
value |= (0x1 << (optionId + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets use on option settings. If nothing is allowed then 'use' option will
|
||||
* not appear in right click menu.
|
||||
*/
|
||||
public void setUseOnSettings(boolean groundItems, boolean npcs, boolean objects, boolean otherPlayer, boolean selfPlayer, boolean component) {
|
||||
int useFlag = 0;
|
||||
if (groundItems) {
|
||||
useFlag |= 0x1;
|
||||
}
|
||||
if (npcs) {
|
||||
useFlag |= 0x2;
|
||||
}
|
||||
if (objects) {
|
||||
useFlag |= 0x4;
|
||||
}
|
||||
if (otherPlayer) {
|
||||
useFlag |= 0x8;
|
||||
}
|
||||
if (selfPlayer) {
|
||||
useFlag |= 0x10;
|
||||
}
|
||||
if (component) {
|
||||
useFlag |= 0x20;
|
||||
}
|
||||
value &= ~(127 << 7); // disable
|
||||
value |= useFlag << 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets interface events depth. For example, we have inventory interface
|
||||
* which is opened on gameframe interface (548) If depth is 1, then the
|
||||
* clicks in inventory will also invoke click event handler scripts on
|
||||
* gameframe interface.
|
||||
* @param depth The depth value.
|
||||
*/
|
||||
public void setInterfaceEventsDepth(int depth) {
|
||||
if (depth < 0 || depth > 7) {
|
||||
throw new IllegalArgumentException("depth must be 0-7.");
|
||||
}
|
||||
value &= ~(0x7 << 18);
|
||||
value |= (depth << 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags other component options being allowed to be used on this component.
|
||||
* @param allow If an option can be used on this component.
|
||||
*/
|
||||
public void allowUsage(boolean allow) {
|
||||
value &= ~(1 << 22);
|
||||
if (allow) {
|
||||
value |= (1 << 22);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value.
|
||||
* @return The value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* An event called when the interface gets closed.
|
||||
* @author Emperor
|
||||
*/
|
||||
public interface CloseEvent {
|
||||
|
||||
/**
|
||||
* Called when the interface gets closed.
|
||||
* @param player The player.
|
||||
* @param c The component.
|
||||
* @return {@code True} if successful, {@code false} if the component should
|
||||
* remain open.
|
||||
*/
|
||||
boolean close(Player player, Component c);
|
||||
|
||||
}
|
||||
178
09HDscape-server/src/org/crandor/game/component/Component.java
Normal file
178
09HDscape-server/src/org/crandor/game/component/Component.java
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.InterfaceManager;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.InterfaceContext;
|
||||
import org.crandor.net.packet.out.Interface;
|
||||
|
||||
/**
|
||||
* Represents a component.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public class Component {
|
||||
|
||||
/**
|
||||
* The component id.
|
||||
*/
|
||||
protected int id;
|
||||
|
||||
/**
|
||||
* The component definitions.
|
||||
*/
|
||||
protected final ComponentDefinition definition;
|
||||
|
||||
/**
|
||||
* The close event.
|
||||
*/
|
||||
protected CloseEvent closeEvent;
|
||||
|
||||
/**
|
||||
* The component plugin.
|
||||
*/
|
||||
protected ComponentPlugin plugin;
|
||||
|
||||
/**
|
||||
* If the component is hidden.
|
||||
*/
|
||||
private boolean hidden;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Component} {@code Object}.
|
||||
* @param id The component id.
|
||||
*/
|
||||
public Component(int id) {
|
||||
this.id = id;
|
||||
this.definition = ComponentDefinition.forId(id);
|
||||
this.plugin = definition.getPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the component.
|
||||
*/
|
||||
public void open(Player player) {
|
||||
InterfaceManager manager = player.getInterfaceManager();
|
||||
if (definition == null) {
|
||||
PacketRepository.send(Interface.class, new InterfaceContext(player, manager.getWindowPaneId(), manager.getDefaultChildId(), getId(), false));
|
||||
if (plugin != null) {
|
||||
plugin.open(player, this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (definition.getType() == InterfaceType.WINDOW_PANE) {
|
||||
return;
|
||||
}
|
||||
if (definition.getType() == InterfaceType.TAB) {
|
||||
PacketRepository.send(Interface.class, new InterfaceContext(player, definition.getWindowPaneId(manager.isResizable()), definition.getChildId(manager.isResizable()) + definition.getTabIndex(), getId(), definition.isWalkable()));
|
||||
if (plugin != null) {
|
||||
plugin.open(player, this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
PacketRepository.send(Interface.class, new InterfaceContext(player, definition.getWindowPaneId(manager.isResizable()), definition.getChildId(manager.isResizable()), getId(), definition.isWalkable()));
|
||||
if (plugin != null) {
|
||||
plugin.open(player, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the component.
|
||||
* @param player The player.
|
||||
* @return {@code True} if the component can be closed.
|
||||
*/
|
||||
public boolean close(Player player) {
|
||||
if (closeEvent != null && !closeEvent.close(player, this)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition.
|
||||
* @return The definition.
|
||||
*/
|
||||
public ComponentDefinition getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the closeEvent.
|
||||
* @return The closeEvent.
|
||||
*/
|
||||
public CloseEvent getCloseEvent() {
|
||||
return closeEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the closeEvent.
|
||||
* @param closeEvent The closeEvent to set.
|
||||
*/
|
||||
public Component setCloseEvent(CloseEvent closeEvent) {
|
||||
this.closeEvent = closeEvent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the component unclosable.
|
||||
* @param c The component.
|
||||
*/
|
||||
public static void setUnclosable(Player p, Component c) {
|
||||
p.setAttribute("close_c_", false);
|
||||
c.setCloseEvent(new CloseEvent() {
|
||||
@Override
|
||||
public boolean close(Player player, Component c) {
|
||||
if (!player.getAttribute("close_c_", false)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the plugin.
|
||||
* @param plugin the plugin.
|
||||
*/
|
||||
public void setPlugin(ComponentPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component plugin.
|
||||
* @return the plugin.
|
||||
*/
|
||||
public ComponentPlugin getPlugin() {
|
||||
if (plugin == null) {
|
||||
ComponentPlugin p = ComponentDefinition.forId(getId()).getPlugin();
|
||||
if ((plugin = p) != null) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hidden value.
|
||||
* @return The hidden.
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hidden value.
|
||||
* @param hidden The hidden to set.
|
||||
*/
|
||||
public void setHidden(boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the component definitions.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public final class ComponentDefinition {
|
||||
|
||||
/**
|
||||
* The component definitions mapping.
|
||||
*/
|
||||
private static final Map<Integer, ComponentDefinition> DEFINITIONS = new HashMap<Integer, ComponentDefinition>();
|
||||
|
||||
/**
|
||||
* The interface type.
|
||||
*/
|
||||
private InterfaceType type = InterfaceType.DEFAULT;
|
||||
|
||||
/**
|
||||
* The interface context.
|
||||
*/
|
||||
private boolean walkable;
|
||||
|
||||
/**
|
||||
* The tab index.
|
||||
*/
|
||||
private int tabIndex = -1;
|
||||
|
||||
/**
|
||||
* Represents the plugin handler.
|
||||
*/
|
||||
private ComponentPlugin plugin;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ComponentDefinition} {@code Object}.
|
||||
*/
|
||||
public ComponentDefinition() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the definition values from a result set.
|
||||
* @param set The result set.
|
||||
* @throws SQLException The exception if thrown.
|
||||
*/
|
||||
public ComponentDefinition parse(ResultSet set) throws SQLException {
|
||||
setType(InterfaceType.values()[set.getInt("interfaceType")]);
|
||||
setWalkable(set.getBoolean("walkable"));
|
||||
setTabIndex(set.getInt("tabIndex"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component definitions for the component id.
|
||||
* @param componentId The component id.
|
||||
* @return The component definitions.
|
||||
*/
|
||||
public static ComponentDefinition forId(int componentId) {
|
||||
ComponentDefinition def = DEFINITIONS.get(componentId);
|
||||
if (def == null) {
|
||||
DEFINITIONS.put(componentId, def = new ComponentDefinition());
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plugin to a definition.
|
||||
* @param id the id.
|
||||
* @param plugin the plugin.
|
||||
*/
|
||||
public static void put(int id, ComponentPlugin plugin) {
|
||||
ComponentDefinition.forId(id).setPlugin(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definitions mapping.
|
||||
* @return The definitions mapping.
|
||||
*/
|
||||
public static Map<Integer, ComponentDefinition> getDefinitions() {
|
||||
return DEFINITIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin.
|
||||
* @return The plugin.
|
||||
*/
|
||||
public ComponentPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the plugin.
|
||||
* @param plugin The plugin to set.
|
||||
*/
|
||||
public void setPlugin(ComponentPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the window pane id.
|
||||
* @param resizable If the player is using resizable mode.
|
||||
* @return The window pane id.
|
||||
*/
|
||||
public int getWindowPaneId(boolean resizable) {
|
||||
return resizable ? type.getResizablePaneId() : type.getFixedPaneId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child id.
|
||||
* @param resizable If the player is using resizable mode.
|
||||
* @return The child id.
|
||||
*/
|
||||
public int getChildId(boolean resizable) {
|
||||
return resizable ? type.getResizableChildId() : type.getFixedChildId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return the type
|
||||
*/
|
||||
public InterfaceType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the batype.
|
||||
* @param type the type to set.
|
||||
*/
|
||||
public void setType(InterfaceType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the walkable.
|
||||
* @return the walkable
|
||||
*/
|
||||
public boolean isWalkable() {
|
||||
return walkable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bawalkable.
|
||||
* @param walkable the walkable to set.
|
||||
*/
|
||||
public void setWalkable(boolean walkable) {
|
||||
this.walkable = walkable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tabIndex.
|
||||
* @return the tabIndex
|
||||
*/
|
||||
public int getTabIndex() {
|
||||
return tabIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the batabIndex.
|
||||
* @param tabIndex the tabIndex to set.
|
||||
*/
|
||||
public void setTabIndex(int tabIndex) {
|
||||
this.tabIndex = tabIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComponentDefinition [type=" + type + ", walkable=" + walkable + ", tabIndex=" + tabIndex + ", plugin=" + plugin + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle a component reward.
|
||||
* @author Vexia
|
||||
*/
|
||||
public abstract class ComponentPlugin implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
* Handles the interface interaction.
|
||||
* @param player The player.
|
||||
* @param component The component.
|
||||
* @param opcode The opcode.
|
||||
* @param slot The slot.
|
||||
* @param itemId The item id.
|
||||
* @return {@code True} if succesfully handled.
|
||||
*/
|
||||
public abstract boolean handle(final Player player, Component component, final int opcode, final int button, int slot, int itemId);
|
||||
|
||||
/**
|
||||
* Called when this component opens.
|
||||
* @param player The player
|
||||
* @param component The component opening.
|
||||
*/
|
||||
public void open(Player player, Component component) {}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package org.crandor.game.component;
|
||||
|
||||
/**
|
||||
* Represents an interface type.
|
||||
* @author Emperor
|
||||
*
|
||||
*/
|
||||
public enum InterfaceType {
|
||||
|
||||
/**
|
||||
* Default interface.
|
||||
*/
|
||||
DEFAULT(548, 746, 11, 6),
|
||||
|
||||
/**
|
||||
* Walkable interface.
|
||||
*/
|
||||
OVERLAY(548, 746, 5, 3),
|
||||
|
||||
/**
|
||||
* A tab interface.
|
||||
*/
|
||||
TAB(548, 746, 83, 93),
|
||||
|
||||
/**
|
||||
* The only tab to be shown (when this type is opened).
|
||||
*/
|
||||
SINGLE_TAB(548, 746, 80, 76),
|
||||
|
||||
/**
|
||||
* Chatbox dialogue interface.
|
||||
*/
|
||||
DIALOGUE(752, 752, 12, 12),
|
||||
|
||||
/**
|
||||
* A window pane.
|
||||
*/
|
||||
WINDOW_PANE(548, 746, 0, 0),
|
||||
|
||||
/**
|
||||
* Client script chatbox interface.
|
||||
*/
|
||||
CS_CHATBOX(752, 752, 6, 6),
|
||||
|
||||
/**
|
||||
* Chatbox interface.
|
||||
*/
|
||||
CHATBOX(752, 752, 8, 8),;
|
||||
|
||||
/**
|
||||
* The fixed window pane id.
|
||||
*/
|
||||
private final int fixedPaneId;
|
||||
|
||||
/**
|
||||
* The resizable window pane id.
|
||||
*/
|
||||
private final int resizablePaneId;
|
||||
|
||||
/**
|
||||
* The fixed child id.
|
||||
*/
|
||||
private final int fixedChildId;
|
||||
|
||||
/**
|
||||
* The resizable child id.
|
||||
*/
|
||||
private final int resizableChildId;
|
||||
|
||||
/**
|
||||
* Constructs a new {@Code InterfaceType} {@Code Object}
|
||||
* @param fixedPaneId The fixed window pane id.
|
||||
* @param resizablePaneId The resizable window pane id.
|
||||
* @param fixedChildId The fixed child id.
|
||||
* @param resizableChildId The resizable child id.
|
||||
*/
|
||||
private InterfaceType(int fixedPaneId, int resizablePaneId, int fixedChildId, int resizableChildId) {
|
||||
this.fixedPaneId = fixedPaneId;
|
||||
this.resizablePaneId = resizablePaneId;
|
||||
this.fixedChildId = fixedChildId;
|
||||
this.resizableChildId = resizableChildId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fixedPaneId.
|
||||
* @return the fixedPaneId
|
||||
*/
|
||||
public int getFixedPaneId() {
|
||||
return fixedPaneId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resizablePaneId.
|
||||
* @return the resizablePaneId
|
||||
*/
|
||||
public int getResizablePaneId() {
|
||||
return resizablePaneId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fixedChildId.
|
||||
* @return the fixedChildId
|
||||
*/
|
||||
public int getFixedChildId() {
|
||||
return fixedChildId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resizableChildId.
|
||||
* @return the resizableChildId
|
||||
*/
|
||||
public int getResizableChildId() {
|
||||
return resizableChildId;
|
||||
}
|
||||
}
|
||||
891
09HDscape-server/src/org/crandor/game/container/Container.java
Normal file
891
09HDscape-server/src/org/crandor/game/container/Container.java
Normal file
|
|
@ -0,0 +1,891 @@
|
|||
package org.crandor.game.container;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.GroundItemManager;
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a container which contains items.
|
||||
* @author Emperor
|
||||
*/
|
||||
public class Container {
|
||||
|
||||
/**
|
||||
* The item array. A crystalline
|
||||
*/
|
||||
private Item[] items;
|
||||
|
||||
/**
|
||||
* The capacity.
|
||||
*/
|
||||
private final int capacity;
|
||||
|
||||
/**
|
||||
* The current sort type.
|
||||
*/
|
||||
private SortType sortType;
|
||||
|
||||
/**
|
||||
* The current container type.
|
||||
*/
|
||||
private final ContainerType type;
|
||||
|
||||
/**
|
||||
* The current container event.
|
||||
*/
|
||||
private ContainerEvent event;
|
||||
|
||||
/**
|
||||
* The container listeners.
|
||||
*/
|
||||
private final List<ContainerListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Container} {@code Object}.
|
||||
* @param capacity The capacity.
|
||||
*/
|
||||
public Container(int capacity) {
|
||||
this(capacity, ContainerType.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Container.java} {@code Object}.
|
||||
* @param capacity the capacity.
|
||||
* @param items the items to add.
|
||||
*/
|
||||
public Container(int capacity, Item... items) {
|
||||
this(capacity);
|
||||
add(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Container} {@code Object}.
|
||||
* @param capacity The capacity.
|
||||
* @param type The container type.
|
||||
*/
|
||||
public Container(int capacity, ContainerType type) {
|
||||
this(capacity, type, SortType.ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Container} {@code Object}.
|
||||
* @param capacity The capacity.
|
||||
* @param type The container type.
|
||||
* @param sortType The sort type.
|
||||
*/
|
||||
public Container(int capacity, ContainerType type, SortType sortType) {
|
||||
this.capacity = capacity;
|
||||
this.type = type;
|
||||
this.items = new Item[capacity];
|
||||
this.sortType = sortType;
|
||||
this.event = new ContainerEvent(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a container listener.
|
||||
* @param listener The container listener.
|
||||
* @return This container instance, for chaining.
|
||||
*/
|
||||
public Container register(ContainerListener listener) {
|
||||
listeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the items.
|
||||
* @param items The items to add.
|
||||
* @return {@code True} if successfully added <b>all</b> items.
|
||||
*/
|
||||
public boolean add(Item... items) {
|
||||
boolean addedAll = true;
|
||||
for (Item item : items) {
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
if (!add(item, false)) {
|
||||
addedAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
update();
|
||||
return addedAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an item into a specific slot.
|
||||
* @param fromSlot The original slot of the item.
|
||||
* @param toSlot The slot to insert into.
|
||||
*/
|
||||
public void insert(int fromSlot, int toSlot) {
|
||||
insert(fromSlot, toSlot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an item into a specific slot.
|
||||
* @param fromSlot The original slot of the item.
|
||||
* @param toSlot The slot to insert into.
|
||||
* @param update If the container packets should be sent.
|
||||
*/
|
||||
public void insert(int fromSlot, int toSlot, boolean update) {
|
||||
Item temp = items[fromSlot];
|
||||
if (toSlot > fromSlot) {
|
||||
for (int i = fromSlot; i < toSlot; i++) {
|
||||
replace(get(i + 1), i, false);
|
||||
}
|
||||
} else if (fromSlot > toSlot) {
|
||||
for (int i = fromSlot; i > toSlot; i--) {
|
||||
replace(get(i - 1), i, false);
|
||||
}
|
||||
}
|
||||
replace(temp, toSlot, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to this container if full it goes to ground.
|
||||
* @param item the item.
|
||||
* @param player the player.
|
||||
* @param ground
|
||||
* @return {@code True} if added.
|
||||
*/
|
||||
public boolean add(final Item item, final Player player) {
|
||||
if (!add(item, true, -1)) {
|
||||
GroundItemManager.create(item, player);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to this container.
|
||||
* @param item The item.
|
||||
* @return {@code True} if the item got added.
|
||||
*/
|
||||
public boolean add(Item item) {
|
||||
return add(item, true, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to this container.
|
||||
* @param item The item to add.
|
||||
* @param fireListener If we should update.
|
||||
* @param preferredSlot The slot to add the item in, when possible.
|
||||
* @return {@code True} if the item got added.
|
||||
*/
|
||||
public boolean add(Item item, boolean fireListener) {
|
||||
return add(item, fireListener, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to this container.
|
||||
* @param item The item to add.
|
||||
* @param fireListener If we should update.
|
||||
* @param preferredSlot The slot to add the item in, when possible.
|
||||
* @return {@code True} if the item got added.
|
||||
*/
|
||||
public boolean add(Item item, boolean fireListener, int preferredSlot) {
|
||||
item = item.copy();
|
||||
int maximum = getMaximumAdd(item);
|
||||
if (maximum == 0) {
|
||||
return false;
|
||||
}
|
||||
// if (preferredSlot > -1 && items[preferredSlot] != null) {
|
||||
// preferredSlot = -1;
|
||||
// }
|
||||
if (item.getAmount() > maximum) {
|
||||
item.setAmount(maximum);
|
||||
}
|
||||
if (type != ContainerType.NEVER_STACK && (item.getDefinition().isStackable() || type == ContainerType.ALWAYS_STACK || type == ContainerType.SHOP)) {
|
||||
boolean hashBased = sortType == SortType.HASH;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i] != null) {
|
||||
if ((hashBased && items[i].getIdHash() == item.getIdHash()) || (!hashBased && items[i].getId() == item.getId())) {
|
||||
int totalCount = item.getAmount() + items[i].getAmount();
|
||||
items[i] = new Item(items[i].getId(), totalCount, item.getCharge());
|
||||
items[i].setIndex(i);
|
||||
event.flag(i, items[i]);
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
int slot = preferredSlot > -1 ? preferredSlot : freeSlot();
|
||||
if (slot == -1) {
|
||||
return false;
|
||||
}
|
||||
items[slot] = item;
|
||||
item.setIndex(slot);
|
||||
event.flag(slot, item);
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int slots = freeSlots();
|
||||
if (slots >= item.getAmount()) {
|
||||
for (int i = 0; i < item.getAmount(); i++) {
|
||||
int slot = i == 0 && preferredSlot > -1 ? preferredSlot : freeSlot();
|
||||
items[slot] = new Item(item.getId(), 1, item.getCharge());
|
||||
items[slot].setIndex(slot);
|
||||
event.flag(slot, items[slot]);
|
||||
}
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a set of items.
|
||||
* @param items The set of items.
|
||||
* @return {@code True} if all items got successfully removed.
|
||||
*/
|
||||
public boolean remove(Item... items) {
|
||||
boolean removedAll = true;
|
||||
for (Item item : items) {
|
||||
if (!remove(item, false)) {
|
||||
removedAll = false;
|
||||
}
|
||||
}
|
||||
update();
|
||||
return removedAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item.
|
||||
* @param item The item.
|
||||
* @return {@code True} if the item got removed, {@code false} if not.
|
||||
*/
|
||||
public boolean remove(Item item) {
|
||||
return remove(item, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item.
|
||||
* @param item The item to remove.
|
||||
* @param fireListener If the fire listener should be "notified".
|
||||
* @return {@code True} if the item got removed, <br> {@code false} if not.
|
||||
*/
|
||||
public boolean remove(Item item, boolean fireListener) {
|
||||
int slot = getSlot(item);
|
||||
if (slot != -1) {
|
||||
return remove(item, slot, fireListener);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from this container.
|
||||
* @param item The item.
|
||||
* @param slot The item slot.
|
||||
* @param fireListener If the fire listener should be "notified".
|
||||
* @return {@code True} if the item got removed, <br> {@code false} if the
|
||||
* item on the slot was null or the ids didn't match.
|
||||
*/
|
||||
public boolean remove(Item item, int slot, boolean fireListener) {
|
||||
Item oldItem = items[slot];
|
||||
if (oldItem == null || oldItem.getId() != item.getId()) {
|
||||
return false;
|
||||
}
|
||||
if (item.getAmount() < 1) {
|
||||
return true;
|
||||
}
|
||||
if (oldItem.getDefinition().isStackable() || type.equals(ContainerType.ALWAYS_STACK) || type == ContainerType.SHOP) {
|
||||
if (item.getAmount() >= oldItem.getAmount()) {
|
||||
items[slot] = null;
|
||||
event.flagNull(slot);
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
items[slot] = new Item(item.getId(), oldItem.getAmount() - item.getAmount(), item.getCharge());
|
||||
items[slot].setIndex(slot);
|
||||
event.flag(slot, items[slot]);
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
items[slot] = null;
|
||||
event.flagNull(slot);
|
||||
int removed = 1;
|
||||
for (int i = removed; i < item.getAmount(); i++) {
|
||||
slot = getSlot(item);
|
||||
if (slot != -1) {
|
||||
items[slot] = null;
|
||||
event.flagNull(slot);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the item on the given slot with the argued item.
|
||||
* @param item The item.
|
||||
* @param slot The slot.
|
||||
* @return The old item.
|
||||
*/
|
||||
public Item replace(Item item, int slot) {
|
||||
return replace(item, slot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the item on the given slot with the argued item.
|
||||
* @param item The item.
|
||||
* @param slot The slot.
|
||||
* @param fireListener If the listener should be "notified".
|
||||
* @return The old item.
|
||||
*/
|
||||
public Item replace(Item item, int slot, boolean fireListener) {
|
||||
if (item != null) {
|
||||
if (item.getAmount() < 1 && type != ContainerType.SHOP) {
|
||||
item = null;
|
||||
} else {
|
||||
item = item.copy();
|
||||
}
|
||||
}
|
||||
Item oldItem = items[slot];
|
||||
items[slot] = item;
|
||||
if (item == null) {
|
||||
event.flagNull(slot);
|
||||
} else {
|
||||
item.setIndex(slot);
|
||||
event.flag(slot, item);
|
||||
}
|
||||
if (fireListener) {
|
||||
update();
|
||||
}
|
||||
return oldItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the container.
|
||||
*/
|
||||
public void update() {
|
||||
if (event.getChangeCount() < 1 && !event.isClear()) {
|
||||
return;
|
||||
}
|
||||
for (ContainerListener listener : listeners) {
|
||||
listener.update(this, event);
|
||||
}
|
||||
event.setClear(false);
|
||||
event = new ContainerEvent(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the container.
|
||||
*/
|
||||
public void update(boolean force) {
|
||||
if (event.getChangeCount() < 1 && !force) {
|
||||
return;
|
||||
}
|
||||
for (ContainerListener listener : listeners) {
|
||||
listener.update(this, event);
|
||||
}
|
||||
event = new ContainerEvent(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the entire container.
|
||||
*/
|
||||
public void refresh() {
|
||||
for (ContainerListener listener : listeners) {
|
||||
listener.refresh(this);
|
||||
}
|
||||
event = new ContainerEvent(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item on the given slot.
|
||||
* @param slot The slot.
|
||||
* @return The item on the slot, or {@code null} if the item wasn't there.
|
||||
*/
|
||||
public Item get(int slot) {
|
||||
if (slot < 0 || slot >= items.length) {
|
||||
return null;
|
||||
}
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item on the given slot.
|
||||
* @param slot The slot.
|
||||
* @return The item on the slot, or a new constructed item with id 0 if the
|
||||
* item wasn't there.
|
||||
*/
|
||||
public Item getNew(int slot) {
|
||||
Item item = items[slot];
|
||||
if (item != null) {
|
||||
return item;
|
||||
}
|
||||
return new Item(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item id on the given slot.
|
||||
* @param slot The slot.
|
||||
* @return The id of the item on the slot.
|
||||
*/
|
||||
public int getId(int slot) {
|
||||
if (slot >= items.length) {
|
||||
return -1;
|
||||
}
|
||||
Item item = items[slot];
|
||||
if (item != null) {
|
||||
return item.getId();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the container data from the byte buffer.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The total value of all items (G.E price > Store price > High
|
||||
* alchemy price).
|
||||
*/
|
||||
public int parse(ByteBuffer buffer) {
|
||||
int slot;
|
||||
int total = 0;
|
||||
while ((slot = buffer.getShort()) != -1) {
|
||||
int id = buffer.getShort() & 0xFFFF;
|
||||
int amount = buffer.getInt();
|
||||
int charge = buffer.getInt();
|
||||
if (id >= ItemDefinition.getDefinitions().size() || id < 0 || slot >= items.length || slot < 0) {
|
||||
continue;
|
||||
}
|
||||
Item item = items[slot] = new Item(id, amount, charge);
|
||||
item.setIndex(slot);
|
||||
total += item.getValue();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the item data on the byte buffer.
|
||||
* @param buffer The byte buffer.
|
||||
* @return The total value of all items (G.E price > Store price > High
|
||||
* alchemy price).
|
||||
*/
|
||||
public long save(ByteBuffer buffer) {
|
||||
long totalValue = 0;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
Item item = items[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
buffer.putShort((short) i);
|
||||
buffer.putShort((short) item.getId());
|
||||
buffer.putInt(item.getAmount());
|
||||
buffer.putInt(item.getCharge());
|
||||
totalValue += item.getValue();
|
||||
}
|
||||
buffer.putShort((short) -1);
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the container to this container.
|
||||
* @param c The container to copy.
|
||||
*/
|
||||
public void copy(Container c) {
|
||||
items = new Item[c.items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
Item it = c.items[i];
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
items[i] = new Item(it.getId(), it.getAmount(), it.getCharge());
|
||||
items[i].setIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a container for the SQL database.
|
||||
* @return the string.
|
||||
*/
|
||||
public String format() {
|
||||
String log = "";
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
Integer old = null;
|
||||
for (Item item : items) {
|
||||
if (item != null) {
|
||||
old = map.get(item.getId());
|
||||
map.put(item.getId(), old == null ? item.getAmount() : old + item.getAmount());
|
||||
|
||||
}
|
||||
}
|
||||
for (int i : map.keySet()) {
|
||||
log += i + "," + map.get(i) + "|";
|
||||
}
|
||||
if (log.length() > 0 && log.charAt(log.length() - 1) == '|') {
|
||||
log = log.substring(0, log.length() - 1);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container contains an item.
|
||||
* @param item the Item
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean containsItem(Item item) {
|
||||
return contains(item.getId(), item.getAmount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the containers contains these items.
|
||||
* @param items the items.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean containsItems(Item... items) {
|
||||
for (Item i : items) {
|
||||
if (!containsItem(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container contains an item.
|
||||
* @param itemId The item id.
|
||||
* @param amount The amount.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean contains(int itemId, int amount) {
|
||||
int count = 0;
|
||||
for (Item item : items) {
|
||||
if (item != null && item.getId() == itemId) {
|
||||
if ((count += item.getAmount()) >= amount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the containers contains ONE item.
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public boolean containsOneItem(int itemId) {
|
||||
for (Item item : items) {
|
||||
if (item != null && item.getId() == itemId && item.getAmount() == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container contains all items.
|
||||
* @param the itemIds to check
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean containsAll(int...itemIds) {
|
||||
for (int i : itemIds) {
|
||||
if (!containsOneItem(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a container to this container.
|
||||
* @param container The container.
|
||||
*/
|
||||
public void addAll(Container container) {
|
||||
add(container.items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the maximum amount of this item we can add.
|
||||
* @param item The item.
|
||||
* @return The maximum amount we can add.
|
||||
*/
|
||||
public int getMaximumAdd(Item item) {
|
||||
if (type != ContainerType.NEVER_STACK) {
|
||||
if (item.getDefinition().isStackable() || type == ContainerType.ALWAYS_STACK || type == ContainerType.SHOP) {
|
||||
if (contains(item.getId(), 1)) {
|
||||
return Integer.MAX_VALUE - getAmount(item);
|
||||
}
|
||||
return freeSlots() > 0 ? Integer.MAX_VALUE : 0;
|
||||
}
|
||||
}
|
||||
return freeSlots();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container has space for the item.
|
||||
* @param item The item to check.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasSpaceFor(Item item) {
|
||||
return item.getAmount() <= getMaximumAdd(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this container has space to add the other container.
|
||||
* @param c The other container.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasSpaceFor(Container c) {
|
||||
if (c == null) {
|
||||
return false;
|
||||
}
|
||||
Container check = new Container(capacity, type);
|
||||
check.addAll(this);
|
||||
for (Item item : c.items) {
|
||||
if (item != null) {
|
||||
if (!check.add(item, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item slot.
|
||||
* @param item The item.
|
||||
* @return The slot of the item in this container.
|
||||
*/
|
||||
public int getSlot(Item item) {
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
int id = item.getId();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
Item it = items[i];
|
||||
if (it != null && it.getId() == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item instance.
|
||||
* @param item the item.
|
||||
* @return the item.
|
||||
*/
|
||||
public Item getItem(Item item) {
|
||||
return get(getSlot(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next free slot.
|
||||
* @return The slot, or <code>-1</code> if there are no available slots.
|
||||
*/
|
||||
public int freeSlot() {
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i] == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the slot of where to add the item.
|
||||
* @param item The item to add.
|
||||
* @return The slot where the item will go.
|
||||
*/
|
||||
public int getAddSlot(Item item) {
|
||||
if (type != ContainerType.NEVER_STACK && (item.getDefinition().isStackable() || type.equals(ContainerType.ALWAYS_STACK) || type == ContainerType.SHOP)) {
|
||||
boolean hashBased = sortType == SortType.HASH;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i] != null) {
|
||||
if ((hashBased && items[i].getIdHash() == item.getIdHash()) || (!hashBased && items[i].getId() == item.getId())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return freeSlot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of free slots.
|
||||
* @return The number of free slots.
|
||||
*/
|
||||
public int freeSlots() {
|
||||
return capacity - itemCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of this container.
|
||||
* @return The size of this container.
|
||||
*/
|
||||
public int itemCount() {
|
||||
int size = 0;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i] != null) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has all the item ids in the inventory.
|
||||
* @param itemIds The item ids.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean containItems(int... itemIds) {
|
||||
for (int i = 0; i < itemIds.length; i++) {
|
||||
if (!contains(itemIds[i], 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of an item.
|
||||
* @param item The item.
|
||||
* @return The amount of this item in this container.
|
||||
*/
|
||||
public int getAmount(Item item) {
|
||||
if (item == null) {
|
||||
return 0;
|
||||
}
|
||||
int count = 0;
|
||||
for (Item i : items) {
|
||||
if (i != null && i.getId() == item.getId()) {
|
||||
count += i.getAmount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount.
|
||||
* @param id the id.
|
||||
* @return the amount.
|
||||
*/
|
||||
public int getAmount(int id) {
|
||||
return getAmount(new Item(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts the elements in the <b>Container</b> to the appropriate position.
|
||||
*/
|
||||
public void shift() {
|
||||
final Item itemss[] = items;
|
||||
clear(false);
|
||||
for (Item item : itemss) {
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
add(item, false);
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container is empty.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
for (Item item : items) {
|
||||
if (item != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the container is full.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isFull() {
|
||||
return freeSlots() < 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears and updates the container.
|
||||
*/
|
||||
public void clear() {
|
||||
clear(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the container.
|
||||
* @param update If the container should be updated.
|
||||
*/
|
||||
public void clear(boolean update) {
|
||||
items = new Item[capacity];
|
||||
event.flagEmpty();
|
||||
if (update) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wealth.
|
||||
* @return the wealth.
|
||||
*/
|
||||
public int getWealth() {
|
||||
int wealth = 0;
|
||||
for (Item i : items) {
|
||||
if (i == null) {
|
||||
continue;
|
||||
}
|
||||
wealth += i.getDefinition().getValue() * i.getAmount();
|
||||
}
|
||||
return wealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representing this container.
|
||||
* @return The array.
|
||||
*/
|
||||
public Item[] toArray() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the listeners.
|
||||
* @return The listeners.
|
||||
*/
|
||||
public List<ContainerListener> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the capacity.
|
||||
* @return The capacity of this container.
|
||||
*/
|
||||
public int capacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event.
|
||||
* @return the event.
|
||||
*/
|
||||
public ContainerEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
package org.crandor.game.container;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a container event.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ContainerEvent {
|
||||
|
||||
/**
|
||||
* Represents a null item.
|
||||
*/
|
||||
public static final Item NULL_ITEM = new Item(0, 0);
|
||||
|
||||
/**
|
||||
* The array of changed items.
|
||||
*/
|
||||
private final Item[] items;
|
||||
|
||||
/**
|
||||
* Clears the container.
|
||||
*/
|
||||
private boolean clear;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ContainerEvent} {@code Object}.
|
||||
* @param size The container size.
|
||||
*/
|
||||
public ContainerEvent(int size) {
|
||||
this.items = new Item[size];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags a null item on the given slot.
|
||||
* @param slot The slot.
|
||||
*/
|
||||
public void flagNull(int slot) {
|
||||
items[slot] = NULL_ITEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags an item on the given slot.
|
||||
* @param slot The slot.
|
||||
* @param item The item.
|
||||
*/
|
||||
public void flag(int slot, Item item) {
|
||||
items[slot] = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of item slots changed.
|
||||
* @return The amount of item slots that have changed.
|
||||
*/
|
||||
public int getChangeCount() {
|
||||
int count = 0;
|
||||
for (Item item : items) {
|
||||
if (item != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the updated slots.
|
||||
* @return The slots array.
|
||||
*/
|
||||
public int[] getSlots() {
|
||||
int size = 0;
|
||||
int[] slots = new int[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i] != null) {
|
||||
slots[size++] = i;
|
||||
}
|
||||
}
|
||||
int[] slot = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
slot[i] = slots[i];
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items.
|
||||
* @return The items.
|
||||
*/
|
||||
public Item[] getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags an empty container.
|
||||
*/
|
||||
public void flagEmpty() {
|
||||
this.clear = true;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clear.
|
||||
* @return The clear.
|
||||
*/
|
||||
public boolean isClear() {
|
||||
return clear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clear flag.
|
||||
* @param clear The container is cleared.
|
||||
*/
|
||||
public void setClear(boolean clear) {
|
||||
this.clear = clear;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.crandor.game.container;
|
||||
|
||||
/**
|
||||
* Represents a container listener.
|
||||
* @author Emperor
|
||||
*/
|
||||
public interface ContainerListener {
|
||||
|
||||
/**
|
||||
* Updates the changed item slots in the container.
|
||||
* @param c The container we're listening to.
|
||||
* @param event The container event.
|
||||
*/
|
||||
void update(Container c, ContainerEvent event);
|
||||
|
||||
/**
|
||||
* Updates the entire container.
|
||||
* @param c The container.
|
||||
*/
|
||||
void refresh(Container c);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package org.crandor.game.container;
|
||||
|
||||
/**
|
||||
* Represents the container types.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum ContainerType {
|
||||
|
||||
/**
|
||||
* The default container type.
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
/**
|
||||
* If the container is used for a shop.
|
||||
*/
|
||||
SHOP,
|
||||
|
||||
/**
|
||||
* The container should always stack items.
|
||||
*/
|
||||
ALWAYS_STACK,
|
||||
|
||||
/**
|
||||
* The container should never stack items.
|
||||
*/
|
||||
NEVER_STACK;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package org.crandor.game.container;
|
||||
|
||||
/**
|
||||
* The sort type of the container.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum SortType {
|
||||
|
||||
/**
|
||||
* Sort by item id (default).
|
||||
*/
|
||||
ID,
|
||||
|
||||
/**
|
||||
* Sort by item identification hash (bank).
|
||||
*/
|
||||
HASH
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package org.crandor.game.container.access;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Contains the mask value methods. The 'access mask' is actually just a bit
|
||||
* register that contains permissions for a specific interface (@Peterbjornx)
|
||||
* @date 5/02/2013
|
||||
* @author Stacx
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BitregisterAssembler {
|
||||
|
||||
/**
|
||||
* The register size.
|
||||
*/
|
||||
public static final int SIZE = 32 - 1;
|
||||
|
||||
/**
|
||||
* Examine option.
|
||||
*/
|
||||
public static final int EXAMINE_OPT = 9;
|
||||
|
||||
/**
|
||||
* Allow dragging.
|
||||
*/
|
||||
public static final int DRAGABLE = 17;
|
||||
|
||||
/**
|
||||
* Allow switching item slots.
|
||||
*/
|
||||
public static final int SLOT_SWITCH = 20;
|
||||
|
||||
/**
|
||||
* The flags.
|
||||
*/
|
||||
private boolean[] permissions = new boolean[SIZE];
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BitregisterAssembler} {@code Object}.
|
||||
* @param permissions The permissions.
|
||||
*/
|
||||
public BitregisterAssembler(int... permissions) {
|
||||
for (int i : permissions) {
|
||||
this.permissions[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BitregisterAssembler} {@code Object}.
|
||||
* @param permissions The permissions.
|
||||
*/
|
||||
public BitregisterAssembler(String[] options) {
|
||||
enableOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the given options ({@code null} options will remain disabled).
|
||||
* @param options The options.
|
||||
*/
|
||||
public void enableOptions(String...options) {
|
||||
if (options.length > 9) {
|
||||
throw new IllegalStateException("Too many options specified - maximum 9 allowed!");
|
||||
}
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
if (options[i] != null && !options[i].equals("null")) {
|
||||
permissions[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the examine option.
|
||||
*/
|
||||
public void enableExamineOption() {
|
||||
permissions[EXAMINE_OPT] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables items being dragged.
|
||||
*/
|
||||
public void enableDragging() {
|
||||
permissions[DRAGABLE] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables item switching slots (& dragging).
|
||||
*/
|
||||
public void enableSlotSwitch() {
|
||||
enableDragging();
|
||||
permissions[SLOT_SWITCH] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Send</b> and assemble a bit register for our
|
||||
* @param player , the player instance
|
||||
* @param interfaceIndex , the interface index
|
||||
* @param childIndex , the child index for our interface
|
||||
* @param offset , the offset for the loop in client
|
||||
* @param length , the length of our loop
|
||||
*/
|
||||
public static void send(Player player, int interfaceIndex, int childIndex, int offset, int length, BitregisterAssembler assembler) {
|
||||
if (offset >= length) {
|
||||
throw new RuntimeException("Offset cannot excess length. length = " + length);
|
||||
}
|
||||
player.getPacketDispatch().sendAccessMask(assembler.calculateRegister(), childIndex, interfaceIndex, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the register.
|
||||
* @return The value.
|
||||
*/
|
||||
public int calculateRegister() {
|
||||
int value = 0;
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
if (permissions[i]) {
|
||||
value |= 2 << i;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
package org.crandor.game.container.access;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
|
||||
/**
|
||||
* Generates a set of items and options on an interface.
|
||||
* @date 5/02/2013
|
||||
* @author Stacx
|
||||
*/
|
||||
public class InterfaceContainer {
|
||||
|
||||
/**
|
||||
* The client script index for set_options.
|
||||
*/
|
||||
private static final int CLIENT_SCRIPT_INDEX = 150;
|
||||
|
||||
/**
|
||||
* This index will increase each time a set is generated.
|
||||
*/
|
||||
private static int index = 600; // 93
|
||||
|
||||
/**
|
||||
* Generates a container/array of items in an interface positioned on the
|
||||
* child index.
|
||||
* @param player , the player we generate this set for
|
||||
* @param itemArray , the container/array of items we want to display
|
||||
* @param options , the right-click options we want for the items
|
||||
* @param interfaceIndex , the interface index
|
||||
* @param childIndex , the child index of the interface where we display the
|
||||
* items at.
|
||||
* @return The container key.
|
||||
*/
|
||||
private static int generate(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y, int key) {
|
||||
Object[] clientScript = new Object[options.length + 7];
|
||||
player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceIndex << 16 | childIndex, x, y, key));
|
||||
BitregisterAssembler.send(player, interfaceIndex, childIndex, 0, itemArray.length, new BitregisterAssembler(options));
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, key, itemArray, itemArray.length, false));
|
||||
return increment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates options for the interface item container.
|
||||
* @param player The player.
|
||||
* @param interfaceId The interface id.
|
||||
* @param childId The child index.
|
||||
* @param itemLength The amount of items.
|
||||
* @param options The options.
|
||||
* @return The container key.
|
||||
*/
|
||||
public static int generate(Player player, int interfaceId, int childId, int itemLength, String... options) {
|
||||
return generate(player, interfaceId, childId, itemLength, 7, 3, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates options for the interface item container.
|
||||
* @param player The player.
|
||||
* @param interfaceId The interface id.
|
||||
* @param childId The child index.
|
||||
* @param itemLength The amount of items.
|
||||
* @param x The amount of items in a row.
|
||||
* @param y The amount of item rows.
|
||||
* @param options The options.
|
||||
* @return The container key.
|
||||
*/
|
||||
public static int generate(Player player, int interfaceId, int childId, int itemLength, int x, int y, String... options) {
|
||||
int key = increment();
|
||||
Object[] clientScript = new Object[options.length + 7];
|
||||
player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceId << 16 | childId, x, y, key));
|
||||
BitregisterAssembler.send(player, interfaceId, childId, 0, itemLength, new BitregisterAssembler(options));
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the current index.
|
||||
* @return The previous index.
|
||||
*/
|
||||
private static int increment() {
|
||||
if (index == 6999) {
|
||||
index = 600;
|
||||
}
|
||||
return index++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates an object array used as a script for the client
|
||||
* @param script , the array we want to populate
|
||||
* @param options , the right-click options for our items
|
||||
* @param hash , interfaceIndex << 16 | childIndex
|
||||
* @return script, the populated script
|
||||
*/
|
||||
private static Object[] populateScript(Object[] script, String[] options, int hash, int x, int y, int key) {
|
||||
int offset = 0;
|
||||
for (String option : options) {
|
||||
script[offset++] = option;
|
||||
}
|
||||
System.arraycopy(new Object[] { -1, 0, x, y, key, hash }, 0, script, offset, 6);
|
||||
return script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a script argument type string for the client (note: everything
|
||||
* but a "s" is integer for the run script packet)
|
||||
* @param length , the amount of options
|
||||
* @return the generated string.
|
||||
*/
|
||||
private static String generateScriptArguments(int length) {
|
||||
StringBuilder builder = new StringBuilder("IviiiI");
|
||||
while (length > 0) {
|
||||
builder.append("s");
|
||||
length--;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default method to generate and send an item array for the client.
|
||||
* @return The container key.
|
||||
* @see {@link InterfaceContainer.generate}
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex) {
|
||||
return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, increment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Default method to generate and send an item array for the client.
|
||||
* @return The container key.
|
||||
* @see {@link InterfaceContainer.generate}
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int key) {
|
||||
return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to generate the send items for the client with a specified
|
||||
* location for the items.
|
||||
* @param x , the x coordinate
|
||||
* @param y , the y coordinate
|
||||
* @return The container key.
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y) {
|
||||
return generateItems(player, itemArray, options, interfaceIndex, childIndex, x, y, increment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to generate the send items for the client with a specified
|
||||
* location for the items.
|
||||
* @param x , the x coordinate
|
||||
* @param y , the y coordinate
|
||||
* @return The container key.
|
||||
*/
|
||||
public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y, int key) {
|
||||
return generate(player, itemArray, options, interfaceIndex, childIndex, x, y, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
package org.crandor.game.container.impl;
|
||||
|
||||
import org.crandor.game.component.CloseEvent;
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.container.*;
|
||||
import org.crandor.game.container.access.BitregisterAssembler;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.IronmanMode;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.mysql.impl.ItemConfigSQLHandler;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Represents the bank container.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BankContainer extends Container {
|
||||
|
||||
/**
|
||||
* The bank container size.
|
||||
*/
|
||||
public static final int SIZE = 496;
|
||||
|
||||
/**
|
||||
* The maximum amount of bank tabs
|
||||
*/
|
||||
public static final int TAB_SIZE = 11;
|
||||
|
||||
/**
|
||||
* The player reference.
|
||||
*/
|
||||
private Player player;
|
||||
|
||||
/**
|
||||
* The bank listener.
|
||||
*/
|
||||
private final BankListener listener;
|
||||
|
||||
/**
|
||||
* Set {@code true} to note items.
|
||||
*/
|
||||
private boolean noteItems;
|
||||
|
||||
/**
|
||||
* If the bank is open.
|
||||
*/
|
||||
private boolean open;
|
||||
|
||||
/**
|
||||
* The last x-amount entered.
|
||||
*/
|
||||
private int lastAmountX = 50;
|
||||
|
||||
/**
|
||||
* The current tab index.
|
||||
*/
|
||||
private int tabIndex = 10;
|
||||
|
||||
/**
|
||||
* The tab start indexes.
|
||||
*/
|
||||
private final int[] tabStartSlot = new int[TAB_SIZE];
|
||||
|
||||
/**
|
||||
* If inserting items is enabled.
|
||||
*/
|
||||
private boolean insertItems;
|
||||
|
||||
/**
|
||||
* Construct a new {@code BankContainer} {@code Object}.
|
||||
* @param player The player reference.
|
||||
*/
|
||||
public BankContainer(Player player) {
|
||||
super(SIZE, ContainerType.ALWAYS_STACK, SortType.HASH);
|
||||
super.register(listener = new BankListener(player));
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the bank.
|
||||
*/
|
||||
public void open() {
|
||||
if (open) {
|
||||
return;
|
||||
}
|
||||
if (player.getIronmanManager().checkRestriction(IronmanMode.ULTIMATE)) {
|
||||
return;
|
||||
}
|
||||
if (!player.getBankPinManager().isUnlocked() && !GameWorld.getSettings().isDevMode()) {
|
||||
player.getBankPinManager().openType(1);
|
||||
return;
|
||||
}
|
||||
player.getInterfaceManager().openComponent(762).setCloseEvent(new CloseEvent() {
|
||||
@Override
|
||||
public boolean close(Player player, Component c) {
|
||||
BankContainer.this.close();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
player.getInterfaceManager().openSingleTab(new Component(763));
|
||||
super.refresh();
|
||||
player.getInventory().getListeners().add(listener);
|
||||
player.getInventory().refresh();
|
||||
player.getConfigManager().set(1249, lastAmountX);
|
||||
player.getPacketDispatch().sendAccessMask(1278, 73, 762, 0, SIZE);
|
||||
BitregisterAssembler assembly = new BitregisterAssembler(0, 1, 2, 3, 4, 5);
|
||||
assembly.enableExamineOption();
|
||||
assembly.enableSlotSwitch();
|
||||
player.getPacketDispatch().sendAccessMask(assembly.calculateRegister(), 0, 763, 0, 27);
|
||||
player.getPacketDispatch().sendRunScript(1451, "");
|
||||
open = true;
|
||||
setTabConfigurations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long save(ByteBuffer buffer) {
|
||||
buffer.putInt(lastAmountX);
|
||||
buffer.put((byte) tabStartSlot.length);
|
||||
for (int i = 0; i < tabStartSlot.length; i++) {
|
||||
buffer.putShort((short) tabStartSlot[i]);
|
||||
}
|
||||
return super.save(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int parse(ByteBuffer buffer) {
|
||||
lastAmountX = buffer.getInt();
|
||||
int length = buffer.get() & 0xFF;
|
||||
for (int i = 0; i < length; i++) {
|
||||
tabStartSlot[i] = buffer.getShort();
|
||||
}
|
||||
return super.parse(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the bank.
|
||||
*/
|
||||
public void close() {
|
||||
open = false;
|
||||
player.getInventory().getListeners().remove(listener);
|
||||
player.getInterfaceManager().closeSingleTab();
|
||||
player.removeAttribute("search");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the bank container.
|
||||
* @param slot The item slot.
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public void addItem(int slot, int amount) {
|
||||
if (slot < 0 || slot > player.getInventory().capacity() || amount < 1) {
|
||||
return;
|
||||
}
|
||||
Item item = player.getInventory().get(slot);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
int maximum = player.getInventory().getAmount(item);
|
||||
if (amount > maximum) {
|
||||
amount = maximum;
|
||||
}
|
||||
int maxCount = super.getMaximumAdd(item);
|
||||
if (amount > maxCount) {
|
||||
amount = maxCount;
|
||||
if (amount < 1) {
|
||||
player.getPacketDispatch().sendMessage("There is not enough space left in your bank.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!item.getDefinition().getConfiguration(ItemConfigSQLHandler.BANKABLE, true)) {
|
||||
player.sendMessage("A magical force prevents you from banking this item");
|
||||
return;
|
||||
}
|
||||
item = new Item(item.getId(), amount, item.getCharge());
|
||||
boolean unnote = !item.getDefinition().isUnnoted();
|
||||
if (player.getInventory().remove(item, slot, true)) {
|
||||
Item add = unnote ? new Item(item.getDefinition().getNoteId(), amount, item.getCharge()) : item;
|
||||
if (unnote && !add.getDefinition().isUnnoted()) {
|
||||
add = item;
|
||||
}
|
||||
int preferredSlot = -1;
|
||||
if (tabIndex != 0 && tabIndex != 10 && !super.contains(add.getId(), 1)) {
|
||||
preferredSlot = tabStartSlot[tabIndex] + getItemsInTab(tabIndex);
|
||||
insert(freeSlot(), preferredSlot, false);
|
||||
increaseTabStartSlots(tabIndex);
|
||||
}
|
||||
super.add(add, true, preferredSlot);
|
||||
setTabConfigurations();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-opens the bank interface.
|
||||
*/
|
||||
public void reopen() {
|
||||
if (!open) {
|
||||
return;
|
||||
}
|
||||
player.getInterfaceManager().close();
|
||||
open();
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a item from the bank container and adds one to the inventory
|
||||
* container.
|
||||
* @param slot The slot.
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public void takeItem(int slot, int amount) {
|
||||
if (slot < 0 || slot > super.capacity() || amount <= 0) {
|
||||
return;
|
||||
}
|
||||
Item item = get(slot);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (amount > item.getAmount()) {
|
||||
amount = item.getAmount(); // It always stacks in the bank.
|
||||
}
|
||||
item = new Item(item.getId(), amount, item.getCharge());
|
||||
int noteId = item.getDefinition().getNoteId();
|
||||
Item add = noteItems && noteId > 0 ? new Item(noteId, amount, item.getCharge()) : item;
|
||||
int maxCount = player.getInventory().getMaximumAdd(add);
|
||||
if (amount > maxCount) {
|
||||
item.setAmount(maxCount);
|
||||
add.setAmount(maxCount);
|
||||
if (maxCount < 1) {
|
||||
player.getPacketDispatch().sendMessage("Not enough space in your inventory.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (noteItems && noteId < 0) {
|
||||
player.getPacketDispatch().sendMessage("This item can't be withdrawn as a note.");
|
||||
add = item;
|
||||
}
|
||||
if (super.remove(item, slot, false)) {
|
||||
player.getInventory().add(add);
|
||||
}
|
||||
int tabId = getTabByItemSlot(slot);
|
||||
if (get(slot) == null) {
|
||||
decreaseTabStartSlots(tabId);
|
||||
}
|
||||
setTabConfigurations();
|
||||
shift();
|
||||
if (player.getAttribute("search", false)) {
|
||||
reopen();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last x-amount entered.
|
||||
* @param amount The amount to set.
|
||||
*/
|
||||
public void updateLastAmountX(int amount) {
|
||||
this.lastAmountX = amount;
|
||||
player.getConfigManager().set(1249, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tab the item slot is in.
|
||||
* @param itemSlot The item slot.
|
||||
* @return The tab index.
|
||||
*/
|
||||
public int getTabByItemSlot(int itemSlot) {
|
||||
int tabId = 0;
|
||||
for (int i = 0; i < tabStartSlot.length; i++) {
|
||||
if (itemSlot >= tabStartSlot[i]) {
|
||||
tabId = i;
|
||||
}
|
||||
}
|
||||
return tabId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases a tab's start slot.
|
||||
* @param startId The start id.
|
||||
*/
|
||||
public void increaseTabStartSlots(int startId) {
|
||||
for (int i = startId + 1; i < tabStartSlot.length; i++) {
|
||||
tabStartSlot[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases a tab's start slot.
|
||||
* @param startId The start id.
|
||||
*/
|
||||
public void decreaseTabStartSlots(int startId) {
|
||||
if (startId == 10) {
|
||||
return;
|
||||
}
|
||||
for (int i = startId + 1; i < tabStartSlot.length; i++) {
|
||||
tabStartSlot[i]--;
|
||||
}
|
||||
if (getItemsInTab(startId) == 0) {
|
||||
collapseTab(startId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array index for a tab.
|
||||
* @param tabId The tab id.
|
||||
* @return The array index.
|
||||
*/
|
||||
public static int getArrayIndex(int tabId) {
|
||||
if (tabId == 41 || tabId == 74) {
|
||||
return 10;
|
||||
}
|
||||
int base = 39;
|
||||
for (int i = 1; i < 10; i++) {
|
||||
if (tabId == base) {
|
||||
return i;
|
||||
}
|
||||
base -= 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the bank space values on the interface.
|
||||
*/
|
||||
public void sendBankSpace() {
|
||||
player.getPacketDispatch().sendString(Integer.toString(capacity() - freeSlots()), 762, 97);
|
||||
player.getPacketDispatch().sendString(Integer.toString(capacity()), 762, 98);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapses a tab.
|
||||
* @param tabId The tab index.
|
||||
*/
|
||||
public void collapseTab(int tabId) {
|
||||
int size = getItemsInTab(tabId);
|
||||
Item[] tempTabItems = new Item[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
tempTabItems[i] = get(tabStartSlot[tabId] + i);
|
||||
replace(null, tabStartSlot[tabId] + i, false);
|
||||
}
|
||||
shift();
|
||||
for (int i = tabId; i < tabStartSlot.length - 1; i++) {
|
||||
tabStartSlot[i] = tabStartSlot[i + 1] - size;
|
||||
}
|
||||
tabStartSlot[10] = tabStartSlot[10] - size;
|
||||
for (int i = 0; i < size; i++) {
|
||||
int slot = freeSlot();
|
||||
replace(tempTabItems[i], slot, false);
|
||||
}
|
||||
refresh(); //We only refresh once.
|
||||
setTabConfigurations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tab configs.
|
||||
*/
|
||||
public void setTabConfigurations() {
|
||||
int value = getItemsInTab(1);
|
||||
value += getItemsInTab(2) << 10;
|
||||
value += getItemsInTab(3) << 20;
|
||||
player.getConfigManager().set(1246, value);
|
||||
value = getItemsInTab(4);
|
||||
value += getItemsInTab(5) << 10;
|
||||
value += getItemsInTab(6) << 20;
|
||||
player.getConfigManager().set(1247, value);
|
||||
value = -2013265920;
|
||||
value += (134217728 * (tabIndex == 10 ? 0 : tabIndex));
|
||||
value += getItemsInTab(7);
|
||||
value += getItemsInTab(8) << 10;
|
||||
player.getConfigManager().set(1248, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of items in one tab.
|
||||
* @param tabId The tab index.
|
||||
* @return The amount of items in this tab.
|
||||
*/
|
||||
public int getItemsInTab(int tabId) {
|
||||
return tabStartSlot[tabId + 1] - tabStartSlot[tabId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the item can be added.
|
||||
* @param item the item.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean canAdd(Item item) {
|
||||
return item.getDefinition().getConfiguration(ItemConfigSQLHandler.BANKABLE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last x-amount.
|
||||
* @return The last x-amount.
|
||||
*/
|
||||
public int getLastAmountX() {
|
||||
return lastAmountX;
|
||||
}
|
||||
|
||||
/**
|
||||
* If items have to be noted.
|
||||
* @return If items have to be noted {@code true}.
|
||||
*/
|
||||
public boolean isNoteItems() {
|
||||
return noteItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if items have to be noted.
|
||||
* @param noteItems If items have to be noted {@code true}.
|
||||
*/
|
||||
public void setNoteItems(boolean noteItems) {
|
||||
this.noteItems = noteItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tabStartSlot value.
|
||||
* @return The tabStartSlot.
|
||||
*/
|
||||
public int[] getTabStartSlot() {
|
||||
return tabStartSlot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tabIndex value.
|
||||
* @return The tabIndex.
|
||||
*/
|
||||
public int getTabIndex() {
|
||||
return tabIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tabIndex value.
|
||||
* @param tabIndex The tabIndex to set.
|
||||
*/
|
||||
public void setTabIndex(int tabIndex) {
|
||||
this.tabIndex = tabIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the insert items value.
|
||||
* @param insertItems The insert items value.
|
||||
*/
|
||||
public void setInsertItems(boolean insertItems) {
|
||||
this.insertItems = insertItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the insert items value.
|
||||
* @return {@code True} if inserting items mode is enabled.
|
||||
*/
|
||||
public boolean isInsertItems() {
|
||||
return insertItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the bank is opened.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the bank container.
|
||||
* @author Emperor
|
||||
*/
|
||||
private static class BankListener implements ContainerListener {
|
||||
|
||||
/**
|
||||
* The player reference.
|
||||
*/
|
||||
private Player player;
|
||||
|
||||
/**
|
||||
* Construct a new {@code BankListener} {@code Object}.
|
||||
* @param player The player reference.
|
||||
*/
|
||||
public BankListener(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Container c, ContainerEvent event) {
|
||||
if (c instanceof BankContainer) {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, event.getItems(), false, event.getSlots()));
|
||||
} else {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, event.getItems(), false, event.getSlots()));
|
||||
}
|
||||
player.getBank().setTabConfigurations();
|
||||
player.getBank().sendBankSpace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Container c) {
|
||||
if (c instanceof BankContainer) {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, c.toArray(), c.capacity(), false));
|
||||
} else {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, c.toArray(), 28, false));
|
||||
}
|
||||
player.getBank().setTabConfigurations();
|
||||
player.getBank().sendBankSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
package org.crandor.game.container.impl;
|
||||
|
||||
import org.crandor.game.container.Container;
|
||||
import org.crandor.game.container.ContainerEvent;
|
||||
import org.crandor.game.container.ContainerListener;
|
||||
import org.crandor.game.node.entity.combat.equipment.WeaponInterface;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.mysql.impl.ItemConfigSQLHandler;
|
||||
import org.crandor.game.world.update.flag.player.AppearanceFlag;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
import org.crandor.net.packet.out.WeightUpdate;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the equipment container.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class EquipmentContainer extends Container {
|
||||
|
||||
/**
|
||||
* The equipment slots.
|
||||
*/
|
||||
public static final int SLOT_HAT = 0, SLOT_CAPE = 1, SLOT_AMULET = 2, SLOT_WEAPON = 3, SLOT_CHEST = 4, SLOT_SHIELD = 5, SLOT_LEGS = 7, SLOT_HANDS = 9, SLOT_FEET = 10, SLOT_RING = 12, SLOT_ARROWS = 13;
|
||||
|
||||
/**
|
||||
* The bonus names.
|
||||
*/
|
||||
private static final String[] BONUS_NAMES = { "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Summoning: ", "Strength: ", "Prayer: " };
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EquipmentContainer} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public EquipmentContainer(Player player) {
|
||||
super(14);
|
||||
this.player = player;
|
||||
register(new EquipmentListener(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Item item, boolean fire) {
|
||||
return add(item, fire, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the equipment container.
|
||||
* @param item The item to add.
|
||||
* @param fire If we should refresh.
|
||||
* @param fromInventory If the item is being equipped from the inventory.
|
||||
* @return {@code True} if succesful, {@code false} if not.
|
||||
*/
|
||||
public boolean add(Item item, boolean fire, boolean fromInventory) {
|
||||
return add(item, player.getInventory().getSlot(item), fire, fromInventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the equipment container.
|
||||
* @param item The item to add.
|
||||
* @param inventorySlot The inventory slot of the item.
|
||||
* @param fire If we should refresh.
|
||||
* @param fromInventory If the item is being equipped from the inventory.
|
||||
* @return {@code True} if succesful, {@code false} if not.
|
||||
*/
|
||||
public boolean add(Item item, int inventorySlot, boolean fire, boolean fromInventory) {
|
||||
int slot = item.getDefinition().getConfiguration(ItemConfigSQLHandler.EQUIP_SLOT, -1);
|
||||
if (slot == -1 && item.getDefinition().getConfiguration(ItemConfigSQLHandler.WEAPON_INTERFACE, -1) != -1) {
|
||||
slot = 3;
|
||||
}
|
||||
// slot = 3;
|
||||
if (slot < 0) {
|
||||
return false; // Item can't be equipped.
|
||||
}
|
||||
if (!item.getDefinition().hasRequirement(player, true, true)) {
|
||||
return false;
|
||||
}
|
||||
Item current = super.get(slot);
|
||||
if (current != null && current.getId() == item.getId() && current.getDefinition().isStackable()) {
|
||||
int amount = getMaximumAdd(item);
|
||||
if (item.getAmount() > amount) {
|
||||
amount += current.getAmount();
|
||||
} else {
|
||||
amount = current.getAmount() + item.getAmount();
|
||||
}
|
||||
if (fromInventory) {
|
||||
player.getInventory().remove(new Item(item.getId(), amount - current.getAmount()));
|
||||
}
|
||||
replace(new Item(item.getId(), amount), slot);
|
||||
return true;
|
||||
}
|
||||
if (fromInventory && current != null) {
|
||||
Plugin<Object> plugin = current.getDefinition().getConfiguration("equipment", null);
|
||||
if (plugin != null) {
|
||||
Object object = plugin.fireEvent("unequip", player, current, item);
|
||||
if (object != null && !((Boolean) object)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fromInventory && !player.getInventory().remove(item, inventorySlot, true)) {
|
||||
return false;
|
||||
}
|
||||
Item secondary = null;
|
||||
if (item.getDefinition().getConfiguration(ItemConfigSQLHandler.TWO_HANDED, false)) {
|
||||
secondary = get(SLOT_SHIELD);
|
||||
} else if (slot == SLOT_SHIELD) {
|
||||
secondary = get(SLOT_WEAPON);
|
||||
if (secondary != null && !secondary.getDefinition().getConfiguration(ItemConfigSQLHandler.TWO_HANDED, false)) {
|
||||
secondary = null;
|
||||
}
|
||||
}
|
||||
int currentSlot = -1;
|
||||
if (current != null) {
|
||||
currentSlot = inventorySlot;
|
||||
if (current.getDefinition().isStackable() && player.getInventory().contains(current.getId(), 1)) {
|
||||
currentSlot = -1;
|
||||
}
|
||||
}
|
||||
if (current != null && !player.getInventory().add(current, true, inventorySlot)) {
|
||||
player.getInventory().add(item);
|
||||
player.getPacketDispatch().sendMessage("Not enough space in your inventory!");
|
||||
return false;
|
||||
}
|
||||
if (secondary != null && !player.getInventory().add(secondary)) {
|
||||
if (current != null && currentSlot != -1) {
|
||||
player.getInventory().remove(current, currentSlot, false);
|
||||
}
|
||||
player.getInventory().add(item);
|
||||
player.getPacketDispatch().sendMessage("Not enough space in your inventory!");
|
||||
return false;
|
||||
}
|
||||
super.replace(item, slot, fire);
|
||||
if (item.getSlot() == SLOT_WEAPON) {
|
||||
player.getPacketDispatch().sendString(item.getName(), 92, 0);
|
||||
}
|
||||
if (secondary != null) {
|
||||
super.remove(secondary);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the equipment container.
|
||||
* @author Emperor
|
||||
*/
|
||||
private static class EquipmentListener implements ContainerListener {
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EquipmentContainer} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public EquipmentListener(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Container c, ContainerEvent event) {
|
||||
int[] slots = event.getSlots();
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 387, 28, 94, event.getItems(), false, slots));
|
||||
update(c);
|
||||
boolean updateDefenceAnimation = false;
|
||||
for (int slot : slots) {
|
||||
if (slot == EquipmentContainer.SLOT_WEAPON) {
|
||||
player.getProperties().setAttackSpeed(c.getNew(slot).getDefinition().getConfiguration(ItemConfigSQLHandler.ATTACK_SPEED, 4));
|
||||
WeaponInterface inter = player.getExtension(WeaponInterface.class);
|
||||
if (inter == null) {
|
||||
break;
|
||||
}
|
||||
inter.updateInterface();
|
||||
updateDefenceAnimation = true;
|
||||
} else if (slot == EquipmentContainer.SLOT_SHIELD) {
|
||||
updateDefenceAnimation = true;
|
||||
}
|
||||
}
|
||||
if (updateDefenceAnimation) {
|
||||
player.getProperties().updateDefenceAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Container c) {
|
||||
player.getProperties().setAttackSpeed(c.getNew(3).getDefinition().getConfiguration(ItemConfigSQLHandler.ATTACK_SPEED, 4));
|
||||
WeaponInterface inter = player.getExtension(WeaponInterface.class);
|
||||
if (inter != null) {
|
||||
inter.updateInterface();
|
||||
}
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 387, 28, 94, c.toArray(), 14, false));
|
||||
update(c);
|
||||
player.getProperties().updateDefenceAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bonuses, weight, animations, ...
|
||||
* @param c The container.
|
||||
*/
|
||||
public void update(Container c) {
|
||||
if (c.getNew(SLOT_SHIELD).getId() != 11283 && player.getAttribute("dfs_spec", false)) {
|
||||
player.removeAttribute("dfs_spec");
|
||||
player.getProperties().getCombatPulse().setHandler(null);
|
||||
if (!player.getSettings().isSpecialToggled()) {
|
||||
player.getConfigManager().set(301, 0);
|
||||
}
|
||||
}
|
||||
player.getAppearance().setAnimations();
|
||||
player.getUpdateMasks().register(new AppearanceFlag(player));
|
||||
player.getSettings().updateWeight();
|
||||
updateBonuses(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bonuses.
|
||||
* @param player The player.
|
||||
*/
|
||||
public static void updateBonuses(Player player) {
|
||||
int[] bonuses = new int[15];
|
||||
for (Item item : player.getEquipment().toArray()) {
|
||||
if (item != null) {
|
||||
int[] bonus = item.getDefinition().getConfiguration(ItemConfigSQLHandler.BONUS, new int[15]);
|
||||
for (int i = 0; i < bonus.length; i++) {
|
||||
if (i == 14 && bonuses[i] != 0) {
|
||||
continue;
|
||||
}
|
||||
bonuses[i] += bonus[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
Item shield = player.getEquipment().get(SLOT_SHIELD);
|
||||
if (shield != null && shield.getId() == 11283) {
|
||||
int increase = shield.getCharge() / 20;
|
||||
bonuses[5] += increase;
|
||||
bonuses[6] += increase;
|
||||
bonuses[7] += increase;
|
||||
bonuses[9] += increase;
|
||||
}
|
||||
player.getProperties().setBonuses(bonuses);
|
||||
update(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the equipment stats interface.
|
||||
* @param player The player to update for.
|
||||
*/
|
||||
public static void update(Player player) {
|
||||
if (!player.getInterfaceManager().hasMainComponent(667)) {
|
||||
return;
|
||||
}
|
||||
PacketRepository.send(WeightUpdate.class, player.getPacketDispatch().getContext());
|
||||
int index = 0;
|
||||
int[] bonuses = player.getProperties().getBonuses();
|
||||
for (int i = 36; i < 50; i++) {
|
||||
if (i == 47) {
|
||||
continue;
|
||||
}
|
||||
int bonus = bonuses[index];
|
||||
String bonusValue = bonus > -1 ? ("+" + bonus) : Integer.toString(bonus);
|
||||
player.getPacketDispatch().sendString(BONUS_NAMES[index++] + bonusValue, 667, i);
|
||||
}
|
||||
player.getPacketDispatch().sendString("Attack bonus", 667, 34);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.crandor.game.container.impl;
|
||||
|
||||
import org.crandor.game.container.Container;
|
||||
import org.crandor.game.container.ContainerEvent;
|
||||
import org.crandor.game.container.ContainerListener;
|
||||
import org.crandor.game.content.skill.member.summoning.SummoningPouch;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
|
||||
/**
|
||||
* Handles the inventory container listening.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class InventoryListener implements ContainerListener {
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code InventoryListener} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public InventoryListener(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the required settings etc for the player when the container
|
||||
* updates.
|
||||
* @param c The container.
|
||||
*/
|
||||
public void update(Container c) {
|
||||
player.getSettings().updateWeight();
|
||||
boolean hadPouch = player.getFamiliarManager().isHasPouch();
|
||||
boolean pouch = false;
|
||||
for (Item item : c.toArray()) {
|
||||
if (item != null && SummoningPouch.get(item.getId()) != null) {
|
||||
pouch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.getFamiliarManager().setHasPouch(pouch);
|
||||
if (hadPouch != pouch && player.getSkullManager().isWilderness()) {
|
||||
player.getAppearance().sync();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Container c) {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 149, 0, 93, c, false));
|
||||
update(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Container c, ContainerEvent event) {
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 149, 0, 93, event.getItems(), false, event.getSlots()));
|
||||
update(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package org.crandor.game.content.activity;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manages the activities.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ActivityManager {
|
||||
|
||||
/**
|
||||
* The mapping of instanced activities.
|
||||
*/
|
||||
private static final Map<String, ActivityPlugin> ACTIVITIES = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ActivityManager} {@code Object}.
|
||||
*/
|
||||
private ActivityManager() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an activity plugin.
|
||||
* @param plugin The plugin to register.
|
||||
*/
|
||||
public static void register(ActivityPlugin plugin) {
|
||||
plugin.register();
|
||||
ACTIVITIES.put(plugin.getName(), plugin);
|
||||
if (!plugin.isInstanced()) {
|
||||
plugin.configure();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an instanced activity.
|
||||
* @param player The player.
|
||||
* @param name The name.
|
||||
* @param login If we are logging in.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
public static boolean start(Player player, String name, boolean login, Object... args) {
|
||||
ActivityPlugin plugin = ACTIVITIES.get(name);
|
||||
if (plugin == null) {
|
||||
if (GameWorld.getSettings().isDevMode()) {
|
||||
System.err.println("Unhandled activity - " + name + "!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (plugin.isInstanced()) {
|
||||
(plugin = plugin.newInstance(player)).configure();
|
||||
}
|
||||
return plugin.start(player, login, args);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
if (GameWorld.getSettings().isDevMode()) {
|
||||
player.getPacketDispatch().sendMessage("Error starting activity " + (plugin == null ? null : plugin.getName()) + "!");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the activity by the name.
|
||||
* @param name the name.
|
||||
* @return the activity.
|
||||
*/
|
||||
public static ActivityPlugin getActivity(String name) {
|
||||
return ACTIVITIES.get(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
package org.crandor.game.content.activity;
|
||||
|
||||
import org.crandor.ServerConstants;
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.Region;
|
||||
import org.crandor.game.world.map.build.DynamicRegion;
|
||||
import org.crandor.game.world.map.zone.*;
|
||||
import org.crandor.game.world.map.zone.impl.MultiwayCombatZone;
|
||||
import org.crandor.plugin.Plugin;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
/**
|
||||
* A plugin implementation used for activity plugins.
|
||||
* @author Emperor
|
||||
*/
|
||||
@PluginManifest(type = PluginType.ACTIVITY)
|
||||
public abstract class ActivityPlugin extends MapZone implements Plugin<Player> {
|
||||
|
||||
/**
|
||||
* If the activity is instanced.
|
||||
*/
|
||||
private boolean instanced;
|
||||
|
||||
/**
|
||||
* If the activity is multicombat.
|
||||
*/
|
||||
private boolean multicombat;
|
||||
|
||||
/**
|
||||
* If the activity is safe.
|
||||
*/
|
||||
private boolean safe;
|
||||
|
||||
/**
|
||||
* The region of the activity.
|
||||
*/
|
||||
protected DynamicRegion region;
|
||||
|
||||
/**
|
||||
* The base location.
|
||||
*/
|
||||
protected Location base;
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
protected Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ActivityPlugin} {@code Object}.
|
||||
* @param name The name.
|
||||
* @param instanced If the activity is instanced.
|
||||
* @param multicombat If the activity is multicombat.
|
||||
* @param safe If the activity is safe (the player does not lose his/her
|
||||
* items).
|
||||
*/
|
||||
public ActivityPlugin(String name, boolean instanced, boolean multicombat, boolean safe, ZoneRestriction... restrictions) {
|
||||
super(name, true, ZoneRestriction.RANDOM_EVENTS);
|
||||
for (ZoneRestriction restriction : restrictions) {
|
||||
addRestriction(restriction.getFlag());
|
||||
}
|
||||
this.instanced = instanced;
|
||||
this.multicombat = multicombat;
|
||||
this.safe = safe;
|
||||
if (safe) {
|
||||
setZoneType(ZoneType.SAFE.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ZoneBorders borders) {
|
||||
if (multicombat) {
|
||||
MultiwayCombatZone.getInstance().register(borders);
|
||||
}
|
||||
super.register(borders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the region base location.
|
||||
*/
|
||||
protected void setRegionBase() {
|
||||
if (region != null) {
|
||||
if (multicombat) {
|
||||
region.toggleMulticombat();
|
||||
}
|
||||
setBase(Location.create(region.getBorders().getSouthWestX(), region.getBorders().getSouthWestY(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the region base for multiple regions.
|
||||
* @param regions The regions.
|
||||
*/
|
||||
protected void setRegionBase(DynamicRegion[] regions) {
|
||||
region = regions[0];
|
||||
Location l = region.getBaseLocation();
|
||||
for (DynamicRegion r : regions) {
|
||||
if (r.getX() > l.getX() || r.getY() > l.getY()) {
|
||||
l = r.getBaseLocation();
|
||||
}
|
||||
}
|
||||
ZoneBorders borders = new ZoneBorders(region.getX() << 6, region.getY() << 6, l.getX() + Region.SIZE, l.getY() + Region.SIZE);
|
||||
RegionZone multiZone = multicombat ? new RegionZone(MultiwayCombatZone.getInstance(), borders) : null;
|
||||
RegionZone zone = new RegionZone(this, borders);
|
||||
for (DynamicRegion r : regions) {
|
||||
if (multicombat) {
|
||||
r.setMulticombat(true);
|
||||
r.getRegionZones().add(multiZone);
|
||||
}
|
||||
r.getRegionZones().add(zone);
|
||||
}
|
||||
setBase(Location.create(borders.getSouthWestX(), borders.getSouthWestY(), 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the activity for the player.
|
||||
* @param player The player.
|
||||
* @param login If the player is logging in.
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if successfully started the activity.
|
||||
*/
|
||||
public boolean start(Player player, boolean login, Object... args) {
|
||||
this.player = player;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enter(Entity e) {
|
||||
Location l;
|
||||
if (e instanceof Player && (l = getSpawnLocation()) != null) {
|
||||
e.getProperties().setSpawnLocation(l);
|
||||
}
|
||||
e.getProperties().setSafeZone(safe);
|
||||
e.setAttribute("activity", this);
|
||||
return super.enter(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean leave(Entity e, boolean logout) {
|
||||
if (e instanceof Player) {
|
||||
e.getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION);
|
||||
}
|
||||
Location l;
|
||||
if (instanced && logout && (l = getSpawnLocation()) != null) {
|
||||
e.setLocation(l);
|
||||
}
|
||||
e.getProperties().setSafeZone(false);
|
||||
e.removeAttribute("activity");
|
||||
return super.leave(e, logout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to do anything on registration.
|
||||
*/
|
||||
public void register() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract ActivityPlugin newInstance(Player p) throws Throwable;
|
||||
|
||||
/**
|
||||
* Gets the spawn location for this activity.
|
||||
*/
|
||||
public abstract Location getSpawnLocation();
|
||||
|
||||
/**
|
||||
* Gets the instanced.
|
||||
* @return The instanced.
|
||||
*/
|
||||
public boolean isInstanced() {
|
||||
return instanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the instanced.
|
||||
* @param instanced The instanced to set.
|
||||
*/
|
||||
public void setInstanced(boolean instanced) {
|
||||
this.instanced = instanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the multicombat.
|
||||
* @return The multicombat.
|
||||
*/
|
||||
public boolean isMulticombat() {
|
||||
return multicombat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the multicombat.
|
||||
* @param multicombat The multicombat to set.
|
||||
*/
|
||||
public void setMulticombat(boolean multicombat) {
|
||||
this.multicombat = multicombat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the safe.
|
||||
* @return The safe.
|
||||
*/
|
||||
public boolean isSafe() {
|
||||
return safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the safe.
|
||||
* @param safe The safe to set.
|
||||
*/
|
||||
public void setSafe(boolean safe) {
|
||||
this.safe = safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base.
|
||||
* @return The base.
|
||||
*/
|
||||
public Location getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base.
|
||||
* @param base The base to set.
|
||||
*/
|
||||
public void setBase(Location base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
package org.crandor.game.content.activity;
|
||||
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.npc.NPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.build.DynamicRegion;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.MinimapStateContext;
|
||||
import org.crandor.net.packet.out.MinimapState;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle a cutscene.
|
||||
* @author Vexia
|
||||
* @date 28/12/2013
|
||||
*/
|
||||
@PluginManifest(type = PluginType.ACTIVITY)
|
||||
public abstract class CutscenePlugin extends ActivityPlugin {
|
||||
|
||||
/**
|
||||
* The list of tabs to remove.
|
||||
*/
|
||||
private static final int[] TABS = new int[] { 0, 1, 2, 3, 4, 5, 6, 11, 12 };
|
||||
|
||||
/**
|
||||
* The npcs in our cutscene.
|
||||
*/
|
||||
protected final List<NPC> npcs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The start pulse used for effect.
|
||||
*/
|
||||
private final StartPulse startPulse = new StartPulse();
|
||||
|
||||
/**
|
||||
* The ending pulse used for effect.
|
||||
*/
|
||||
private final EndPulse endPulse = new EndPulse();
|
||||
|
||||
/**
|
||||
* If we should use a fade in or not.
|
||||
*/
|
||||
private final boolean fade;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CutscenePlugin} {@code Object}.
|
||||
* @param name the name of the cutscene/mapzone.
|
||||
* @param fading in or not.
|
||||
*/
|
||||
public CutscenePlugin(String name, final boolean fade) {
|
||||
super(name, true, false, true);
|
||||
this.fade = fade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CutscenePlugin} {@code Object}.
|
||||
* @param name the name.
|
||||
*/
|
||||
public CutscenePlugin(final String name) {
|
||||
this(name, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start(final Player player, boolean login, Object... args) {
|
||||
player.setAttribute("cutscene:original-loc", player.getLocation());
|
||||
player.removeAttribute("real-end");
|
||||
player.setAttribute("real-end", player.getLocation());
|
||||
if (isFade()) {
|
||||
GameWorld.submit(getStartPulse());
|
||||
} else {
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState()));
|
||||
player.getInterfaceManager().hideTabs(getRemovedTabs());
|
||||
player.getProperties().setTeleportLocation(getStartLocation());
|
||||
player.unlock();
|
||||
player.getWalkingQueue().reset();
|
||||
player.getLocks().lockMovement(1000000);
|
||||
player.getInterfaceManager().close();
|
||||
open();
|
||||
}
|
||||
player.lock();
|
||||
return super.start(player, login, args);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean leave(final Entity e, boolean logout) {
|
||||
if (player != null) {
|
||||
if (logout) {
|
||||
player.setLocation(player.getAttribute("cutscene:original-loc", player.getLocation()));
|
||||
end();
|
||||
} else {
|
||||
unpause();
|
||||
}
|
||||
player.unlock();
|
||||
player.getWalkingQueue().reset();
|
||||
player.getLocks().unlockMovement();
|
||||
}
|
||||
return super.leave(e, logout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to stop the cutscene.
|
||||
* @param if we should use a fade cutout.
|
||||
*/
|
||||
public void stop(boolean fade) {
|
||||
if (fade) {
|
||||
GameWorld.submit(endPulse);
|
||||
} else {
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to end the cutscene.
|
||||
*/
|
||||
public void end() {
|
||||
if (region != null) {
|
||||
for (int i = 0; i < region.getPlanes().length; i++) {
|
||||
for (NPC n : region.getPlanes()[i].getNpcs()) {
|
||||
if (n == null) {
|
||||
continue;
|
||||
}
|
||||
n.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0));
|
||||
player.getInterfaceManager().restoreTabs();
|
||||
player.unlock();// incase he was locked.
|
||||
player.getWalkingQueue().reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the pulse used when starting a cutscene. This is used to give
|
||||
* dramatic effect for entering a cutscene. In the future allow for this to
|
||||
* be toggled.
|
||||
* @author 'Vexia
|
||||
* @date 30/12/2013
|
||||
*/
|
||||
public class StartPulse extends Pulse {
|
||||
|
||||
/**
|
||||
* Represents the counter.
|
||||
*/
|
||||
private int counter = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StartPulse} {@code Object}.
|
||||
*/
|
||||
public StartPulse() {
|
||||
super(1, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
case 1:
|
||||
player.lock();
|
||||
player.getInterfaceManager().openOverlay(new Component(115));
|
||||
break;
|
||||
case 3:
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState()));
|
||||
player.getInterfaceManager().hideTabs(getRemovedTabs());
|
||||
break;
|
||||
case 4:
|
||||
player.getProperties().setTeleportLocation(getStartLocation());
|
||||
break;
|
||||
case 5:
|
||||
player.getInterfaceManager().closeOverlay();
|
||||
player.getInterfaceManager().close();
|
||||
player.unlock();
|
||||
player.getWalkingQueue().reset();
|
||||
player.getLocks().lockMovement(1000000);
|
||||
open();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the pulse used when ending a cutscene. This is used to give
|
||||
* dramatic effect for entering a cutscene.
|
||||
* @author 'Vexia
|
||||
* @date 30/12/2013
|
||||
*/
|
||||
public class EndPulse extends Pulse {
|
||||
|
||||
/**
|
||||
* Represents the counter.
|
||||
*/
|
||||
private int counter = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EndPulse} {@code Object}.
|
||||
*/
|
||||
public EndPulse() {
|
||||
super(1, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
case 1:
|
||||
player.lock();
|
||||
player.getInterfaceManager().openOverlay(new Component(115));
|
||||
break;
|
||||
case 3:
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState()));
|
||||
player.getInterfaceManager().hideTabs(getRemovedTabs());
|
||||
break;
|
||||
case 4:
|
||||
Location loc = (Location) (player.getAttribute("real-end", player.getAttribute("cutscene:original-loc", player.getLocation())));
|
||||
player.getProperties().setTeleportLocation(loc);
|
||||
break;
|
||||
case 5:
|
||||
end();
|
||||
stop();
|
||||
fade();// specfic for fadeout.
|
||||
if (player.getSession().isActive()) {
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0));
|
||||
}
|
||||
player.getInterfaceManager().closeOverlay();
|
||||
if (player.getSession().isActive()) {
|
||||
player.getInterfaceManager().close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when the dim interface is closed. And you can see the
|
||||
* cutscene.
|
||||
*/
|
||||
public void open() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called on the end of the cutscene.
|
||||
*/
|
||||
public void fade() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mapstate to use. (override if needed).
|
||||
* @return the state.
|
||||
*/
|
||||
public int getMapState() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the removed tabs. (override if needed).
|
||||
* @return the tabs.
|
||||
*/
|
||||
public int[] getRemovedTabs() {
|
||||
return TABS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the starting location (region based, override if needed).
|
||||
* @return the location.
|
||||
*/
|
||||
public Location getStartLocation() {
|
||||
return getBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to unpause this cutscene.
|
||||
*/
|
||||
public final void unpause() {
|
||||
stop(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the region.
|
||||
* @return The region.
|
||||
*/
|
||||
public DynamicRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nPCS.
|
||||
* @return The nPCS.
|
||||
*/
|
||||
public List<NPC> getNPCS() {
|
||||
return npcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fade.
|
||||
* @return The fade.
|
||||
*/
|
||||
public boolean isFade() {
|
||||
return fade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start pulse.
|
||||
* @return the pulse.
|
||||
*/
|
||||
public Pulse getStartPulse() {
|
||||
return startPulse;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package org.crandor.game.content.ame;
|
||||
|
||||
import org.crandor.game.content.dialogue.DialoguePlugin;
|
||||
import org.crandor.game.node.entity.npc.NPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
import org.crandor.game.world.update.flag.context.Graphics;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
/**
|
||||
* Handles the dialogue of an anti macro npc.
|
||||
* @author Vexia
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public abstract class AntiMacroDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* The anti macro event.
|
||||
*/
|
||||
protected AntiMacroEvent event;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AntiMacroDialogue} {@code Object}.
|
||||
*/
|
||||
public AntiMacroDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AntiMacroDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public AntiMacroDialogue(final Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
if (!player.getAntiMacroHandler().isNPC(npc, true)) {
|
||||
end();
|
||||
return false;
|
||||
}
|
||||
if (player.getAntiMacroHandler().getEvent() == null) {
|
||||
return false;
|
||||
}
|
||||
if (asAme().inCombat()) {
|
||||
asAme().getProperties().getCombatPulse().stop();
|
||||
}
|
||||
|
||||
setEvent(player.getAntiMacroHandler().getEvent());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper method for waving the npc good bye.
|
||||
*/
|
||||
public void wave() {
|
||||
wave(Animation.create(863));
|
||||
}
|
||||
|
||||
/**
|
||||
* Waves the npc good bye.
|
||||
* @param animation the wave animation.
|
||||
*/
|
||||
public void wave(Animation wave) {
|
||||
end();
|
||||
npc.lock();
|
||||
if (wave != null) {
|
||||
npc.animate(wave);
|
||||
}
|
||||
GameWorld.submit(new Pulse(4, npc, player) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
((AntiMacroNPC) npc).clear();
|
||||
Graphics.send(new Graphics(86), npc.getLocation());
|
||||
//player.getPacketDispatch().sendPositionedGraphic(86, 0, 1, npc.getLocation());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
event.terminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npc as an AME.
|
||||
* @return the ame.
|
||||
*/
|
||||
public AntiMacroNPC asAme() {
|
||||
return ((AntiMacroNPC) npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event.
|
||||
* @return The event.
|
||||
*/
|
||||
public AntiMacroEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event.
|
||||
* @param event The event to set.
|
||||
*/
|
||||
public void setEvent(AntiMacroEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
package org.crandor.game.content.ame;
|
||||
|
||||
import org.crandor.game.content.activity.ActivityPlugin;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.login.SavingModule;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.zone.ZoneRestriction;
|
||||
import org.crandor.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles an anti-macro event.
|
||||
* @author Emperor
|
||||
*/
|
||||
public abstract class AntiMacroEvent extends ActivityPlugin implements SavingModule {
|
||||
|
||||
/**
|
||||
* The random locations to teleport to if unresponsive.
|
||||
*/
|
||||
public static final Location[] LOCATIONS = new Location[] { Location.create(3218, 9616, 0),// Lumby
|
||||
// basement
|
||||
Location.create(3200, 3228, 0),// behind lumby
|
||||
Location.create(2961, 3381, 0),// Fally square
|
||||
};
|
||||
|
||||
/**
|
||||
* The skill ids.
|
||||
*/
|
||||
private final int[] skillIds;
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
protected Player player;
|
||||
|
||||
/**
|
||||
* If the anti-macro event is terminated.
|
||||
*/
|
||||
protected boolean terminated;
|
||||
|
||||
/**
|
||||
* If saving is required.
|
||||
*/
|
||||
private boolean saveRequired;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AntiMacroEvent} {@code Object}.
|
||||
* @param name The random event name.
|
||||
* @param instanced If the event is instanced.
|
||||
* @param saveRequired .
|
||||
* @param skillIds The skill ids of the skills that fire this event (nothing
|
||||
* for default).
|
||||
*/
|
||||
public AntiMacroEvent(String name, boolean instanced, boolean saveRequired, int... skillIds) {
|
||||
super(name, instanced, false, false, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FIRES, ZoneRestriction.FOLLOWERS);
|
||||
this.saveRequired = saveRequired;
|
||||
this.skillIds = skillIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AntiMacroEvent newInstance(Player player) {
|
||||
AntiMacroHandler.register(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean start(Player player, boolean login, Object... args);
|
||||
|
||||
/**
|
||||
* Creates a new anti macro event instance.
|
||||
* @param player The player.
|
||||
* @return The anti macro event instance.
|
||||
*/
|
||||
public abstract AntiMacroEvent create(Player player);
|
||||
|
||||
/**
|
||||
* Called to end the macro event.
|
||||
*/
|
||||
public void terminate() {
|
||||
if (terminated) {
|
||||
return;
|
||||
}
|
||||
if (player != null) {
|
||||
player.getAntiMacroHandler().setEvent(null);
|
||||
}
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the random event for the player.
|
||||
* @param player The player.
|
||||
*/
|
||||
public void init(Player player) {
|
||||
player.addExtension(AntiMacroEvent.class, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes all the items in an inventory.
|
||||
*/
|
||||
public void noteItems() {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
for (Item i : player.getInventory().toArray()) {
|
||||
if (i == null || !i.isActive()) {
|
||||
continue;
|
||||
}
|
||||
if (i.getDefinition().isUnnoted()) {
|
||||
int noteId = i.getDefinition().getNoteId();
|
||||
if (noteId < 0) {
|
||||
continue;
|
||||
}
|
||||
player.getInventory().remove(i);
|
||||
player.getInventory().add(new Item(noteId, i.getAmount()));
|
||||
}
|
||||
}
|
||||
player.getInventory().shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the macro event can be fired for the given skill id.
|
||||
* @param skillId The skill id.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean canFire(int skillId) {
|
||||
if (skillIds.length == 0) {
|
||||
return true;
|
||||
}
|
||||
for (int id : skillIds) {
|
||||
if (id == skillId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random location.
|
||||
* @return a random location.
|
||||
*/
|
||||
public static Location getRandomLocation() {
|
||||
return LOCATIONS[RandomFunction.random(LOCATIONS.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to get the gender prefix.
|
||||
* @return the prefix.
|
||||
*/
|
||||
public String getGenderPrefix() {
|
||||
return getGenderPrefix(player.getAppearance().isMale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the gender prefix.
|
||||
* @param if male.
|
||||
* @return the prefix.
|
||||
*/
|
||||
public String getGenderPrefix(boolean male) {
|
||||
return male ? "Sir" : "Mam";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the terminated.
|
||||
* @return The terminated.
|
||||
*/
|
||||
public boolean isTerminated() {
|
||||
return terminated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the terminated.
|
||||
* @param terminated The terminated to set.
|
||||
*/
|
||||
public void setTerminated(boolean terminated) {
|
||||
this.terminated = terminated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the saveRequired.
|
||||
* @return The saveRequired.
|
||||
*/
|
||||
public boolean isSaveRequired() {
|
||||
return saveRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the saveRequired.
|
||||
* @param saveRequired The saveRequired to set.
|
||||
*/
|
||||
public void setSaveRequired(boolean saveRequired) {
|
||||
this.saveRequired = saveRequired;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
package org.crandor.game.content.ame;
|
||||
|
||||
import org.crandor.cache.misc.buffer.ByteBufferUtils;
|
||||
import org.crandor.game.content.skill.Skills;
|
||||
import org.crandor.game.node.entity.npc.NPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.login.SavingModule;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.zone.ZoneRestriction;
|
||||
import org.crandor.tools.RandomFunction;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles anti-macroing.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class AntiMacroHandler implements SavingModule {
|
||||
|
||||
/**
|
||||
* The update frequency.
|
||||
*/
|
||||
private static final int UPDATE_FREQUENCY = 50;
|
||||
|
||||
/**
|
||||
* The ratio of firing events, the higher the less frequent.
|
||||
*/
|
||||
public static int FIRE_RATIO = 250;
|
||||
|
||||
/**
|
||||
* The list of anti-macro events.
|
||||
*/
|
||||
public static final Map<String, AntiMacroEvent> EVENTS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* The last pulse tick.
|
||||
*/
|
||||
private int nextPulse;
|
||||
|
||||
/**
|
||||
* The current event.
|
||||
*/
|
||||
private AntiMacroEvent event;
|
||||
|
||||
/**
|
||||
* The experience monitors.
|
||||
*/
|
||||
private ExperienceMonitor[] monitors = new ExperienceMonitor[Skills.SKILL_NAME.length];
|
||||
|
||||
/**
|
||||
* The chance ratio of firing random events.
|
||||
*/
|
||||
private final int[] chanceRatio = new int[Skills.SKILL_NAME.length];
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AntiMacroHandler} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public AntiMacroHandler(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if saving is required.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isSaveRequired() {
|
||||
return hasEvent() && event.isSaveRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ByteBuffer buffer) {
|
||||
if (hasEvent()) {
|
||||
buffer.put((byte) 1);
|
||||
ByteBufferUtils.putString(event.getName(), buffer);
|
||||
buffer.put((byte) 0);
|
||||
int index = buffer.position();
|
||||
event.save(buffer);
|
||||
buffer.put(index - 1, (byte) (buffer.position() - index));
|
||||
}
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(ByteBuffer buffer) {
|
||||
event = null;
|
||||
while (true) {
|
||||
switch (buffer.get() & 0xFF) {
|
||||
case 0:
|
||||
return;
|
||||
case 1:
|
||||
event = EVENTS.get(ByteBufferUtils.getString(buffer));
|
||||
int length = buffer.get() & 0xFF;
|
||||
ByteBuffer buf = ByteBuffer.allocate(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
buf.put(buffer.get());
|
||||
}
|
||||
buf.flip();
|
||||
if (event != null) {
|
||||
(event = event.create(player)).parse(buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets called every game pulse.
|
||||
*/
|
||||
public void pulse() {
|
||||
if (GameWorld.getTicks() < nextPulse) {
|
||||
return;
|
||||
}
|
||||
if (!player.getLocks().isInteractionLocked() && !player.getLocks().isTeleportLocked() && !player.getLocks().isMovementLocked()) {
|
||||
for (int i = 0; i < monitors.length; i++) {
|
||||
FIRE_RATIO = 250;
|
||||
if (chanceRatio[i] > FIRE_RATIO) {
|
||||
fireEvent(i);
|
||||
}
|
||||
ExperienceMonitor monitor = monitors[i];
|
||||
if (monitor.getExperienceAmount() > 0) {
|
||||
double modifier = monitor.getExperienceAmount() / UPDATE_FREQUENCY;
|
||||
chanceRatio[i] += modifier;
|
||||
monitor.setExperienceAmount(0);
|
||||
} else if ((chanceRatio[i] -= 5) < 0) {
|
||||
chanceRatio[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
nextPulse = GameWorld.getTicks() + UPDATE_FREQUENCY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the trigger chance ratio.
|
||||
*/
|
||||
public void resetTrigger() {
|
||||
for (int j = 0; j < chanceRatio.length; j++) {
|
||||
chanceRatio[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chance ratio.
|
||||
* @param skillId The skill id.
|
||||
* @return The chance ratio.
|
||||
*/
|
||||
public int getChanceRatio(int skillId) {
|
||||
return chanceRatio[skillId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the anti macro event handler.
|
||||
*/
|
||||
public void init() {
|
||||
for (int i = 0; i < monitors.length; i++) {
|
||||
monitors[i] = new ExperienceMonitor(i);
|
||||
}
|
||||
nextPulse = GameWorld.getTicks() + UPDATE_FREQUENCY;
|
||||
if (event != null) {
|
||||
event.start(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new anti-macro event.
|
||||
* @param event The event.
|
||||
*/
|
||||
public static void register(AntiMacroEvent event) {
|
||||
event.register();
|
||||
EVENTS.put(event.getName(), event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers experience gain.
|
||||
* @param skill The skill id.
|
||||
* @param experience The experience gained.
|
||||
*/
|
||||
public void registerExperience(int skill, double experience) {
|
||||
monitors[skill].setExperienceAmount((int) (monitors[skill].getExperienceAmount() + experience));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the npc is part of the event.
|
||||
* @param npc the npc.
|
||||
* @return {@code True} if so.
|
||||
* @param message the message.
|
||||
*/
|
||||
public boolean isNPC(NPC npc, boolean message) {
|
||||
if (!hasEvent()) {
|
||||
if (message) {
|
||||
player.getPacketDispatch().sendMessage("They don't seem interested in talking to you.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
AntiMacroNPC n = (AntiMacroNPC) npc;
|
||||
if (n.getEvent() != event) {
|
||||
if (message) {
|
||||
player.getPacketDispatch().sendMessage("They don't seem interested in talking to you.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires an anti-macro event.
|
||||
* @param name The name of the event to start.
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if the event has been fired.
|
||||
*/
|
||||
public boolean fireEvent(String name, Object... args) {
|
||||
if (hasEvent() || player.getZoneMonitor().isRestricted(ZoneRestriction.RANDOM_EVENTS) || player.isArtificial()) {
|
||||
return false;
|
||||
}
|
||||
AntiMacroEvent event = EVENTS.get(name);
|
||||
if (event == null) {
|
||||
if (GameWorld.getSettings().isDevMode()) {
|
||||
throw new IllegalArgumentException("Could not find event " + name + "!");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
event = event.create(player);
|
||||
if (!event.start(player, false, args)) {
|
||||
return false;
|
||||
}
|
||||
resetTrigger();
|
||||
this.event = event;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires an event.
|
||||
* @param skillId The skill id, -1 for default events..
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if the event has been fired.
|
||||
*/
|
||||
public boolean fireEvent(int skillId, Object... args) {
|
||||
if (hasEvent() || EVENTS.isEmpty() || player.getZoneMonitor().isRestricted(ZoneRestriction.RANDOM_EVENTS) || player.isArtificial()) {
|
||||
return false;
|
||||
}
|
||||
event = getRandomEvent(skillId);
|
||||
if (event != null) {
|
||||
if ((event = event.create(player)).start(player, false, args)) {
|
||||
resetTrigger();
|
||||
return true;
|
||||
}
|
||||
event = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an anti marco event.
|
||||
* @param skillId the skillId.
|
||||
* @return {@code AntiMacroEvent} the event.
|
||||
*/
|
||||
public AntiMacroEvent getRandomEvent(int skillId) {
|
||||
int index = RandomFunction.random(EVENTS.size());
|
||||
int count = 0;
|
||||
AntiMacroEvent event = null;
|
||||
AntiMacroEvent[] events = EVENTS.values().toArray(new AntiMacroEvent[EVENTS.size()]);
|
||||
while (!(event = events[index]).canFire(skillId)) {
|
||||
if (count++ >= events.length) {
|
||||
event = null;
|
||||
break;
|
||||
}
|
||||
index = (index + 1) % events.length;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has an anti-macro event running.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasEvent() {
|
||||
return event != null && !event.isTerminated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event.
|
||||
* @return The event.
|
||||
*/
|
||||
public AntiMacroEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event.
|
||||
* @param event The event to set.
|
||||
*/
|
||||
public void setEvent(AntiMacroEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
package org.crandor.game.content.ame;
|
||||
|
||||
import org.crandor.game.interaction.MovementPulse;
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.combat.CombatStyle;
|
||||
import org.crandor.game.node.entity.npc.AbstractNPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.RegionManager;
|
||||
import org.crandor.game.world.map.path.Pathfinder;
|
||||
import org.crandor.game.world.update.flag.context.Graphics;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Handles an anti macro npc.
|
||||
* @author Vexia
|
||||
*/
|
||||
public abstract class AntiMacroNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
protected final Player player;
|
||||
|
||||
/**
|
||||
* The anti macro event.
|
||||
*/
|
||||
protected final AntiMacroEvent event;
|
||||
|
||||
/**
|
||||
* The quotes the npc will say(null if none)
|
||||
*/
|
||||
private String[] quotes;
|
||||
|
||||
/**
|
||||
* The counter representing speech cycles.
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* The time until the next speech.
|
||||
*/
|
||||
private int nextSpeech;
|
||||
|
||||
/**
|
||||
* If the players time is up.
|
||||
*/
|
||||
protected boolean timeUp;
|
||||
|
||||
/**
|
||||
* The end time.
|
||||
*/
|
||||
private int endTime;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code AntiMacroNPC} {@code Object}.
|
||||
* @param id the id.
|
||||
* @param location the location.
|
||||
* @param player the player.
|
||||
*/
|
||||
public AntiMacroNPC(int id, Location location, AntiMacroEvent event, Player player, String... quotes) {
|
||||
super(id, location);
|
||||
this.event = event;
|
||||
this.player = player;
|
||||
this.quotes = quotes;
|
||||
this.endTime = (int) (GameWorld.getTicks() + (1000 / 0.6));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (event == null) {
|
||||
super.clear();
|
||||
return;
|
||||
}
|
||||
location = RegionManager.getSpawnLocation(player, this);
|
||||
if (location == null) {
|
||||
clear();
|
||||
event.terminate();
|
||||
return;
|
||||
}
|
||||
super.init();
|
||||
startFollowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
if (GameWorld.getTicks() > endTime) {
|
||||
clear();
|
||||
}
|
||||
if (!getLocks().isMovementLocked()) {
|
||||
if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) {
|
||||
dialoguePlayer = null;
|
||||
}
|
||||
}
|
||||
if (!player.isActive() || !getLocation().withinDistance(player.getLocation(), 10)) {
|
||||
handlePlayerLeave();
|
||||
}
|
||||
if (!getPulseManager().hasPulseRunning()) {
|
||||
startFollowing();
|
||||
}
|
||||
if (quotes != null) {
|
||||
if (nextSpeech < GameWorld.getTicks() && this.getDialoguePlayer() == null && !this.getLocks().isMovementLocked()) {
|
||||
if (count > quotes.length - 1) {
|
||||
return;
|
||||
}
|
||||
sendChat(quotes[count].replace("@name", player.getUsername()).replace("@gender", event.getGenderPrefix()).replace("@gL", event.getGenderPrefix().toLowerCase()));
|
||||
nextSpeech = (int) (GameWorld.getTicks() + (20 / 0.5));
|
||||
if (++count >= quotes.length) {
|
||||
setTimeUp(true);
|
||||
handleTimeUp();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the player is gone.
|
||||
*/
|
||||
public void handlePlayerLeave() {
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the quotes are finished.
|
||||
*/
|
||||
public void handleTimeUp() {
|
||||
teleport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttackable(Entity entity, CombatStyle style) {
|
||||
if (entity instanceof Player && entity != player) {
|
||||
((Player) entity).getPacketDispatch().sendMessage("It's not after you.");
|
||||
return false;
|
||||
}
|
||||
return super.isAttackable(entity, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegionInactivity() {
|
||||
super.onRegionInactivity();
|
||||
clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
if (event != null) {
|
||||
event.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNPC construct(int id, Location location, Object... objects) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports the player away.
|
||||
*/
|
||||
public void teleport() {
|
||||
player.lock();
|
||||
GameWorld.submit(new Pulse(1, player) {
|
||||
int count;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (++count) {
|
||||
case 1:
|
||||
clear();
|
||||
player.getProperties().setTeleportLocation(AntiMacroEvent.getRandomLocation());
|
||||
break;
|
||||
case 2:
|
||||
player.unlock();
|
||||
event.noteItems();
|
||||
player.graphics(Graphics.create(86));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts following the player.
|
||||
*/
|
||||
public void startFollowing() {
|
||||
getPulseManager().run(new MovementPulse(this, player, Pathfinder.DUMB) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
return false;
|
||||
}
|
||||
}, "movement");
|
||||
face(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
return super.newInstance(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event.
|
||||
* @return The event.
|
||||
*/
|
||||
public AntiMacroEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timeUp.
|
||||
* @return The timeUp.
|
||||
*/
|
||||
public boolean isTimeUp() {
|
||||
return timeUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timeUp.
|
||||
* @param timeUp The timeUp to set.
|
||||
*/
|
||||
public void setTimeUp(boolean timeUp) {
|
||||
this.timeUp = timeUp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package org.crandor.game.content.ame;
|
||||
|
||||
/**
|
||||
* Used to monitor experience gain.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ExperienceMonitor {
|
||||
|
||||
/**
|
||||
* The skill id.
|
||||
*/
|
||||
private final int skillId;
|
||||
|
||||
/**
|
||||
* The amount of experience gained since the last monitor pulse.
|
||||
*/
|
||||
private int experienceAmount;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ExperienceMonitor} {@code Object}.
|
||||
* @param skillId The skill id.
|
||||
*/
|
||||
public ExperienceMonitor(int skillId) {
|
||||
this.skillId = skillId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experienceAmount.
|
||||
* @return The experienceAmount.
|
||||
*/
|
||||
public int getExperienceAmount() {
|
||||
return experienceAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the experienceAmount.
|
||||
* @param experienceAmount The experienceAmount to set.
|
||||
*/
|
||||
public void setExperienceAmount(int experienceAmount) {
|
||||
this.experienceAmount = experienceAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skillId.
|
||||
* @return The skillId.
|
||||
*/
|
||||
public int getSkillId() {
|
||||
return skillId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.crandor.game.content.dialogue;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* A dialogue reward.
|
||||
* @author Vexia
|
||||
*/
|
||||
public interface DialogueAction {
|
||||
|
||||
/**
|
||||
* Handles a dialogue click.
|
||||
* @param player the player.
|
||||
* @param buttonId the buttonId.
|
||||
*/
|
||||
public void handle(Player player, int buttonId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,610 @@
|
|||
package org.crandor.game.content.dialogue;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.cache.def.impl.NPCDefinition;
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.content.global.tutorial.TutorialSession;
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.npc.NPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.mysql.impl.ItemConfigSQLHandler;
|
||||
import org.crandor.game.system.script.ScriptContext;
|
||||
import org.crandor.game.system.script.ScriptManager;
|
||||
import org.crandor.game.system.script.context.*;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles the dialogues.
|
||||
* @author Emperor
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public final class DialogueInterpreter {
|
||||
|
||||
/**
|
||||
* The dialogue plugins.
|
||||
*/
|
||||
private static final Map<Integer, DialoguePlugin> PLUGINS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The dialogue scripts.
|
||||
*/
|
||||
private static final Map<Integer, ScriptContext> SCRIPTS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* a List of dialogue actions.
|
||||
*/
|
||||
private final List<DialogueAction> actions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The currently opened dialogue.
|
||||
*/
|
||||
private DialoguePlugin dialogue;
|
||||
|
||||
/**
|
||||
* Scripted dialogue current stage.
|
||||
*/
|
||||
private ScriptContext dialogueStage;
|
||||
|
||||
/**
|
||||
* The current dialogue key.
|
||||
*/
|
||||
private int key;
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialogueInterpreter} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public DialogueInterpreter(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dialogue the dialogue to set.
|
||||
*/
|
||||
public void setDialogue(DialoguePlugin dialogue) {
|
||||
this.dialogue = dialogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialogue for the given dialogue type.
|
||||
* @param dialogueType The dialogue type.
|
||||
* @param args the args.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean open(String dialogueType, Object... args) {
|
||||
return open(getDialogueKey(dialogueType), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialogue for the given NPC id.
|
||||
* @param dialogueKey The dialogue key (usually NPC id).
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean open(int dialogueKey, Object... args) {
|
||||
key = dialogueKey;
|
||||
if (args.length > 0 && args[0] instanceof NPC) {
|
||||
NPC npc = (NPC) args[0];
|
||||
npc.setDialoguePlayer(player);
|
||||
npc.getWalkingQueue().reset();
|
||||
npc.getPulseManager().clear();
|
||||
} else if (args.length < 1) {
|
||||
args = new Object[] { dialogueKey };
|
||||
}
|
||||
ScriptContext script = SCRIPTS.get(dialogueKey);
|
||||
if (script != null) {
|
||||
Object[] arguments = new Object[args.length + 1];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
arguments[i + 1] = args[i];
|
||||
}
|
||||
arguments[0] = player;
|
||||
startScript(script, arguments);
|
||||
return true;
|
||||
}
|
||||
DialoguePlugin plugin = PLUGINS.get(dialogueKey);
|
||||
if (plugin == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.isDebug()) {
|
||||
player.sendMessage("Dialogue opening - " + plugin.getClass().getSimpleName() + ", key=" + dialogueKey + "");
|
||||
}
|
||||
this.dialogue = plugin.newInstance(player);
|
||||
if (dialogue == null || !dialogue.open(args)) {
|
||||
dialogue = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a dialogue script.
|
||||
* @param script The script.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
public void startScript(ScriptContext script, Object... args) {
|
||||
startScript(key, script, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a dialogue script.
|
||||
* @param dialogueKey The dialogue key.
|
||||
* @param script The script.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
public void startScript(int dialogueKey, ScriptContext script, Object... args) {
|
||||
key = dialogueKey;
|
||||
(dialogueStage = script).execute(args);
|
||||
if (script != null && script.isInstant()) {
|
||||
dialogueStage = script = ScriptManager.run(script, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an dialogue input.
|
||||
* @param componentId The id of the chatbox component.
|
||||
* @param buttonId The button id.
|
||||
*/
|
||||
public void handle(int componentId, int buttonId) {
|
||||
if (dialogueStage != null) {
|
||||
dialogueStage = ScriptManager.run(dialogueStage, player, key, buttonId);
|
||||
if (!(dialogueStage instanceof PDialInstruction || dialogueStage instanceof NPCDialInstruction || dialogueStage instanceof OptionDialInstruction || dialogueStage instanceof PlainMessageInstruction || dialogueStage instanceof ItemMessageInstruction)) {
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
}
|
||||
return;
|
||||
}
|
||||
player.getDialogueInterpreter().getDialogue().handle(componentId, buttonId - 1);//here
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the current dialogue.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean close() {
|
||||
if (dialogue != null || dialogueStage != null) {
|
||||
actions.clear();
|
||||
if (player.getInterfaceManager().getChatbox() != null && player.getInterfaceManager().getChatbox().getCloseEvent() != null) {
|
||||
return true;
|
||||
}
|
||||
if (dialogueStage != null) {
|
||||
dialogueStage = null;
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
}
|
||||
if (dialogue != null && dialogue.close()) {
|
||||
dialogue = null;
|
||||
}
|
||||
}
|
||||
return dialogue == null && dialogueStage == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a dialogue plugin on the mapping.
|
||||
* @param id The NPC id (or {@code 1 << 16 | dialogueId} when the dialogue
|
||||
* isn't for an NPC).
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public static void add(int id, DialoguePlugin plugin) {
|
||||
if (PLUGINS.containsKey(id)) {
|
||||
throw new IllegalArgumentException("Dialogue " + (id & 0xFFFF) + " is already in use - [old=" + PLUGINS.get(id).getClass().getSimpleName() + ", new=" + plugin.getClass().getSimpleName() + "]!");
|
||||
}
|
||||
PLUGINS.put(id, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dialogue script for the given key.
|
||||
* @param dialogueKey The dialogue key.
|
||||
* @param context The dialogue script.
|
||||
*/
|
||||
public static void add(int dialogueKey, ScriptContext context) {
|
||||
if (SCRIPTS.containsKey(dialogueKey)) {
|
||||
// throw new IllegalArgumentException("Dialogue " + dialogueKey +
|
||||
// " is already in use - [old=" +
|
||||
// SCRIPTS.get(dialogueKey).getClass().getSimpleName() + ", new=" +
|
||||
// context.getClass().getSimpleName() + "]!");
|
||||
}
|
||||
SCRIPTS.put(dialogueKey, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the script context for the given dialogue key.
|
||||
* @param key The dialogue key.
|
||||
* @return The script context.
|
||||
*/
|
||||
public static ScriptContext getScript(int key) {
|
||||
return SCRIPTS.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plane messages based on the amount of specified messages.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogue(String... messages) {
|
||||
if (messages.length < 1 || messages.length > 4) {
|
||||
return null;
|
||||
}
|
||||
int interfaceId = 209 + messages.length;
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], interfaceId, i + 1);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
if (player.getAttribute("tut-island", false)) {
|
||||
|
||||
}
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 1, false);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a plane message and hides the continue button.
|
||||
* @param hideContinue if we should hide it or not.
|
||||
* @param messages the messages.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component sendPlainMessage(final boolean hideContinue, String... messages) {
|
||||
sendDialogue(messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), (messages.length + 1), hideContinue);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the destroy item chatbox interface.
|
||||
* @param id The item id.
|
||||
* @param message The message to display.
|
||||
* @return The component.
|
||||
*/
|
||||
public Component sendDestroyItem(int id, String message) {
|
||||
player.getInterfaceManager().openChatbox(94);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 94, 93, 93, new Item[] { new Item(id) }, 1, false));
|
||||
String text = ItemDefinition.forId(id).getConfiguration(ItemConfigSQLHandler.DESTROY_MESSAGE, "Are you sure you want to destroy this object?");
|
||||
if (text.length() > 200) {
|
||||
String[] words = text.split(" ");
|
||||
StringBuilder sb = new StringBuilder(words[0]);
|
||||
for (int i = 1; i < words.length; i++) {
|
||||
if (i == (words.length / 2)) {
|
||||
sb.append("<br>");
|
||||
} else {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(words[i]);
|
||||
}
|
||||
text = sb.toString();
|
||||
}
|
||||
player.getPacketDispatch().sendString("Are you sure you want to destroy this object?", 94, 2);
|
||||
player.getPacketDispatch().sendString("Yes.", 94, 3);
|
||||
player.getPacketDispatch().sendString("No.", 94, 4);
|
||||
player.getPacketDispatch().sendString(text, 94, 7);
|
||||
player.getPacketDispatch().sendString(ItemDefinition.forId(id).getName(), 94, 8);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plane messages with a blue title.
|
||||
* @param title The title.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendPlaneMessageWithBlueTitle(String title, String... messages) {
|
||||
player.getPacketDispatch().sendString(title, 372, 0);
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], 372, i + 1);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(372);
|
||||
if (player.getAttributes().containsKey("tut-island") || TutorialSession.getExtension(player).getStage() <= TutorialSession.MAX_STAGE) {
|
||||
}
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plane messages with scroll and a blue title.
|
||||
* @param title The title.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendScrollMessageWithBlueTitle(String title, String... messages) {
|
||||
for (int i = 0; i < 11; i++) {
|
||||
player.getPacketDispatch().sendString(" ", 421, i + 2);
|
||||
}
|
||||
player.getPacketDispatch().sendString(title, 421, 1);
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], 421, i + 2);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(421);
|
||||
if (player.getAttributes().containsKey("tut-island")) {
|
||||
}
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public Component sendItemMessage(int itemId, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
*/
|
||||
public Component sendItemMessage(final Item item, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(item.getId(), item.getAmount(), 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param message The message.
|
||||
*/
|
||||
public Component sendDoubleItemMessage(int first, int second, String message) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(first, 1, 131, 0);
|
||||
player.getPacketDispatch().sendItemOnInterface(second, 1, 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param message The message.
|
||||
*/
|
||||
public Component sendDoubleItemMessage(Item first, Item second, String message) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(first.getId(), first.getAmount(), 131, 0);
|
||||
player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param entity The entity.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, FacialExpression expression, String... messages) {
|
||||
return sendDialogues(entity, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param entity The entity.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, int expression, String... messages) {
|
||||
return sendDialogues(entity instanceof Player ? -1 : ((NPC) entity).getShownNPC(player).getId(), expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, FacialExpression expression, boolean hide, String... messages) {
|
||||
sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, FacialExpression expression, boolean hide, String... messages) {
|
||||
sendDialogues(entity, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, int expression, boolean hide, String... messages) {
|
||||
sendDialogues(entity, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param entity The entity.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, int expression, boolean hide, String... messages) {
|
||||
sendDialogues(npcId, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, FacialExpression expression, String... messages) {
|
||||
return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, int expression, String... messages) {
|
||||
if (messages.length < 1 || messages.length > 4) {
|
||||
return null;
|
||||
}
|
||||
boolean npc = npcId > -1;
|
||||
int interfaceId = (npc ? 240 : 63) + messages.length;
|
||||
if (expression == -1) {
|
||||
expression = FacialExpression.NORMAL.getAnimationId();
|
||||
}
|
||||
player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2);
|
||||
if (npc) {
|
||||
player.getPacketDispatch().sendNpcOnInterface(npcId, interfaceId, 2);
|
||||
player.getPacketDispatch().sendString(NPCDefinition.forId(npcId).getName(), interfaceId, 3);
|
||||
} else {
|
||||
player.getPacketDispatch().sendPlayerOnInterface(interfaceId, 2);
|
||||
player.getPacketDispatch().sendString(player.getUsername(), interfaceId, 3);
|
||||
}
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i].toString().replace("@name", player.getUsername()), interfaceId, (i + 4));
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
if (player.getAttributes().containsKey("tut-island") || TutorialSession.getExtension(player).getStage() <= TutorialSession.MAX_STAGE) {
|
||||
}
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send options based on the amount of specified options.
|
||||
* @param title The title.
|
||||
* @param options The options.
|
||||
*/
|
||||
public void sendOptions(Object title, String... options) {
|
||||
int interfaceId = 224 + (2 * options.length);
|
||||
if (options.length < 2 || options.length > 5) {
|
||||
return;
|
||||
}
|
||||
if (title != null) {
|
||||
player.getPacketDispatch().sendString(title.toString(), interfaceId, 1);
|
||||
}
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
player.getPacketDispatch().sendString(options[i].toString(), interfaceId, i + 2);
|
||||
}
|
||||
if (player.getAttributes().containsKey("tut-island")) {
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a input run script.
|
||||
* @param string The strings.
|
||||
* @param objects The arguments.
|
||||
*/
|
||||
public void sendInput(boolean string, Object... objects) {
|
||||
player.getPacketDispatch().sendRunScript(string ? 109 : 108, "s", objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a long input.
|
||||
* @param objects the objects.
|
||||
*/
|
||||
public void sendLongInput(Object... objects) {
|
||||
player.getPacketDispatch().sendRunScript(110, "s", objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the private message input.
|
||||
* @param reciever The receiver.
|
||||
*/
|
||||
public void sendMessageInput(String reciever) {
|
||||
player.getPacketDispatch().sendRunScript(107, "s", reciever);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the dialogue for the given id is added.
|
||||
* @param id The NPC id/dialogue id.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean contains(int id) {
|
||||
return PLUGINS.containsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently opened dialogue.
|
||||
* @return The dialogue plugin.
|
||||
*/
|
||||
public DialoguePlugin getDialogue() {
|
||||
return dialogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserves a key for the name.
|
||||
* @param name The name.
|
||||
* @return The key.
|
||||
*/
|
||||
public static int getDialogueKey(String name) {
|
||||
return 1 << 16 | name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dialogueStage.
|
||||
* @return The dialogueStage.
|
||||
*/
|
||||
public ScriptContext getDialogueStage() {
|
||||
return dialogueStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dialogueStage.
|
||||
* @param dialogueStage The dialogueStage to set.
|
||||
*/
|
||||
public void setDialogueStage(ScriptContext dialogueStage) {
|
||||
this.dialogueStage = dialogueStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dialogue reward.
|
||||
* @param action the reward.
|
||||
*/
|
||||
public void addAction(DialogueAction action) {
|
||||
actions.clear();
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the actions.
|
||||
* @return The actions.
|
||||
*/
|
||||
public List<DialogueAction> getActions() {
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
package org.crandor.game.content.dialogue;
|
||||
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.npc.NPC;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.plugin.Plugin;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
/**
|
||||
* Represents a dialogue plugin.
|
||||
* @author Emperor
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public abstract class DialoguePlugin implements Plugin<Player> {
|
||||
|
||||
/**
|
||||
* Represents the red string.
|
||||
*/
|
||||
protected static final String RED = "<col=8A0808>";
|
||||
|
||||
/**
|
||||
* Represents the blue string.
|
||||
*/
|
||||
protected static final String BLUE = "<col=08088A>";
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
protected Player player;
|
||||
|
||||
/**
|
||||
* The dialogue interpreter.
|
||||
*/
|
||||
protected DialogueInterpreter interpreter;
|
||||
|
||||
/**
|
||||
* Two options interface.
|
||||
*/
|
||||
protected final int TWO_OPTIONS = 228;
|
||||
|
||||
/**
|
||||
* Three options interface.
|
||||
*/
|
||||
protected final int THREE_OPTIONS = 230;
|
||||
|
||||
/**
|
||||
* Four options interface.
|
||||
*/
|
||||
protected final int FOUR_OPTIONS = 232;
|
||||
|
||||
/**
|
||||
* Five options interface.
|
||||
*/
|
||||
protected final int FIVE_OPTIONS = 234;
|
||||
|
||||
/**
|
||||
* The NPC the player is talking with.
|
||||
*/
|
||||
protected NPC npc;
|
||||
|
||||
/**
|
||||
* The current dialogue stage.
|
||||
*/
|
||||
protected int stage;
|
||||
|
||||
/**
|
||||
* If the dialogue is finished.
|
||||
*/
|
||||
protected boolean finished;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialoguePlugin} {@code Object}.
|
||||
*/
|
||||
public DialoguePlugin() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
public String pirateGender() {
|
||||
return (player.isMale() ? "lad" : "lass");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialoguePlugin} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public DialoguePlugin(Player player) {
|
||||
this.player = player;
|
||||
if (player != null) {
|
||||
this.interpreter = player.getDialogueInterpreter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this plugin.
|
||||
*/
|
||||
public void init() {
|
||||
for (int id : getIds()) {
|
||||
DialogueInterpreter.add(id, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes <b>(but does not end)</b> the dialogue.
|
||||
* @return {@code True} if the dialogue succesfully closed.
|
||||
*/
|
||||
public boolean close() {
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
player.getInterfaceManager().openChatbox(137);
|
||||
finished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void sendNormalDialogue(Entity entity, FacialExpression expression, String... messages) {
|
||||
interpreter.sendDialogues(entity, expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the stage variable.
|
||||
*/
|
||||
public void increment() {
|
||||
stage++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Increments the stage variable.
|
||||
* @return The stage variable.
|
||||
*/
|
||||
public int getAndIncrement() {
|
||||
return stage++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the dialogue.
|
||||
*/
|
||||
public void end() {
|
||||
if (interpreter != null) {
|
||||
interpreter.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract DialoguePlugin newInstance(Player player);
|
||||
|
||||
/**
|
||||
* Opens the dialogue.
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if the dialogue plugin succesfully opened.
|
||||
*/
|
||||
public abstract boolean open(Object... args);
|
||||
|
||||
/**
|
||||
* Handles the progress of this dialogue..
|
||||
* @return {@code True} if the dialogue has started.
|
||||
*/
|
||||
public abstract boolean handle(int interfaceId, int buttonId);
|
||||
|
||||
/**
|
||||
* Gets the ids of the NPCs using this dialogue plugin.
|
||||
* @return The array of NPC ids.
|
||||
*/
|
||||
public abstract int[] getIds();
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(final String... messages) {
|
||||
if (npc == null) {
|
||||
return interpreter.sendDialogues(getIds()[0], getIds()[0] > 8591 ? FacialExpression.OSRS_NORMAL : FacialExpression.NORMAL, messages);
|
||||
}
|
||||
return interpreter.sendDialogues(npc, getIds()[0] > 8591 ? FacialExpression.OSRS_NORMAL : FacialExpression.NORMAL, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @param id the id.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(int id, final String... messages) {
|
||||
return interpreter.sendDialogues(id, FacialExpression.NORMAL, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(FacialExpression expression, final String... messages) {
|
||||
if (npc == null) {
|
||||
return interpreter.sendDialogues(getIds()[0], FacialExpression.NORMAL, messages);
|
||||
}
|
||||
return interpreter.sendDialogues(npc, expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send a player dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component player(final String... messages) {
|
||||
return interpreter.sendDialogues(player, null, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to send options.
|
||||
* @param options the options.
|
||||
*/
|
||||
public void options(final String... options) {
|
||||
interpreter.sendOptions("Select an Option", options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the dialogue plugin is finished.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stage.
|
||||
* @param i the stage.
|
||||
*/
|
||||
public void setStage(int i) {
|
||||
this.stage = i;
|
||||
}
|
||||
|
||||
public void next() {
|
||||
this.stage += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package org.crandor.game.content.dialogue;
|
||||
|
||||
/**
|
||||
* Represents the facial expressions (the animations the entity does when
|
||||
* talking).
|
||||
* @author Emperor
|
||||
* @author Empathy
|
||||
*/
|
||||
public enum FacialExpression {
|
||||
|
||||
/**
|
||||
* The normal talking expression.
|
||||
*/
|
||||
OSRS_HAPPY(588), OSRS_NORMAL(594), OSRS_SAD(596), OSRS_LAUGH1(605), OSRS_LAUGH2(606), OSRS_LAUGH3(607), OSRS_LAUGH4(608), //TODO: More
|
||||
NORMAL(9760), ANGRY(9792), GRUMPY(9784), ANNOYED(9812), SNEAKY(595), SAD(9776), DISTRESSED(9820), HAPPY(9851), NEARLY_CRYING(9836), CHILD_QUESTIONABLE(7171), CHILD_BACK_AND_FORTH(7172), CHILD_NORMAL(7173), CHILD_SLOW_NOD(7174), CHILD_CRAZY_LAUGH(7175), CHILD_THINKING(7176), CHILD_SAD(7177), CHILD_BIG_EYES(7178), CHILD_LOOKING_OUT(7179);
|
||||
|
||||
/**
|
||||
* The animation id.
|
||||
*/
|
||||
private final int animationId;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FacialExpression} {@code Object}.
|
||||
* @param animationId The animation id.
|
||||
*/
|
||||
private FacialExpression(int animationId) {
|
||||
this.animationId = animationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the animation id.
|
||||
* @return The animation id.
|
||||
*/
|
||||
public int getAnimationId() {
|
||||
return animationId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,489 @@
|
|||
package org.crandor.game.content.dialogue;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ChildPositionContext;
|
||||
import org.crandor.net.packet.out.RepositionChild;
|
||||
import org.crandor.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents a skill dialogue handler class.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class SkillDialogueHandler {
|
||||
|
||||
/**
|
||||
* Represents the skill dialogue id.
|
||||
*/
|
||||
public static final int SKILL_DIALOGUE = 3 << 16;
|
||||
|
||||
/**
|
||||
* Represents the player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Represents the skill dialogue type.
|
||||
*/
|
||||
private final SkillDialogue type;
|
||||
|
||||
/**
|
||||
* Represents the object data passed through.
|
||||
*/
|
||||
private final Object[] data;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SkillDialogueHandler} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param type the type.
|
||||
* @param data the data.
|
||||
*/
|
||||
public SkillDialogueHandler(final Player player, final SkillDialogue type, final Object... data) {
|
||||
this.player = player;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to open a skill dialogue.
|
||||
*/
|
||||
public void open() {
|
||||
player.getDialogueInterpreter().open(SKILL_DIALOGUE, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display the content on the dialogue.
|
||||
*/
|
||||
public void display() {
|
||||
if (type == null) {
|
||||
player.debug("Error! Type is null.");
|
||||
return;
|
||||
}
|
||||
type.display(player, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to create a product.
|
||||
* @param amount the amount.
|
||||
* @param index the index.
|
||||
*/
|
||||
public void create(final int amount, int index) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total amount of items to be made.
|
||||
* @param index the index.
|
||||
* @return the amount.
|
||||
*/
|
||||
public int getAll(int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*/
|
||||
public SkillDialogue getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the passed data.
|
||||
* @return the data.
|
||||
*/
|
||||
public Object[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @param item the item.
|
||||
* @return the name.
|
||||
*/
|
||||
protected String getName(Item item) {
|
||||
return StringUtils.formatDisplayName(item.getName().replace("Unfired", ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a skill dialogue type.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
public static enum SkillDialogue {
|
||||
ONE_OPTION(309, 5, 1) {
|
||||
|
||||
@Override
|
||||
public void display(Player player, SkillDialogueHandler handler) {
|
||||
final Item item = (Item) handler.getData()[0];
|
||||
player.getPacketDispatch().sendString("<br><br><br><br>" + item.getName(), 309, 6);
|
||||
player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 160, 309, 2);
|
||||
PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 309, 6, 60, 20));
|
||||
PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 309, 2, 210, 30));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
return buttonId == 5 ? 1 : buttonId == 4 ? 5 : buttonId == 3 ? -1 : handler.getAll(getIndex(handler, buttonId));
|
||||
}
|
||||
},
|
||||
TWO_OPTION(303, 7, 2) {
|
||||
|
||||
@Override
|
||||
public void display(Player player, SkillDialogueHandler handler) {
|
||||
Item item;
|
||||
player.getInterfaceManager().openChatbox(306);
|
||||
for (int i = 0; i < handler.getData().length; i++) {
|
||||
item = (Item) handler.getData()[i];
|
||||
player.getPacketDispatch().sendString("<br><br><br><br>" + handler.getName(item), 303, 7 + i);
|
||||
player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 160, 303, 2 + i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 6:
|
||||
case 5:
|
||||
case 4:
|
||||
case 3:
|
||||
return 0;
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
case 7:
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 6:
|
||||
case 10:
|
||||
return 1;
|
||||
case 5:
|
||||
case 9:
|
||||
return 5;
|
||||
case 4:
|
||||
case 8:
|
||||
return 10;
|
||||
case 3:
|
||||
case 7:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
THREE_OPTION(304, 8, 3) {
|
||||
@Override
|
||||
public void display(Player player, SkillDialogueHandler handler) {
|
||||
Item item = null;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
item = (Item) handler.getData()[i];
|
||||
player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 135, 304, 2 + i);
|
||||
player.getPacketDispatch().sendString("<br><br><br><br>" + item.getName(), 304, (304 - 296) + (i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 7:
|
||||
case 6:
|
||||
case 5:
|
||||
case 4:
|
||||
return 0;
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
return 1;
|
||||
case 15:
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 7:
|
||||
case 11:
|
||||
case 15:
|
||||
return 1;
|
||||
case 6:
|
||||
case 10:
|
||||
case 14:
|
||||
return 5;
|
||||
case 5:
|
||||
case 9:
|
||||
case 13:
|
||||
return 10;
|
||||
case 4:
|
||||
case 8:
|
||||
case 12:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
FOUR_OPTION(305, 9, 4) {
|
||||
@Override
|
||||
public void display(Player player, SkillDialogueHandler handler) {
|
||||
Item item = null;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
item = (Item) handler.getData()[i];
|
||||
player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 135, 305, 2 + i);
|
||||
player.getPacketDispatch().sendString("<br><br><br><br>" + item.getName(), 305, (305 - 296) + (i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 5:
|
||||
case 8:
|
||||
case 6:
|
||||
case 7:
|
||||
return 0;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
return 1;
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
return 2;
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 8:
|
||||
case 12:
|
||||
case 16:
|
||||
case 20:
|
||||
return 1;
|
||||
case 7:
|
||||
case 11:
|
||||
case 15:
|
||||
case 19:
|
||||
return 5;
|
||||
case 6:
|
||||
case 10:
|
||||
case 14:
|
||||
case 18:
|
||||
return 5;
|
||||
case 5:
|
||||
case 9:
|
||||
case 13:
|
||||
case 17:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
},
|
||||
FIVE_OPTION(306, 7, 5) {
|
||||
|
||||
/**
|
||||
* Represents the position data.
|
||||
*/
|
||||
private final int[][] positions = new int[][] { { 10, 30 }, { 117, 10 }, { 217, 20 }, { 317, 15 }, { 408, 15 } };
|
||||
|
||||
@Override
|
||||
public void display(Player player, SkillDialogueHandler handler) {
|
||||
Item item;
|
||||
player.getInterfaceManager().openChatbox(306);
|
||||
for (int i = 0; i < handler.getData().length; i++) {
|
||||
item = (Item) handler.getData()[i];
|
||||
player.getPacketDispatch().sendString("<br><br><br><br>" + handler.getName(item), 306, 10 + (4 * i));
|
||||
player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 160, 306, 2 + i);
|
||||
PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1]));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int getIndex(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 9:
|
||||
case 8:
|
||||
case 7:
|
||||
case 6:
|
||||
return 0;
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
return 1;
|
||||
case 17:
|
||||
case 16:
|
||||
case 15:
|
||||
case 14:
|
||||
return 2;
|
||||
case 21:
|
||||
case 20:
|
||||
case 19:
|
||||
case 18:
|
||||
return 3;
|
||||
case 25:
|
||||
case 24:
|
||||
case 23:
|
||||
case 22:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
switch(buttonId){
|
||||
case 9:
|
||||
case 13:
|
||||
case 17:
|
||||
case 21:
|
||||
case 25:
|
||||
return 1;
|
||||
case 8:
|
||||
case 12:
|
||||
case 16:
|
||||
case 20:
|
||||
case 24:
|
||||
return 5;
|
||||
case 7:
|
||||
case 11:
|
||||
case 15:
|
||||
case 19:
|
||||
case 23:
|
||||
return 10;
|
||||
case 6:
|
||||
case 10:
|
||||
case 14:
|
||||
case 18:
|
||||
case 22:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the interface id.
|
||||
*/
|
||||
private final int interfaceId;
|
||||
|
||||
/**
|
||||
* Represents the base button.
|
||||
*/
|
||||
private final int baseButton;
|
||||
|
||||
/**
|
||||
* Represents the length.
|
||||
*/
|
||||
private final int length;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SkillDialogue} {@code Object}.
|
||||
* @param interfaceId the interface id.
|
||||
* @param base the base button.
|
||||
* @param length the length.
|
||||
*/
|
||||
private SkillDialogue(final int interfaceId, final int baseButton, final int length) {
|
||||
this.interfaceId = interfaceId;
|
||||
this.baseButton = baseButton;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display the content for this type.
|
||||
* @param player the player.
|
||||
* @param handler the handler.
|
||||
*/
|
||||
public void display(final Player player, final SkillDialogueHandler handler) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount.
|
||||
* @param handler the handler.
|
||||
* @param buttonId the buttonId.
|
||||
* @return the amount.
|
||||
*/
|
||||
public int getAmount(SkillDialogueHandler handler, final int buttonId) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
int val = (baseButton - k) + (4 * i);
|
||||
if (val == buttonId) {
|
||||
return k == 13 ? 1 : k == 8 ? 5 : k == 7 ? 10 : 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index selected.
|
||||
* @param handler the handler.
|
||||
* @param buttonId the buttonId.
|
||||
* @return the index selected.
|
||||
*/
|
||||
public int getIndex(SkillDialogueHandler handler, final int buttonId) {
|
||||
int index = 0;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
for (int i = 1; i < length; i++) {
|
||||
int val = (baseButton + k) + (4 * i);
|
||||
if (val == buttonId) {
|
||||
return index + 1;
|
||||
} else if (val <= buttonId) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interfaceId.
|
||||
* @return The interfaceId.
|
||||
*/
|
||||
public int getInterfaceId() {
|
||||
return interfaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type for the length.
|
||||
* @param length2 the length to compare.
|
||||
* @return the type.
|
||||
*/
|
||||
public static SkillDialogue forLength(int length2) {
|
||||
for (SkillDialogue dial : values()) {
|
||||
if (dial.length == length2) {
|
||||
return dial;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
package org.crandor.game.content.dialogue.book;
|
||||
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.content.dialogue.DialoguePlugin;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.plugin.PluginManifest;
|
||||
import org.crandor.plugin.PluginType;
|
||||
|
||||
/**
|
||||
* Represents a dialogue book.
|
||||
* @author 'Vexia
|
||||
* @date 1/1/14
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public abstract class Book extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Represents the component interface of the book.
|
||||
*/
|
||||
private static final Component INTERFACE = new Component(49);
|
||||
|
||||
/**
|
||||
* Represents the red string.
|
||||
*/
|
||||
protected static final String RED = "<col=8A0808>";
|
||||
|
||||
/**
|
||||
* Represents the blue string.
|
||||
*/
|
||||
protected static final String BLUE = "<col=08088A>";
|
||||
|
||||
/**
|
||||
* Represents the name of the book.
|
||||
*/
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Represents the id of this book.
|
||||
*/
|
||||
protected int id;
|
||||
|
||||
/**
|
||||
* Represents the pages of this book.
|
||||
*/
|
||||
protected PageSet[] sets;
|
||||
|
||||
/**
|
||||
* Represents the index of the page set we're at.
|
||||
*/
|
||||
protected int index = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Book} {@code Object}.
|
||||
* @param name the name.
|
||||
* @param id the id.
|
||||
*/
|
||||
public Book(final Player player, final String name, final int id, final PageSet... sets) {
|
||||
this.player = player;
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.sets = sets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Book} {@code Object}.
|
||||
*/
|
||||
public Book() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
return open(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (buttonId) {
|
||||
case 112:
|
||||
player.getInterfaceManager().close();
|
||||
break;
|
||||
case 66:
|
||||
case 52:
|
||||
next();
|
||||
break;
|
||||
case 64:
|
||||
case 50:
|
||||
previous();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to open a book.
|
||||
* @return <code>True</code> if succesfully opened.
|
||||
*/
|
||||
public boolean open(final Player player) {
|
||||
next();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to write the next dialogue.
|
||||
*/
|
||||
public void next() {
|
||||
player.lock();
|
||||
index++;
|
||||
if (index > sets.length - 1) {
|
||||
player.unlock();
|
||||
player.getInterfaceManager().close();
|
||||
return;
|
||||
}
|
||||
final Page[] set = sets[index].getPages();
|
||||
display(set);
|
||||
player.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to write the previous dialogue.
|
||||
*/
|
||||
public void previous() {
|
||||
player.lock();
|
||||
index--;
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
final Page[] set = sets[index].getPages();
|
||||
display(set);
|
||||
player.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display a set of pages.
|
||||
* @param set the set.
|
||||
*/
|
||||
public void display(Page[] set) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used when the book is finished.
|
||||
*/
|
||||
public void finish() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index.
|
||||
* @return The index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index.
|
||||
* @param index The index to set.
|
||||
*/
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interface component.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component getInterface() {
|
||||
return INTERFACE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package org.crandor.game.content.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a book line.
|
||||
* @author 'Vexia
|
||||
* @date 31/12/2013
|
||||
*/
|
||||
public class BookLine {
|
||||
|
||||
/**
|
||||
* Represents the message to display.
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Represents the child if of the line.
|
||||
*/
|
||||
private final int child;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Page} {@code Object}.
|
||||
* @param message the message.
|
||||
* @param child the child.
|
||||
*/
|
||||
public BookLine(final String message, final int child) {
|
||||
this.message = message;
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message.
|
||||
* @return The message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child.
|
||||
* @return The child.
|
||||
*/
|
||||
public int getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package org.crandor.game.content.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a page on a book.
|
||||
* @author 'Vexia
|
||||
* @date 1/1/14
|
||||
*/
|
||||
public class Page {
|
||||
|
||||
/**
|
||||
* Represents the lines on a page.
|
||||
*/
|
||||
private final BookLine[] lines;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Page} {@code Object}.
|
||||
* @param lines the lines.
|
||||
*/
|
||||
public Page(BookLine... lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lines.
|
||||
* @return The lines.
|
||||
*/
|
||||
public BookLine[] getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package org.crandor.game.content.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a set of pages on a book.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
public class PageSet {
|
||||
|
||||
/**
|
||||
* Represents the set of pages.
|
||||
*/
|
||||
private final Page[] pages;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PageSet} {@code Object}.
|
||||
* @param pages the pages.
|
||||
*/
|
||||
public PageSet(final Page... pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pages.
|
||||
* @return The pages.
|
||||
*/
|
||||
public Page[] getPages() {
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.crandor.game.content.eco;
|
||||
|
||||
/**
|
||||
* The several statuses used for the economy.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum EcoStatus {
|
||||
|
||||
/**
|
||||
* The status set when money should be drained from the economy.
|
||||
*/
|
||||
DRAINING,
|
||||
|
||||
/**
|
||||
* The status set when money should be pumped into the economy.
|
||||
*/
|
||||
BOOSTING,
|
||||
|
||||
/**
|
||||
* If we are maintaining the current economy.
|
||||
*/
|
||||
MAINTAINING;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package org.crandor.game.content.eco;
|
||||
|
||||
/**
|
||||
* Represents a managing class for the economy.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class EconomyManagement {
|
||||
|
||||
/**
|
||||
* The current economy state.
|
||||
*/
|
||||
private static EcoStatus ecoState = EcoStatus.BOOSTING;
|
||||
|
||||
/**
|
||||
* The modification rate.
|
||||
*/
|
||||
private static double modificationRate = 10;
|
||||
|
||||
/**
|
||||
* Sets the ecoState.
|
||||
* @param ecoState The ecoState to set.
|
||||
*/
|
||||
public static void update(EcoStatus ecoState, double modificationRate) {
|
||||
boolean update = EconomyManagement.ecoState != ecoState;
|
||||
EconomyManagement.ecoState = ecoState;
|
||||
if (EconomyManagement.modificationRate != modificationRate) {
|
||||
EconomyManagement.modificationRate = modificationRate;
|
||||
update = true;
|
||||
}
|
||||
if (update) {
|
||||
System.out.println("-------------------------------------------------------------------");
|
||||
System.out.println(" Switched economy management status to " + ecoState + " with a rate of " + modificationRate + " |");
|
||||
System.out.println("-------------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ecoState.
|
||||
* @param ecoState The ecoState to set.
|
||||
*/
|
||||
public static void updateEcoState(EcoStatus ecoState) {
|
||||
update(ecoState, modificationRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the modificationRate.
|
||||
* @param modificationRate The modificationRate to set.
|
||||
*/
|
||||
public static void updateModificationRate(double modificationRate) {
|
||||
update(ecoState, modificationRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ecoState.
|
||||
* @return The ecoState.
|
||||
*/
|
||||
public static EcoStatus getEcoState() {
|
||||
return ecoState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modificationRate.
|
||||
* @return The modificationRate.
|
||||
*/
|
||||
public static double getModificationRate() {
|
||||
return modificationRate;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.system.mysql.impl.ItemConfigSQLHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles the buying limitations.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class BuyingLimitation {
|
||||
|
||||
/**
|
||||
* Mapping holding buying amounts per player for every item id.
|
||||
*/
|
||||
private static final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BuyingLimitation} {@code Object}.
|
||||
*/
|
||||
private BuyingLimitation() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum amount the player can buy of this item.
|
||||
* @param itemId The item id.
|
||||
* @param playerUID The player UID.
|
||||
* @return The maximum amount to buy.
|
||||
*/
|
||||
public static int getMaximumBuy(int itemId, int playerUID) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
Integer current = 0;
|
||||
if (data != null) {
|
||||
current = data.get(playerUID);
|
||||
}
|
||||
if (current == null) {
|
||||
current = 0;
|
||||
}
|
||||
return ItemDefinition.forId(itemId).getConfiguration(ItemConfigSQLHandler.GE_LIMIT, 25000) - current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the currently bought amount.
|
||||
* @param itemId The item id.
|
||||
* @param playerUID The player UID.
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public static void updateBoughtAmount(int itemId, int playerUID, int amount) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
if (data == null) {
|
||||
CACHE.put(itemId, data = new HashMap<>());
|
||||
}
|
||||
Integer current = data.get(playerUID);
|
||||
if (current == null) {
|
||||
current = 0;
|
||||
}
|
||||
current += amount;
|
||||
data.put(playerUID, current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the offer is limited.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isLimited(int itemId, int playerUID) {
|
||||
Map<Integer, Integer> data = CACHE.get(itemId);
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
Integer current = data.get(playerUID);
|
||||
if (current == null) {
|
||||
return false;
|
||||
}
|
||||
int max = ItemDefinition.forId(itemId).getConfiguration(ItemConfigSQLHandler.GE_LIMIT, 25000);
|
||||
return current >= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached data.
|
||||
*/
|
||||
public static void clear() {
|
||||
CACHE.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents the glass used to open the guide prices for the different type of
|
||||
* trade(herbs, logs, runes, etc...)
|
||||
* @author 'Vexia
|
||||
* @date 30/11/2013
|
||||
*/
|
||||
public final class GEGuidePrice {
|
||||
|
||||
/**
|
||||
* Represents the guide price component.
|
||||
*/
|
||||
private static final Component COMPONENT = new Component(642);
|
||||
|
||||
/**
|
||||
* Method used to open a Grand Exchange guide price type.
|
||||
* @param player the player.
|
||||
* @param type the type.
|
||||
*/
|
||||
public static final void open(final Player player, final GuideType type) {
|
||||
player.getInterfaceManager().open(COMPONENT);
|
||||
type.display(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to clear the current items being showed.
|
||||
* @param player the player.
|
||||
*/
|
||||
public static final void clear(final Player player) {
|
||||
for (int i = 135; i < 165; i++) {
|
||||
player.getPacketDispatch().sendInterfaceConfig(COMPONENT.getId(), i, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a guide item shown on the Guide Price interface.
|
||||
* @author 'Vexia
|
||||
* @date 01/12/2013
|
||||
*/
|
||||
public static class GuideItem {
|
||||
|
||||
/**
|
||||
* Represents the item of this type.
|
||||
*/
|
||||
private final int item;
|
||||
|
||||
/**
|
||||
* Represents the unlock child.
|
||||
*/
|
||||
private final int[] childData;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GEGuidePrice} {@code Object}.
|
||||
* @param item the item.
|
||||
* @param childData the child data.
|
||||
*/
|
||||
public GuideItem(final int item, final int... childData) {
|
||||
this.item = item;
|
||||
this.childData = childData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public int getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the childData.
|
||||
* @return The childData.
|
||||
*/
|
||||
public int[] getChildData() {
|
||||
return childData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a guide price type of trade(herbs, logs, etc...)
|
||||
* @author 'Vexia
|
||||
* @date 30/11/2013
|
||||
*/
|
||||
public enum GuideType {
|
||||
LOGS(new int[] { 0, 0 }, new GuideItem(1511, 155), new GuideItem(2862, 156), new GuideItem(1521, 157), new GuideItem(1519, 158), new GuideItem(6333, 159), new GuideItem(1517, 160), new GuideItem(6332, 161), new GuideItem(12581, 162), new GuideItem(1515, 163), new GuideItem(1513, 164)), ORES(new int[] { 40, 44 }, new GuideItem(436, 33), new GuideItem(438, 34), new GuideItem(440, 35), new GuideItem(442, 36), new GuideItem(453, 37), new GuideItem(444, 38), new GuideItem(447, 39), new GuideItem(449, 40), new GuideItem(451, 41)), RUNES(new int[] { 215, 216 }, new GuideItem(1436, 183), new GuideItem(7936, 184), new GuideItem(556, 185), new GuideItem(558, 186), new GuideItem(555, 187), new GuideItem(557, 188), new GuideItem(554, 189), new GuideItem(559, 190), new GuideItem(564, 191), new GuideItem(562, 192), new GuideItem(9075, 193), new GuideItem(561, 194), new GuideItem(563, 195), new GuideItem(560, 196), new GuideItem(565, 197), new GuideItem(566, 198)), HERBS(new int[] { 130, 135 }, new GuideItem(249, 119), new GuideItem(251, 120), new GuideItem(253, 121), new GuideItem(255, 122), new GuideItem(257, 123), new GuideItem(2998, 124), new GuideItem(259, 125), new GuideItem(12172, 126), new GuideItem(261, 127), new GuideItem(263, 128), new GuideItem(3000, 129), new GuideItem(265, 130), new GuideItem(2481, 131), new GuideItem(267, 132), new GuideItem(269, 133)), WEAPONS_AND_ARMOUR(new int[] { 88, 89 }, new GuideItem(11834, 73), new GuideItem(11838, 74), new GuideItem(11842, 75), new GuideItem(11864, 76), new GuideItem(11870, 77), new GuideItem(11846, 78), new GuideItem(11848, 79), new GuideItem(11850, 80), new GuideItem(11856, 81), new GuideItem(11732, 82), new GuideItem(4151, 83), new GuideItem(11235, 84), new GuideItem(6739, 85), new GuideItem(4587, 86), new GuideItem(4153, 87));
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GEGuidePrice} {@code Object}.
|
||||
* @param childData the childData.
|
||||
* @param items the guide items.
|
||||
*/
|
||||
GuideType(final int[] childData, final GuideItem... items) {
|
||||
this.childData = childData;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the guide items.
|
||||
*/
|
||||
private final GuideItem[] items;
|
||||
|
||||
/**
|
||||
* Represents the child data for the guide type.
|
||||
*/
|
||||
private final int childData[];
|
||||
|
||||
/**
|
||||
* Gets the items.
|
||||
* @return The items.
|
||||
*/
|
||||
public GuideItem[] getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the childData.
|
||||
* @return The childData.
|
||||
*/
|
||||
public int[] getChildData() {
|
||||
return childData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display the guide type.
|
||||
* @param player the player.
|
||||
*/
|
||||
public void display(final Player player) {
|
||||
player.setAttribute("guide-price", this);
|
||||
if (this != LOGS) {
|
||||
clear(player);
|
||||
}
|
||||
player.getPacketDispatch().sendString("Guide Prices: " + StringUtils.formatDisplayName(name()), COMPONENT.getId(), 14);
|
||||
for (int i = getChildData()[0]; i < getChildData()[1]; i++) {
|
||||
player.getPacketDispatch().sendInterfaceConfig(642, i, false);
|
||||
}
|
||||
for (GuideItem item : getItems()) {
|
||||
player.getPacketDispatch().sendString("" + GrandExchangeDatabase.getDatabase().get(item.getItem()).getValue() + " gp", COMPONENT.getId(), item.getChildData()[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Holds the Grand Exchange item sets.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum GEItemSet {
|
||||
|
||||
BRONZE_L(11814, 1155, 1117, 1075, 1189), BRONZE_SK(11816, 1155, 1117, 1087, 1189), IRON_L(11818, 1153, 1115, 1067, 1191), IRON_SK(11820, 1153, 1115, 1081, 1191), STEEL_L(11822, 1157, 1119, 1069, 1193), STEEL_SK(11824, 1157, 1119, 1083, 1193), BLACK_L(11826, 1165, 1125, 1077, 1195), BLACK_SK(11828, 1165, 1125, 1089, 1195), MITHRIL_L(11830, 1159, 1121, 1071, 1197), MITHRIL_SK(11832, 1159, 1121, 1085, 1197), ADAMANT_L(11834, 1161, 1123, 1073, 1199), ADAMANT_SK(11836, 1161, 1123, 1091, 1199), RUNE_L(11838, 1163, 1127, 1079, 1201), RUNE_SK(11840, 1163, 1127, 1093, 1201), DRAGON_L(11842, 1149, 3140, 4087), DRAGON_SK(11844, 1149, 3140, 4585),
|
||||
// NULL_1(-1), //This would create the spaces between the sets (uncomment
|
||||
// when needed)
|
||||
AHRIMS(11846, 4708, 4712, 4714, 4710), DHAROKS(11848, 4716, 4720, 4722, 4718), GUTHANS(11850, 4724, 4728, 4730, 4726), KARILS(11852, 4732, 4736, 4738, 4734), TORAGS(11854, 4745, 4749, 4751, 4747), VERACS(11856, 4753, 4757, 4759, 4755), THIRD_AGE_MELEE(11858, 10350, 10348, 10346, 10352), THIRD_AGE_RANGE(11860, 10334, 10330, 10332, 10336), THIRD_AGE_MAGE(11862, 10342, 10338, 10340, 10344), GREEN_DHIDE(11864, 1135, 1099, 1065), BLUE_DHIDE(11866, 2499, 2493, 2487), RED_DHIDE(11868, 2501, 2495, 2489), BLACK_DHIDE(11870, 2503, 2497, 2491), MYSTIC(11872, 4089, 4091, 4093, 4095, 4097), LIGHT_MYSTIC(11960, 4109, 4111, 4113, 4115, 4117), DARK_MYSTIC(11962, 4099, 4101, 4103, 4105, 4107), INFINITY(11874, 6918, 6916, 6924, 6922, 6920), SPLITBARK(11876, 3385, 3387, 3389, 3391, 3393), BLACK_TRIMMED_L(11878, 2587, 2583, 2585, 2589), BLACK_TRIMMED_SK(11880, 2587, 2583, 3472, 2589), BLACK_GOLD_TRIMMED_L(11882, 2595, 2591, 2593, 2597), BLACK_GOLD_TRIMMED_SK(11884, 2595, 2591, 3473, 2597), ADAMANT_TRIMMED_L(11886, 2605, 2599, 2601, 2603), ADAMANT_TRIMMED_SK(11888, 2605, 2599, 3474), ADAMANT_GOLD_TRIMMED_L(11890, 2613, 2607, 2609, 2611), ADAMANT_GOLD_TRIMMED_SK(11892, 2613, 3475, 2611), RUNE_TRIMMED_L(11894, 2627, 2623, 2625, 2629), RUNE_TRIMMED_SK(11896, 2627, 2623, 3477, 2629), RUNE_GOLD_TRIMMED_L(11898, 2619, 2615, 2617, 2621), RUNE_GOLD_TRIMMED_SK(11900, 2619, 2615, 3476, 2621), ENCHANTED(11902, 7400, 7399, 7398), TRIMMED_BLUE_WIZARD(11904, 7396, 7392, 7388), GOLD_TRIMMED_BLUE_WIZARD(11906, 7394, 7390, 7386), TRIMMED_LEATHER(11908, 7364, 7368), GOLD_TRIMMED_LEATHER(11910, 7362, 7366), GREEN_DHIDE_T(11912, 7372, 7380), GREEN_DHIDE_G(11914, 7370, 7378), BLUE_DHIDE_T(11916, 7376, 7384), BLUE_DHIDE_G(11918, 7374, 7382), GREEN_DHIDE_BLESSED(11920, 10382, 10378, 10380, 10376), BLUE_DHIDE_BLESSED(11922, 10390, 10386, 10388, 10384), RED_DHIDE_BLESSED(11924, 10374, 10370, 10372, 10368), GUTHIX_L(11926, 2673, 2669, 2671, 2675), SARADOMIN_L(11928, 2665, 2661, 2663, 2667), ZAMORAK_L(11930, 2657, 2653, 2655, 2659), GUTHIX_SK(11932, 2673, 2669, 3480, 2675), SARADOMIN_SK(11934, 2665, 2661, 3479, 2667), ZAMORAK_SK(11936, 2657, 2653, 3478, 2659), GILDED_L(11938, 3486, 3481, 3483, 3488), GILDED_SK(11940, 3486, 3481, 3485, 3488), ROCKSHELL(11942, 6128, 6129, 6130, 6151, 6145), SPINED(11944, 6131, 6133, 6135, 6149, 6143), SKELETAL(11946, 6137, 6139, 6141, 6153, 6147), CANNON(11967, 6, 8, 10, 12);
|
||||
|
||||
/**
|
||||
* The item sets mapping.
|
||||
*/
|
||||
private static final Map<Integer, GEItemSet> ITEM_SETS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The items array.
|
||||
*/
|
||||
private static Item[] itemArray;
|
||||
|
||||
/**
|
||||
* Populate the mapping.
|
||||
*/
|
||||
static {
|
||||
itemArray = new Item[values().length];
|
||||
for (int i = 0; i < itemArray.length; i++) {
|
||||
GEItemSet set = values()[i];
|
||||
itemArray[i] = set.itemId == -1 ? new Item() : new Item(set.itemId);
|
||||
ITEM_SETS.put(set.itemId, set);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item set for the given id.
|
||||
* @param setId The set item id.
|
||||
* @return The item set object.
|
||||
*/
|
||||
public static GEItemSet forId(int setId) {
|
||||
return ITEM_SETS.get(setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private int itemId;
|
||||
|
||||
/**
|
||||
* The components.
|
||||
*/
|
||||
private int[] components;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GEItemSet} {@code Object}.
|
||||
* @param itemId The item id.
|
||||
* @param components The components.
|
||||
*/
|
||||
private GEItemSet(int itemId, int... components) {
|
||||
this.itemId = itemId;
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the itemId.
|
||||
* @return The itemId.
|
||||
*/
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the itemId.
|
||||
* @param itemId The itemId to set.
|
||||
*/
|
||||
public void setItemId(int itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the components.
|
||||
* @return The components.
|
||||
*/
|
||||
public int[] getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the components.
|
||||
* @param components The components to set.
|
||||
*/
|
||||
public void setComponents(int[] components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item array.
|
||||
* @return The item array.
|
||||
*/
|
||||
public static Item[] getItemArray() {
|
||||
return itemArray;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.game.content.eco.EcoStatus;
|
||||
import org.crandor.game.content.eco.EconomyManagement;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.system.task.TaskExecutor;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.callback.CallBack;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles the Grand Exchange offers.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GEOfferDispatch extends Pulse implements CallBack {
|
||||
|
||||
/**
|
||||
* The update notification.
|
||||
*/
|
||||
public static final String UPDATE_NOTIFICATION = "One or more of your grand exchange offers have been updated.";
|
||||
|
||||
/**
|
||||
* The database path.
|
||||
*/
|
||||
private static final String DB_PATH = "eco/offer_dispatch_db.emp";
|
||||
|
||||
/**
|
||||
* The offset of the offer UIDs.
|
||||
*/
|
||||
private static long offsetUID = 1;
|
||||
|
||||
/**
|
||||
* The mapping of all current offers.
|
||||
*/
|
||||
private static final Map<Long, GrandExchangeOffer> OFFER_MAPPING = new HashMap<>();
|
||||
|
||||
/**
|
||||
* If the database should be dumped.
|
||||
*/
|
||||
private static boolean dumpDatabase;
|
||||
|
||||
/**
|
||||
* Initializes the Grand Exchange.
|
||||
*/
|
||||
public static void init() {
|
||||
File file = new File("data/" + DB_PATH);
|
||||
if (!file.exists()) {
|
||||
System.err.println("[GEOfferDispatch]: Could not locate database! [path=" + file.getAbsolutePath() + "]");
|
||||
return;
|
||||
}
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel c = raf.getChannel()) {
|
||||
ByteBuffer b = c.map(MapMode.READ_WRITE, 0, c.size());
|
||||
offsetUID = b.getLong();
|
||||
long uid;
|
||||
while ((uid = b.getLong()) != 0) {
|
||||
int itemId = b.getShort();
|
||||
boolean sale = b.get() == 1;
|
||||
GrandExchangeOffer offer = new GrandExchangeOffer(itemId, sale);
|
||||
offer.setUid(uid);
|
||||
offer.setAmount(b.getInt());
|
||||
offer.setCompletedAmount(b.getInt());
|
||||
offer.setOfferedValue(b.getInt());
|
||||
offer.setTimeStamp(b.getLong());
|
||||
offer.setState(OfferState.values()[b.get()]);
|
||||
offer.setTotalCoinExchange(b.getInt());
|
||||
offer.setPlayerUID(b.getInt());
|
||||
int idx = -1;
|
||||
while ((idx = b.get()) != -1) {
|
||||
offer.getWithdraw()[idx] = new Item(b.getShort(), b.getInt());
|
||||
}
|
||||
OFFER_MAPPING.put(uid, offer);
|
||||
}
|
||||
raf.close();
|
||||
c.close();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
ResourceManager.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the grand exchange offers.
|
||||
* @param directory The directory to save to.
|
||||
*/
|
||||
public static void dump(String directory) {
|
||||
File file = new File(directory + DB_PATH);
|
||||
ByteBuffer b = ByteBuffer.allocate(50_000_000);
|
||||
b.putLong(offsetUID);
|
||||
for (long uid : OFFER_MAPPING.keySet()) {
|
||||
GrandExchangeOffer offer = OFFER_MAPPING.get(uid);
|
||||
if (offer == null) {
|
||||
continue;
|
||||
}
|
||||
b.putLong(uid);
|
||||
b.putShort((short) offer.getItemId());
|
||||
b.put((byte) (offer.isSell() ? 1 : 0));
|
||||
b.putInt(offer.getAmount());
|
||||
b.putInt(offer.getCompletedAmount());
|
||||
b.putInt(offer.getOfferedValue());
|
||||
b.putLong(offer.getTimeStamp());
|
||||
b.put((byte) offer.getState().ordinal());
|
||||
b.putInt(offer.getTotalCoinExchange());
|
||||
b.putInt(offer.getPlayerUID());
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Item item;
|
||||
if ((item = offer.getWithdraw()[i]) != null) {
|
||||
b.put((byte) i);
|
||||
b.putShort((short) item.getId());
|
||||
b.putInt(item.getAmount());
|
||||
}
|
||||
}
|
||||
b.put((byte) -1);
|
||||
}
|
||||
b.putLong(0);
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel c = raf.getChannel()) {
|
||||
b.flip();
|
||||
c.write(b);
|
||||
raf.close();
|
||||
c.close();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
ResourceManager.dump(directory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean call() {
|
||||
init();
|
||||
setDelay(1);
|
||||
GameWorld.submit(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if ((GameWorld.getTicks() % 24000) == 0) {
|
||||
for (GrandExchangeOffer offer : OFFER_MAPPING.values()) {
|
||||
if (offer.isActive() && offer.isLimitation()) {
|
||||
updateOffer(offer);
|
||||
}
|
||||
}
|
||||
BuyingLimitation.clear();
|
||||
}
|
||||
if (dumpDatabase) {
|
||||
TaskExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (GEOfferDispatch.this) {
|
||||
dump("data/");
|
||||
}
|
||||
}
|
||||
});
|
||||
dumpDatabase = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an offer.
|
||||
* @param player The player.
|
||||
* @param offer The grand exchange offer.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public static boolean dispatch(Player player, GrandExchangeOffer offer) {
|
||||
if (offer.getAmount() < 1) {
|
||||
player.getPacketDispatch().sendMessage("You must choose the quantity you wish to buy!");
|
||||
return false;
|
||||
}
|
||||
if (offer.getOfferedValue() < 1) {
|
||||
player.getPacketDispatch().sendMessage("You must choose the price you wish to buy for!");
|
||||
return false;
|
||||
}
|
||||
if (offer.getState() != OfferState.PENDING || offer.getUid() != 0) {
|
||||
return false;
|
||||
}
|
||||
offer.setPlayerUID(player.getDetails().getUid());
|
||||
offer.setUid(nextUID());
|
||||
offer.setState(OfferState.REGISTERED);
|
||||
OFFER_MAPPING.put(offer.getUid(), offer);
|
||||
offer.setTimeStamp(System.currentTimeMillis());
|
||||
player.getGrandExchange().update(offer);
|
||||
dumpDatabase = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the offer.
|
||||
* @param offer The G.E. offer to update.
|
||||
*/
|
||||
public static void updateOffer(GrandExchangeOffer offer) {
|
||||
if (!offer.isActive()) {
|
||||
return;
|
||||
}
|
||||
for (GrandExchangeOffer o : OFFER_MAPPING.values()) {
|
||||
if (o.isSell() != offer.isSell() && o.getItemId() == offer.getItemId() && o.isActive()) {
|
||||
exchange(offer, o);
|
||||
if (offer.getState() == OfferState.COMPLETED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (offer.getState() != OfferState.COMPLETED) {
|
||||
for (GrandExchangeOffer o : ResourceManager.getStock()) {
|
||||
if (o.isSell() != offer.isSell() && o.getItemId() == offer.getItemId() && o.isActive()) {
|
||||
exchange(offer, o);
|
||||
if (offer.getState() == OfferState.COMPLETED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchanges between 2 offers.
|
||||
* @param offer The grand exchange offer to update.
|
||||
* @param o The other offer to exchange with.
|
||||
*/
|
||||
private static void exchange(GrandExchangeOffer offer, GrandExchangeOffer o) {
|
||||
if (o.isSell() == offer.isSell()) {
|
||||
return;
|
||||
}
|
||||
if ((offer.isSell() && o.getOfferedValue() < offer.getOfferedValue()) || (!offer.isSell() && o.getOfferedValue() > offer.getOfferedValue())) {
|
||||
return;
|
||||
}
|
||||
int amount = offer.getAmountLeft(true);
|
||||
if (amount > o.getAmountLeft(true)) {
|
||||
amount = o.getAmountLeft(true);
|
||||
}
|
||||
if (amount < 1) {
|
||||
return;
|
||||
}
|
||||
int coinDifference = offer.isSell() ? (o.getOfferedValue() - offer.getOfferedValue()) : (offer.getOfferedValue() - o.getOfferedValue());
|
||||
if (coinDifference < 0) {
|
||||
return;
|
||||
}
|
||||
if (EconomyManagement.getEcoState() == EcoStatus.DRAINING) {
|
||||
coinDifference *= (1.0 - EconomyManagement.getModificationRate());
|
||||
}
|
||||
offer.setCompletedAmount(offer.getCompletedAmount() + amount);
|
||||
o.setCompletedAmount(o.getCompletedAmount() + amount);
|
||||
offer.setState(offer.getAmountLeft() < 1 ? OfferState.COMPLETED : OfferState.UPDATED);
|
||||
o.setState(o.getAmountLeft() < 1 ? OfferState.COMPLETED : OfferState.UPDATED);
|
||||
if (offer.isSell()) {
|
||||
if (offer.getAmountLeft() < 1 && offer.getPlayer() != null) {
|
||||
offer.getPlayer().getAudioManager().send(new Audio(4042, 1, 1));
|
||||
}
|
||||
offer.addWithdraw(995, amount * offer.getOfferedValue());
|
||||
o.addWithdraw(o.getItemId(), amount);
|
||||
BuyingLimitation.updateBoughtAmount(o.getItemId(), o.getPlayerUID(), amount);
|
||||
} else {
|
||||
if (o.getAmountLeft() < 1 && o.getPlayer() != null) {
|
||||
o.getPlayer().getAudioManager().send(new Audio(4042, 1, 1));
|
||||
}
|
||||
offer.addWithdraw(offer.getItemId(), amount);
|
||||
o.addWithdraw(995, amount * o.getOfferedValue());
|
||||
BuyingLimitation.updateBoughtAmount(offer.getItemId(), offer.getPlayerUID(), amount);
|
||||
}
|
||||
if (coinDifference > 0) {
|
||||
addCoinDifference(offer, o, coinDifference, amount);
|
||||
}
|
||||
offer.getEntry().influenceValue(offer.getOfferedValue());
|
||||
offer.notify(UPDATE_NOTIFICATION);
|
||||
o.notify(UPDATE_NOTIFICATION);
|
||||
dumpDatabase = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the coin difference between 2 offers.
|
||||
* @param offer The offer.
|
||||
* @param o The other offer.
|
||||
* @param coinDifference The difference in prices.
|
||||
*/
|
||||
private static void addCoinDifference(GrandExchangeOffer offer, GrandExchangeOffer o, int coinDifference, int amount) {
|
||||
if (!offer.isSell()) {
|
||||
offer.addWithdraw(995, coinDifference * amount);
|
||||
} else {
|
||||
o.addWithdraw(995, coinDifference * amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offer for the given UID.
|
||||
* @param uid The unique ID given to the offer.
|
||||
* @return The grand exchange offer.
|
||||
*/
|
||||
public static GrandExchangeOffer forUID(long uid) {
|
||||
return OFFER_MAPPING.get(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the offer for the given UID.
|
||||
* @param uid The UID.
|
||||
* @return {@code True} if successfully removed.
|
||||
*/
|
||||
public static boolean remove(long uid) {
|
||||
return OFFER_MAPPING.remove(uid) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next UID.
|
||||
* @return The UID.
|
||||
*/
|
||||
private static long nextUID() {
|
||||
long id = offsetUID++;
|
||||
if (id == 0) {
|
||||
return nextUID();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offerMapping.
|
||||
* @return the offerMapping
|
||||
*/
|
||||
public static Map<Long, GrandExchangeOffer> getOfferMapping() {
|
||||
return OFFER_MAPPING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dumping flag.
|
||||
* @param dump The dump to set.
|
||||
*/
|
||||
public static void setDumpDatabase(boolean dump) {
|
||||
GEOfferDispatch.dumpDatabase = dump;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,647 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.component.CloseEvent;
|
||||
import org.crandor.game.component.Component;
|
||||
import org.crandor.game.component.InterfaceType;
|
||||
import org.crandor.game.container.Container;
|
||||
import org.crandor.game.container.ContainerEvent;
|
||||
import org.crandor.game.container.ContainerListener;
|
||||
import org.crandor.game.container.access.BitregisterAssembler;
|
||||
import org.crandor.game.container.access.InterfaceContainer;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.login.SavingModule;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.monitor.PlayerMonitor;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.GrandExchangeContext;
|
||||
import org.crandor.net.packet.out.GrandExchangePacket;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Handles a player's Grand Exchange.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GrandExchange implements SavingModule {
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* The grand exchange offers.
|
||||
*/
|
||||
private final GrandExchangeOffer[] offers = new GrandExchangeOffer[6];
|
||||
|
||||
/**
|
||||
* The offer the player is currently constructing.
|
||||
*/
|
||||
private GrandExchangeOffer temporaryOffer;
|
||||
|
||||
/**
|
||||
* The grand exchange offer history.
|
||||
*/
|
||||
private GrandExchangeOffer[] history = new GrandExchangeOffer[5];
|
||||
|
||||
/**
|
||||
* The currently opened index.
|
||||
*/
|
||||
private int openedIndex = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GrandExchange} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public GrandExchange(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the Grand Exchange menu.
|
||||
*/
|
||||
public void open() {
|
||||
if (player.getIronmanManager().checkRestriction()) {
|
||||
return;
|
||||
}
|
||||
if (!player.getBankPinManager().isUnlocked()) {
|
||||
player.getBankPinManager().openType(4);
|
||||
return;
|
||||
}
|
||||
player.getInterfaceManager().open(new Component(105)).setCloseEvent(new CloseEvent() {
|
||||
@Override
|
||||
public boolean close(Player player, Component c) {
|
||||
temporaryOffer = null;
|
||||
player.getPacketDispatch().sendRunScript(571, "");
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
player.getInterfaceManager().closeSingleTab();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
player.getPacketDispatch().sendInterfaceConfig(105, 193, true);
|
||||
player.getPacketDispatch().sendAccessMask(6, 211, 105, -1, -1);
|
||||
player.getPacketDispatch().sendAccessMask(6, 209, 105, -1, -1);
|
||||
toMainInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the collection box.
|
||||
*/
|
||||
public void openCollectionBox() {
|
||||
if (!player.getBankPinManager().isUnlocked()) {
|
||||
player.getBankPinManager().openType(3);
|
||||
return;
|
||||
}
|
||||
player.getInterfaceManager().openComponent(109);
|
||||
player.getPacketDispatch().sendAccessMask(6, 18, 109, 0, 2);
|
||||
player.getPacketDispatch().sendAccessMask(6, 23, 109, 0, 2);
|
||||
player.getPacketDispatch().sendAccessMask(6, 28, 109, 0, 2);
|
||||
player.getPacketDispatch().sendAccessMask(6, 36, 109, 0, 2);
|
||||
player.getPacketDispatch().sendAccessMask(6, 44, 109, 0, 2);
|
||||
player.getPacketDispatch().sendAccessMask(6, 52, 109, 0, 2);
|
||||
for (GrandExchangeOffer offer : player.getGrandExchange().getOffers()) {
|
||||
if (offer != null) {
|
||||
offer.sendItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the history log.
|
||||
* @param p The player to open it for.
|
||||
*/
|
||||
public void openHistoryLog(Player p) {
|
||||
p.getInterfaceManager().open(new Component(643));
|
||||
for (int i = 0; i < history.length; i++) {
|
||||
GrandExchangeOffer o = history[i];
|
||||
if (o == null) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
p.getPacketDispatch().sendString("-", 643, 25 + i + (j * 5));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
p.getPacketDispatch().sendString(o.isSell() ? "You sold" : "You bought", 643, 25 + i);
|
||||
p.getPacketDispatch().sendString(NumberFormat.getNumberInstance(Locale.US).format(o.getCompletedAmount()), 643, 30 + i);
|
||||
p.getPacketDispatch().sendString(ItemDefinition.forId(o.getItemId()).getName(), 643, 35 + i);
|
||||
p.getPacketDispatch().sendString(NumberFormat.getNumberInstance(Locale.US).format(o.getTotalCoinExchange()) + " gp", 643, 40 + i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the item sets interface.
|
||||
*/
|
||||
public void openItemSets() {
|
||||
player.getInventory().getListeners().add(new ContainerListener() {
|
||||
|
||||
@Override
|
||||
public void update(Container c, ContainerEvent event) {
|
||||
player.setAttribute("container-key", InterfaceContainer.generateItems(player, player.getInventory().toArray(), new String[] { "Examine", "Exchange", "Components" }, 644, 0, 7, 4));
|
||||
InterfaceContainer.generateItems(player, GEItemSet.getItemArray(), new String[] { "Examine", "Exchange", "Components" }, 645, 16, 15, 10);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Container c) {
|
||||
player.setAttribute("container-key", InterfaceContainer.generateItems(player, player.getInventory().toArray(), new String[] { "Examine", "Exchange", "Components" }, 644, 0, 7, 4));
|
||||
InterfaceContainer.generateItems(player, GEItemSet.getItemArray(), new String[] { "Examine", "Exchange", "Components" }, 645, 16, 15, 10);
|
||||
}
|
||||
|
||||
});
|
||||
player.getInterfaceManager().open(new Component(645)).setCloseEvent(new CloseEvent() {
|
||||
@Override
|
||||
public boolean close(Player player, Component c) {
|
||||
player.getInventory().getListeners().remove(1);
|
||||
player.getInterfaceManager().closeSingleTab();
|
||||
player.removeAttribute("container-key");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
player.getInterfaceManager().openSingleTab(new Component(644)).open(player);
|
||||
player.setAttribute("container-key", InterfaceContainer.generateItems(player, player.getInventory().toArray(), new String[] { "Examine", "Exchange", "Components" }, 644, 0, 7, 4));
|
||||
InterfaceContainer.generateItems(player, GEItemSet.getItemArray(), new String[] { "Examine", "Exchange", "Components" }, 645, 16, 15, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns to the main interface.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void toMainInterface() {
|
||||
player.getConfigManager().send(1112, -1);
|
||||
player.getConfigManager().send(1113, -1);
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
player.getInterfaceManager().closeSingleTab();
|
||||
openedIndex = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ByteBuffer buffer) {
|
||||
for (GrandExchangeOffer offer : offers) {
|
||||
if (offer != null) {
|
||||
buffer.put((byte) offer.getIndex());
|
||||
buffer.putLong(offer.getUid());
|
||||
}
|
||||
}
|
||||
buffer.put((byte) -1);
|
||||
for (GrandExchangeOffer o : history) {
|
||||
if (o == null) {
|
||||
buffer.put((byte) -1);
|
||||
continue;
|
||||
}
|
||||
buffer.put((byte) (o.isSell() ? 1 : 0));
|
||||
buffer.putShort((short) o.getItemId());
|
||||
buffer.putInt(o.getTotalCoinExchange());
|
||||
buffer.putInt(o.getCompletedAmount());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(ByteBuffer buffer) {
|
||||
int index = -1;
|
||||
GrandExchangeOffer o;
|
||||
while ((index = buffer.get()) != -1) {
|
||||
long key = buffer.getLong();
|
||||
o = offers[index] = GEOfferDispatch.forUID(key);
|
||||
if (o != null) {
|
||||
o.setIndex(index);
|
||||
} else {
|
||||
System.out.println("Could not locate G.E offer for key " +
|
||||
key + "!");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < history.length; i++) {
|
||||
int s = buffer.get();
|
||||
if (s == -1) {
|
||||
continue;
|
||||
}
|
||||
o = history[i] = new GrandExchangeOffer(buffer.getShort(), s == 1);
|
||||
o.setTotalCoinExchange(buffer.getInt());
|
||||
o.setCompletedAmount(buffer.getInt());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the grand exchange.
|
||||
*/
|
||||
public void init() {
|
||||
boolean updated = false;
|
||||
for (GrandExchangeOffer offer : offers) {
|
||||
if (offer != null) {
|
||||
offer.setPlayer(player);
|
||||
if (!updated && (offer.getWithdraw()[0] != null || offer.getWithdraw()[1] != null)) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
if (updated) {
|
||||
player.getPacketDispatch().sendMessage("You have items from the Grand Exchange waiting in your collection box.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the grand exchange data.
|
||||
*/
|
||||
public void update() {
|
||||
for (GrandExchangeOffer offer : offers) {
|
||||
update(offer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a grand exchange offer.
|
||||
* @param offer The offer to update.
|
||||
*/
|
||||
public void update(GrandExchangeOffer offer) {
|
||||
if (offer != null) {
|
||||
PacketRepository.send(GrandExchangePacket.class, new GrandExchangeContext(player, offer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new buy offer.
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public void constructBuy(int itemId) {
|
||||
if (openedIndex < 0) {
|
||||
return;
|
||||
}
|
||||
temporaryOffer = new GrandExchangeOffer(itemId, false);
|
||||
if (temporaryOffer.getEntry() == null) {
|
||||
player.getPacketDispatch().sendMessage("This item has been blacklisted from the Grand Exchange.");
|
||||
return;
|
||||
}
|
||||
temporaryOffer.setPlayer(player);
|
||||
temporaryOffer.setDefault();
|
||||
sendConfiguration(temporaryOffer, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new sale offer.
|
||||
* @param item The item to sell.
|
||||
*/
|
||||
public void constructSale(Item item) {
|
||||
if (openedIndex < 0 || offers[openedIndex] != null) {
|
||||
return;
|
||||
}
|
||||
if (item.getId() == 995) {
|
||||
player.getPacketDispatch().sendMessage("You can't offer money!");
|
||||
return;
|
||||
}
|
||||
int id = item.getId();
|
||||
if (!item.getDefinition().isUnnoted()) {
|
||||
id = item.getNoteChange();
|
||||
}
|
||||
if (GrandExchangeDatabase.getDatabase().get(id) == null) {
|
||||
player.getPacketDispatch().sendMessage("This item can't be sold on the Grand Exchange.");
|
||||
return;
|
||||
}
|
||||
temporaryOffer = new GrandExchangeOffer(id, true);
|
||||
temporaryOffer.setPlayer(player);
|
||||
temporaryOffer.setDefault();
|
||||
temporaryOffer.setAmount(item.getAmount());
|
||||
sendConfiguration(temporaryOffer, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total amount of this item in the inventory (including noted
|
||||
* version).
|
||||
* @param player The player.
|
||||
* @param itemId the item id.
|
||||
* @return The amount of items + notes in the inventory.
|
||||
*/
|
||||
public static int getInventoryAmount(Player player, int itemId) {
|
||||
Item item = new Item(itemId);
|
||||
int amount = player.getInventory().getAmount(item);
|
||||
if (item.getDefinition().getNoteId() > -1) {
|
||||
amount += player.getInventory().getAmount(new Item(item.getDefinition().getNoteId()));
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms the current offer.
|
||||
*/
|
||||
public void confirmOffer() {
|
||||
if (openedIndex < 0 || temporaryOffer == null) {
|
||||
return;
|
||||
}
|
||||
if (temporaryOffer.getOfferedValue() < 1) {
|
||||
player.getAudioManager().send(new Audio(4039, 1, 1));
|
||||
player.getPacketDispatch().sendMessage("You can't make an offer for 0 coins.");
|
||||
return;
|
||||
}
|
||||
if (temporaryOffer.getAmount() > (Integer.MAX_VALUE / temporaryOffer.getOfferedValue())) {
|
||||
player.getAudioManager().send(new Audio(4039, 1, 1));
|
||||
player.getPacketDispatch().sendMessage("You can't " + (temporaryOffer.isSell() ? "sell " : "buy ") + " this much!");
|
||||
return;
|
||||
}
|
||||
temporaryOffer.setIndex(openedIndex);
|
||||
if (temporaryOffer.isSell()) {
|
||||
int maxAmount = getInventoryAmount(player, temporaryOffer.getItemId());
|
||||
if (temporaryOffer.getAmount() > maxAmount) {
|
||||
player.getAudioManager().send(new Audio(4039, 1, 1));
|
||||
player.getPacketDispatch().sendMessage("You do not have enough of this item in your inventory to cover the");
|
||||
player.getPacketDispatch().sendMessage("offer.");
|
||||
return;
|
||||
}
|
||||
Item item;
|
||||
int amountLeft = temporaryOffer.getAmount() - player.getInventory().getAmount(new Item(temporaryOffer.getItemId()));
|
||||
boolean remove = player.getInventory().remove(item = new Item(temporaryOffer.getItemId(), temporaryOffer.getAmount()));
|
||||
int note;
|
||||
if (amountLeft > 0) {
|
||||
if ((note = item.getNoteChange()) > 0) {
|
||||
player.getInventory().remove(new Item(note, amountLeft));
|
||||
} else if (remove) {
|
||||
player.getInventory().add(new Item(temporaryOffer.getItemId(), temporaryOffer.getAmount() - amountLeft));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (GEOfferDispatch.dispatch(player, temporaryOffer)) {
|
||||
offers[openedIndex] = temporaryOffer;
|
||||
GEOfferDispatch.updateOffer(temporaryOffer);
|
||||
}
|
||||
} else {
|
||||
int total = temporaryOffer.getAmount() * temporaryOffer.getOfferedValue();
|
||||
if (total > player.getInventory().getAmount(new Item(995))) {
|
||||
player.getAudioManager().send(new Audio(4039, 1, 1));
|
||||
player.getPacketDispatch().sendMessage("You do not have enough coins to cover the offer.");
|
||||
return;
|
||||
}
|
||||
if (GEOfferDispatch.dispatch(player, temporaryOffer) && player.getInventory().remove(new Item(995, total))) {
|
||||
offers[openedIndex] = temporaryOffer;
|
||||
GEOfferDispatch.updateOffer(temporaryOffer);
|
||||
}
|
||||
}
|
||||
player.getMonitor().log((temporaryOffer.isSell() ? "selling" : "buying") + " offer => item => " + ItemDefinition.forId(temporaryOffer.getItemId()).getName() + " => amount => " + temporaryOffer.getAmount() + " => price => " + temporaryOffer.getOfferedValue(), PlayerMonitor.GRAND_EXCHANGE_LOG);
|
||||
toMainInterface();
|
||||
player.getAudioManager().send(new Audio(4043, 1, 1));
|
||||
temporaryOffer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aborts an offer.
|
||||
* @param index The offer index.
|
||||
*/
|
||||
public void abort(int index) {
|
||||
GrandExchangeOffer offer = offers[index];
|
||||
player.getPacketDispatch().sendMessage("Abort request acknowledged. Please be aware that your offer may");
|
||||
player.getPacketDispatch().sendMessage("have already been completed.");
|
||||
if (offer == null || !offer.isActive()) {
|
||||
return;
|
||||
}
|
||||
offer.setState(OfferState.ABORTED);
|
||||
if (offer.isSell()) {
|
||||
offer.addWithdraw(offer.getItemId(), offer.getAmountLeft(), true);
|
||||
} else {
|
||||
offer.addWithdraw(995, offer.getAmountLeft() * offer.getOfferedValue(), true);
|
||||
}
|
||||
player.getGrandExchange().update(offer);
|
||||
player.getMonitor().log("aborted offer => item => " + ItemDefinition.forId(offer.getItemId()).getName() + " => amount => " + offer.getAmount() + "", PlayerMonitor.GRAND_EXCHANGE_LOG);
|
||||
|
||||
GEOfferDispatch.setDumpDatabase(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an offer.
|
||||
* @param index The offer index.
|
||||
*/
|
||||
public boolean remove(int index) {
|
||||
GrandExchangeOffer offer;
|
||||
if ((offer = offers[index]) == null) {
|
||||
return false;
|
||||
}
|
||||
if (offer.getCompletedAmount() > 0) {
|
||||
logHistory(offer);
|
||||
player.getMonitor().log("offer removed => item => " + ItemDefinition.forId(offer.getItemId()).getName() + " => amount => " + offer.getAmount() + " => amount_left => " + offer.getAmountLeft() + " => completed_amount => " + offer.getCompletedAmount() + "", PlayerMonitor.GRAND_EXCHANGE_LOG);
|
||||
|
||||
}
|
||||
offer.setWithdraw(new Item[2]);
|
||||
offer.setUid(0);
|
||||
offer.setState(OfferState.REMOVED);
|
||||
offers[index] = null;
|
||||
update(offer);
|
||||
toMainInterface();
|
||||
return GEOfferDispatch.remove(offer.getUid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the completed offer to the log.
|
||||
* @param offer The completed offer.
|
||||
*/
|
||||
public void logHistory(GrandExchangeOffer offer) {
|
||||
GrandExchangeOffer[] newHistory = new GrandExchangeOffer[5];
|
||||
newHistory[0] = offer;
|
||||
System.arraycopy(history, 0, newHistory, 1, 4);
|
||||
history = newHistory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Views a registered offer.
|
||||
* @param index The index.
|
||||
*/
|
||||
public void view(int index) {
|
||||
if (offers[index] == null) {
|
||||
return;
|
||||
}
|
||||
this.openedIndex = index;
|
||||
sendConfiguration(offers[index], false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the buying screen.
|
||||
* @param index The offer index.
|
||||
*/
|
||||
public void openBuy(int index) {
|
||||
if (index > 3 && !player.isDonator()) {
|
||||
player.getPacketDispatch().sendMessage("You have to be a member to unlock this slot.");
|
||||
return;
|
||||
}
|
||||
this.openedIndex = index;
|
||||
sendConfiguration(offers[index], false);
|
||||
openSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the selling screen.
|
||||
*/
|
||||
public void openSell(int index) {
|
||||
if (index > 3 && !player.isDonator()) {
|
||||
player.getPacketDispatch().sendMessage("You have to be a member to unlock this slot.");
|
||||
return;
|
||||
}
|
||||
this.openedIndex = index;
|
||||
sendConfiguration(offers[index], true);
|
||||
player.getInterfaceManager().openSingleTab(new Component(107)).open(player);
|
||||
player.getPacketDispatch().sendRunScript(149, "IviiiIsssss", "", "", "", "Examine", "Offer", -1, 0, 7, 4, 93, 7012370);
|
||||
BitregisterAssembler.send(player, 107, 18, 0, 27, new BitregisterAssembler(0, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraws an item.
|
||||
* @param offer The offer to withdraw from.
|
||||
* @param index The item index.
|
||||
*/
|
||||
public void withdraw(GrandExchangeOffer offer, int index) {
|
||||
Item item = offer.getWithdraw()[index];
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (player.getInventory().getMaximumAdd(item) < item.getAmount()) {
|
||||
int note = item.getNoteChange();
|
||||
if (note == -1 || player.getInventory().getMaximumAdd(new Item(note)) < item.getAmount()) {
|
||||
player.getAudioManager().send(new Audio(4039, 1, 1));
|
||||
player.getPacketDispatch().sendMessage("You do not have enough room in your inventory.");
|
||||
return;
|
||||
}
|
||||
player.getInventory().add(new Item(note, item.getAmount()));
|
||||
} else {
|
||||
player.getInventory().add(item);
|
||||
}
|
||||
offer.getWithdraw()[index] = null;
|
||||
if (!offer.isActive() && offer.getWithdraw()[0] == null && offer.getWithdraw()[1] == null) {
|
||||
player.getGrandExchange().remove(offer.getIndex());
|
||||
}
|
||||
player.getAudioManager().send(new Audio(4040, 1, 1));
|
||||
offer.sendItems();
|
||||
GEOfferDispatch.setDumpDatabase(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the search interface.
|
||||
*/
|
||||
public void openSearch() {
|
||||
Component c = new Component(389);
|
||||
c.getDefinition().setType(InterfaceType.CS_CHATBOX);
|
||||
c.setCloseEvent(new CloseEvent() {
|
||||
@Override
|
||||
public boolean close(Player player, Component c) {
|
||||
player.getPacketDispatch().sendRunScript(571, "");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
player.getPacketDispatch().sendRunScript(570, "s", "Grand Exchange Item Search");
|
||||
player.getInterfaceManager().openChatbox(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the configuration packets for the offer.
|
||||
* @param offer The grand exchange offer.
|
||||
* @param sell If it's a selling offer.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void sendConfiguration(GrandExchangeOffer offer, boolean sell) {
|
||||
boolean construct = offer == null;
|
||||
GrandExchangeEntry entry = null;
|
||||
String examine = "";
|
||||
if (!construct) {
|
||||
entry = offer.getEntry();
|
||||
examine = ItemDefinition.forId(offer.getItemId()).getExamine();
|
||||
}
|
||||
player.getPacketDispatch().sendString(examine, 105, 142);
|
||||
player.getConfigManager().send(1114, entry == null ? 0 : entry.getValue());
|
||||
player.getConfigManager().send(1115, (int) (entry == null ? 0 : entry.getValue() * 0.95));
|
||||
player.getConfigManager().send(1116, (int) (entry == null ? 0 : entry.getValue() * 1.05));
|
||||
player.getConfigManager().send(1112, openedIndex);
|
||||
player.getConfigManager().send(1113, sell ? 1 : 0);
|
||||
player.getConfigManager().send(1109, construct ? -1 : offer.getItemId());
|
||||
player.getConfigManager().send(1110, construct ? 0 : offer.getAmount());
|
||||
player.getConfigManager().send(1111, construct ? 0 : offer.getOfferedValue());
|
||||
if (!construct) {
|
||||
offer.sendItems();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the grand exchange.
|
||||
* @return the formatted offer for the SQL database.
|
||||
*/
|
||||
public String format() {
|
||||
String log = "";
|
||||
for (GrandExchangeOffer offer : offers) {
|
||||
if (offer != null) {
|
||||
log += offer.getItemId() + "," + offer.getAmount() + "," + offer.isSell() + "|";
|
||||
}
|
||||
}
|
||||
if (log.length() > 0 && log.charAt(log.length() - 1) == '|') {
|
||||
log = log.substring(0, log.length() - 1);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently opened offer.
|
||||
* @return The grand exchange offer currently opened.
|
||||
*/
|
||||
public GrandExchangeOffer getOpenedOffer() {
|
||||
if (openedIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
return offers[openedIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has an active offer.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasActiveOffer() {
|
||||
for (GrandExchangeOffer offer : offers) {
|
||||
if (offer != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offers.
|
||||
* @return The offers.
|
||||
*/
|
||||
public GrandExchangeOffer[] getOffers() {
|
||||
return offers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the openedIndex.
|
||||
* @return The openedIndex.
|
||||
*/
|
||||
public int getOpenedIndex() {
|
||||
return openedIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the openedIndex.
|
||||
* @param openedIndex The openedIndex to set.
|
||||
*/
|
||||
public void setOpenedIndex(int openedIndex) {
|
||||
this.openedIndex = openedIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the temporaryOffer.
|
||||
* @return The temporaryOffer.
|
||||
*/
|
||||
public GrandExchangeOffer getTemporaryOffer() {
|
||||
return temporaryOffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the temporaryOffer.
|
||||
* @param temporaryOffer The temporaryOffer to set.
|
||||
*/
|
||||
public void setTemporaryOffer(GrandExchangeOffer temporaryOffer) {
|
||||
this.temporaryOffer = temporaryOffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the history.
|
||||
* @return The history.
|
||||
*/
|
||||
public GrandExchangeOffer[] getHistory() {
|
||||
return history;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the grand exchange database.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GrandExchangeDatabase {
|
||||
|
||||
/**
|
||||
* The grand exchange database mapping.
|
||||
*/
|
||||
private static final Map<Integer, GrandExchangeEntry> DATABASE = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The minimum amount of unique trades required for an entry to change its
|
||||
* value.
|
||||
*/
|
||||
private static final int MINIMUM_TRADES = 10;// 200
|
||||
|
||||
/**
|
||||
* The amount of hours between each update cycle.
|
||||
*/
|
||||
private static final int UPDATE_CYCLE_HOURS = 3;
|
||||
|
||||
/**
|
||||
* The next update.
|
||||
*/
|
||||
private static long nextUpdate;
|
||||
|
||||
/**
|
||||
* If the G.E database has initialized.
|
||||
*/
|
||||
private static boolean initialized;
|
||||
|
||||
/**
|
||||
* Initializes the database
|
||||
*/
|
||||
public static void init() {
|
||||
String path = "data/" + "eco/";
|
||||
if (!new File(path + "grand_exchange_db.emp").exists()) {
|
||||
dump("data/");
|
||||
System.err.println("ge db wasn't found!");
|
||||
}
|
||||
try (RandomAccessFile raf = new RandomAccessFile(path + "grand_exchange_db.emp", "rw")) {
|
||||
nextUpdate = raf.readLong();
|
||||
int length = raf.readInt();
|
||||
for (int i = 0; i < length; i++) {
|
||||
int itemId = raf.readShort() & 0xFFFF;
|
||||
GrandExchangeEntry entry = new GrandExchangeEntry(itemId);
|
||||
entry.setValue(raf.readInt());
|
||||
if (entry.getValue() < 1) {
|
||||
entry.setValue(1);
|
||||
}
|
||||
int logLength = raf.readByte() & 0xFF;
|
||||
entry.setLogLength(logLength);
|
||||
for (int index = 0; index < logLength; index++) {
|
||||
entry.getValueLog()[index] = raf.readInt();
|
||||
}
|
||||
entry.setUniqueTrades(raf.readShort());
|
||||
entry.setTotalValue(raf.readLong());
|
||||
entry.setLastUpdate(raf.readLong());
|
||||
DATABASE.put(itemId, entry);
|
||||
}
|
||||
checkUpdate();
|
||||
raf.close();
|
||||
initialized = true;
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the entry values, if needed.
|
||||
*/
|
||||
public static void checkUpdate() {
|
||||
if (nextUpdate < System.currentTimeMillis()) {
|
||||
updateValues();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the grand exchange database.
|
||||
* @param directory The directory to save to.
|
||||
*/
|
||||
public static void dump(String directory) {
|
||||
File f = new File(directory + "eco/grand_exchange_db.emp", "rw");
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
try (RandomAccessFile raf = new RandomAccessFile(directory + "eco/grand_exchange_db.emp", "rw")) {
|
||||
raf.writeLong(nextUpdate);
|
||||
raf.writeInt(DATABASE.size());
|
||||
for (GrandExchangeEntry entry : DATABASE.values()) {
|
||||
raf.writeShort(entry.getItemId());
|
||||
raf.writeInt(entry.getValue());
|
||||
raf.writeByte(entry.getLogLength());
|
||||
for (int i = 0; i < entry.getLogLength(); i++) {
|
||||
raf.writeInt(entry.getValueLog()[i]);
|
||||
}
|
||||
raf.writeShort(entry.getUniqueTrades());
|
||||
raf.writeLong(entry.getTotalValue());
|
||||
raf.writeLong(entry.getLastUpdate());
|
||||
}
|
||||
raf.close();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the item values.
|
||||
*/
|
||||
public static void updateValues() {
|
||||
try {
|
||||
for (GrandExchangeEntry entry : DATABASE.values()) {
|
||||
if (entry.getUniqueTrades() < MINIMUM_TRADES || entry.getTotalValue() == 0) {
|
||||
continue;
|
||||
}
|
||||
double newAverage = entry.getTotalValue() / entry.getUniqueTrades();
|
||||
double changePercentage = newAverage / (double) (entry.getValue() + .001);
|
||||
if (changePercentage == 1.0) {
|
||||
continue;
|
||||
} else if (changePercentage > 1.15) {
|
||||
changePercentage = 1.15;
|
||||
} else if (changePercentage < 0.85) {
|
||||
changePercentage = 0.85;
|
||||
}
|
||||
int newValue = (int) (entry.getValue() * changePercentage);
|
||||
if (newValue == entry.getValue()) {
|
||||
if (changePercentage > 1.0) { // Fixes 1gp not being
|
||||
// influenced.
|
||||
newValue++;
|
||||
} else if (newValue > 0) {
|
||||
newValue--;
|
||||
}
|
||||
}
|
||||
entry.updateValue(newValue);
|
||||
entry.setLastUpdate(nextUpdate);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
nextUpdate = System.currentTimeMillis() + (UPDATE_CYCLE_HOURS * (60 * 60 * 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database.
|
||||
* @return The database.
|
||||
*/
|
||||
public static Map<Integer, GrandExchangeEntry> getDatabase() {
|
||||
return DATABASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nextUpdate.
|
||||
* @return The nextUpdate.
|
||||
*/
|
||||
public static long getNextUpdate() {
|
||||
return nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nextUpdate.
|
||||
* @param nextUpdate The nextUpdate to set.
|
||||
*/
|
||||
public static void setNextUpdate(long nextUpdate) {
|
||||
GrandExchangeDatabase.nextUpdate = nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the grand exchange database has initialized.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean hasInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a grand exchange entry, which contains the item id, current price
|
||||
* and previous prices.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GrandExchangeEntry {
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final int itemId;
|
||||
|
||||
/**
|
||||
* The item value.
|
||||
*/
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* The value log.
|
||||
*/
|
||||
private int[] valueLog = new int[256];
|
||||
|
||||
/**
|
||||
* The log length.
|
||||
*/
|
||||
private int logLength;
|
||||
|
||||
/**
|
||||
* The amount of unique trades completed.
|
||||
*/
|
||||
private int uniqueTrades;
|
||||
|
||||
/**
|
||||
* The total value amount of each the unique trades. <br> This is used to
|
||||
* calculate the average price, so we know whether or not to update price.
|
||||
*/
|
||||
private long totalValue;
|
||||
|
||||
/**
|
||||
* The last update time stamp.
|
||||
*/
|
||||
private long lastUpdate;
|
||||
|
||||
/**
|
||||
* The mapping of completed buying offers.
|
||||
*/
|
||||
private Map<Integer, Integer> boughtMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GrandExchangeEntry} {@code Object}.
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public GrandExchangeEntry(int itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the item value.
|
||||
* @param value The new item value to set.
|
||||
*/
|
||||
public void updateValue(int value) {
|
||||
int[] newValueLog = new int[256];
|
||||
System.arraycopy(valueLog, 0, newValueLog, 1, logLength);
|
||||
newValueLog[0] = this.value;
|
||||
this.valueLog = newValueLog;
|
||||
this.value = value;
|
||||
this.uniqueTrades = 0;
|
||||
this.totalValue = 0;
|
||||
if (++logLength > 255) {
|
||||
logLength = 255;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Influences the price of this item.
|
||||
* @param player The player exchanging this item.
|
||||
* @param value The value offered in the exchange.
|
||||
*/
|
||||
public void influenceValue(int value) {
|
||||
if (value < this.value * 0.5) { // Makes sure the player can't influence
|
||||
// too much
|
||||
value = (int) (this.value * 0.5);
|
||||
} else if (value > this.value * 1.5) {
|
||||
value = (int) (this.value * 1.5);
|
||||
}
|
||||
uniqueTrades++;
|
||||
totalValue += value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the itemId.
|
||||
* @return The itemId.
|
||||
*/
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value.
|
||||
* @return The value.
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the valueLog.
|
||||
* @return The valueLog.
|
||||
*/
|
||||
public int[] getValueLog() {
|
||||
return valueLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the valueLog.
|
||||
* @param valueLog The valueLog to set.
|
||||
*/
|
||||
public void setValueLog(int[] valueLog) {
|
||||
this.valueLog = valueLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uniqueTrades.
|
||||
* @return The uniqueTrades.
|
||||
*/
|
||||
public int getUniqueTrades() {
|
||||
return uniqueTrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the uniqueTrades.
|
||||
* @param uniqueTrades The uniqueTrades to set.
|
||||
*/
|
||||
public void setUniqueTrades(int uniqueTrades) {
|
||||
this.uniqueTrades = uniqueTrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the totalValue.
|
||||
* @return The totalValue.
|
||||
*/
|
||||
public long getTotalValue() {
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the totalValue.
|
||||
* @param totalValue The totalValue to set.
|
||||
*/
|
||||
public void setTotalValue(long totalValue) {
|
||||
this.totalValue = totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lastUpdate.
|
||||
* @return The lastUpdate.
|
||||
*/
|
||||
public long getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lastUpdate.
|
||||
* @param lastUpdate The lastUpdate to set.
|
||||
*/
|
||||
public void setLastUpdate(long lastUpdate) {
|
||||
this.lastUpdate = lastUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the logLength.
|
||||
* @return The logLength.
|
||||
*/
|
||||
public int getLogLength() {
|
||||
return logLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logLength.
|
||||
* @param logLength The logLength to set.
|
||||
*/
|
||||
public void setLogLength(int logLength) {
|
||||
this.logLength = logLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boughtMap.
|
||||
* @return The boughtMap.
|
||||
*/
|
||||
public Map<Integer, Integer> getBoughtMap() {
|
||||
return boughtMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boughtMap.
|
||||
* @param boughtMap The boughtMap to set.
|
||||
*/
|
||||
public void setBoughtMap(Map<Integer, Integer> boughtMap) {
|
||||
this.boughtMap = boughtMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GrandExchangeEntry [itemId=" + itemId + ", value=" + value + ", valueLog=" + Arrays.toString(valueLog) + ", logLength=" + logLength + ", uniqueTrades=" + uniqueTrades + ", totalValue=" + totalValue + ", lastUpdate=" + lastUpdate + ", boughtMap=" + boughtMap + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,466 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ContainerContext;
|
||||
import org.crandor.net.packet.out.ContainerPacket;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a Grand Exchange offer.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class GrandExchangeOffer {
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final int itemId;
|
||||
|
||||
/**
|
||||
* The amount.
|
||||
*/
|
||||
private int amount;
|
||||
|
||||
/**
|
||||
* The completed amount.
|
||||
*/
|
||||
private int completedAmount;
|
||||
|
||||
/**
|
||||
* The offered value per item.
|
||||
*/
|
||||
private int offeredValue;
|
||||
|
||||
/**
|
||||
* The index of this offer.
|
||||
*/
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* If the player is selling.
|
||||
*/
|
||||
private boolean sell;
|
||||
|
||||
/**
|
||||
* The current state of this offer.
|
||||
*/
|
||||
private OfferState state = OfferState.PENDING;
|
||||
|
||||
/**
|
||||
* The unique id of this offer.
|
||||
*/
|
||||
private long uid;
|
||||
|
||||
/**
|
||||
* The time stamp of when this offer was entered.
|
||||
*/
|
||||
private long timeStamp;
|
||||
|
||||
/**
|
||||
* The items to withdraw from this offer.
|
||||
*/
|
||||
private Item[] withdraw = new Item[2];
|
||||
|
||||
/**
|
||||
* The total amount of coins that have been exchanged.
|
||||
*/
|
||||
private int totalCoinExchange;
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private Player player;
|
||||
|
||||
/**
|
||||
* The player UID.
|
||||
*/
|
||||
private int playerUID;
|
||||
|
||||
/**
|
||||
* If the offer is limited due to buying limitation.
|
||||
*/
|
||||
private boolean limitation;
|
||||
|
||||
/**
|
||||
* The grand exchange entry.
|
||||
*/
|
||||
private GrandExchangeEntry entry;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GrandExchangeOffer} {@code Object}.
|
||||
* @param itemId The item id.
|
||||
* @param sell If the offer is a selling offer.
|
||||
*/
|
||||
public GrandExchangeOffer(int itemId, boolean sell) {
|
||||
this.itemId = itemId;
|
||||
this.sell = sell;
|
||||
this.entry = GrandExchangeDatabase.getDatabase().get(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this offer is still active for dispatching.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return state != OfferState.ABORTED && state != OfferState.PENDING && state != OfferState.COMPLETED && state != OfferState.REMOVED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new item to withdraw.
|
||||
* @param itemId The item id.
|
||||
* @param amount The amount to add.
|
||||
*/
|
||||
public void addWithdraw(int itemId, int amount) {
|
||||
addWithdraw(itemId, amount, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new item to withdraw.
|
||||
* @param itemId The item id.
|
||||
* @param amount The amount to add.
|
||||
* @param abort If the item is added due to abort.
|
||||
*/
|
||||
public void addWithdraw(int itemId, int amount, boolean abort) {
|
||||
if (!abort) {
|
||||
if (sell) {
|
||||
if (itemId == 995) {
|
||||
totalCoinExchange += amount;
|
||||
}
|
||||
} else {
|
||||
if (itemId == 995) {
|
||||
totalCoinExchange -= amount;
|
||||
} else {
|
||||
totalCoinExchange += offeredValue * amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < withdraw.length; i++) {
|
||||
if (withdraw[i] == null) {
|
||||
withdraw[i] = new Item(itemId, amount);
|
||||
break;
|
||||
}
|
||||
if (withdraw[i].getId() == itemId) {
|
||||
withdraw[i].setAmount(withdraw[i].getAmount() + amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player != null) {
|
||||
sendItems();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the items.
|
||||
*/
|
||||
public void sendItems() {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -1757, 523 + index, withdraw, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default values for an offer.
|
||||
*/
|
||||
public void setDefault() {
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
this.amount = 1;
|
||||
this.offeredValue = entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a notification to the player, if he is online.
|
||||
* @param message The notification message.
|
||||
*/
|
||||
public void notify(String message) {
|
||||
if (player == null || !player.isActive()) {
|
||||
return;
|
||||
}
|
||||
player.getPacketDispatch().sendMessage(message);
|
||||
player.getGrandExchange().update(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the offer is currently being limited by the 4-hours buying
|
||||
* limitation.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isLimited() {
|
||||
return !sell && BuyingLimitation.isLimited(itemId, playerUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the offer.
|
||||
*/
|
||||
public void init() {
|
||||
this.timeStamp = entry.getLastUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database entry of this offer.
|
||||
* @return The grand exchange entry.
|
||||
*/
|
||||
public GrandExchangeEntry getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total amount of money entered.
|
||||
* @return The total value.
|
||||
*/
|
||||
public int getTotalValue() {
|
||||
return offeredValue * amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the itemId.
|
||||
* @return The itemId.
|
||||
*/
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timeStamp.
|
||||
* @return The timeStamp.
|
||||
*/
|
||||
public long getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of this item left to buy.
|
||||
* @return The amount.
|
||||
*/
|
||||
public int getAmountLeft() {
|
||||
return getAmountLeft(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of this item left to buy.
|
||||
* @param limit If the buying limit should be taken into consideration.
|
||||
* @return The amount.
|
||||
*/
|
||||
public int getAmountLeft(boolean limit) {
|
||||
int left = amount - completedAmount;
|
||||
if (limit && !sell && left > 0) {
|
||||
int maximum = BuyingLimitation.getMaximumBuy(itemId, playerUID);
|
||||
if (left >= maximum) {
|
||||
left = maximum;
|
||||
limitation = true;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount.
|
||||
* @return The amount.
|
||||
*/
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount.
|
||||
* @param amount The amount to set.
|
||||
*/
|
||||
public void setAmount(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offeredValue.
|
||||
* @return The offeredValue.
|
||||
*/
|
||||
public int getOfferedValue() {
|
||||
return offeredValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offeredValue.
|
||||
* @param offeredValue The offeredValue to set.
|
||||
*/
|
||||
public void setOfferedValue(int offeredValue) {
|
||||
this.offeredValue = offeredValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sell.
|
||||
* @return The sell.
|
||||
*/
|
||||
public boolean isSell() {
|
||||
return sell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sell.
|
||||
* @param sell The sell to set.
|
||||
*/
|
||||
public void setSell(boolean sell) {
|
||||
this.sell = sell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state.
|
||||
* @return The state.
|
||||
*/
|
||||
public OfferState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state.
|
||||
* @param state The state to set.
|
||||
*/
|
||||
public void setState(OfferState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uid.
|
||||
* @return The uid.
|
||||
*/
|
||||
public long getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the uid.
|
||||
* @param uid The uid to set.
|
||||
*/
|
||||
public void setUid(long uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the withdraw.
|
||||
* @return The withdraw.
|
||||
*/
|
||||
public Item[] getWithdraw() {
|
||||
return withdraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the withdraw.
|
||||
* @param withdraw The withdraw to set.
|
||||
*/
|
||||
public void setWithdraw(Item[] withdraw) {
|
||||
this.withdraw = withdraw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the completedAmount.
|
||||
* @return The completedAmount.
|
||||
*/
|
||||
public int getCompletedAmount() {
|
||||
return completedAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the completedAmount.
|
||||
* @param completedAmount The completedAmount to set.
|
||||
*/
|
||||
public void setCompletedAmount(int completedAmount) {
|
||||
this.completedAmount = completedAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index.
|
||||
* @return The index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index.
|
||||
* @param index The index to set.
|
||||
*/
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player.
|
||||
* @param player The player to set.
|
||||
*/
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time stamp.
|
||||
* @param timeStamp The time stamp.
|
||||
*/
|
||||
public void setTimeStamp(long timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the totalCoinExchange.
|
||||
* @return The totalCoinExchange.
|
||||
*/
|
||||
public int getTotalCoinExchange() {
|
||||
return totalCoinExchange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the totalCoinExchange.
|
||||
* @param totalCoinExchange The totalCoinExchange to set.
|
||||
*/
|
||||
public void setTotalCoinExchange(int totalCoinExchange) {
|
||||
this.totalCoinExchange = totalCoinExchange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the playerUID.
|
||||
* @return The playerUID.
|
||||
*/
|
||||
public int getPlayerUID() {
|
||||
return playerUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the playerUID.
|
||||
* @param playerUID The playerUID to set.
|
||||
*/
|
||||
public void setPlayerUID(int playerUID) {
|
||||
this.playerUID = playerUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the limitation.
|
||||
* @return The limitation.
|
||||
*/
|
||||
public boolean isLimitation() {
|
||||
return limitation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the limitation.
|
||||
* @param limitation The limitation to set.
|
||||
*/
|
||||
public void setLimitation(boolean limitation) {
|
||||
this.limitation = limitation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[name=" + ItemDefinition.forId(itemId).getName() + ", itemId=" + itemId + ", amount=" + amount + ", completedAmount=" + completedAmount + ", offeredValue=" + offeredValue + ", index=" + index + ", sell=" + sell + ", state=" + state + ", withdraw=" + Arrays.toString(withdraw) + ", totalCoinExchange=" + totalCoinExchange + ", playerUID=" + playerUID + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
/**
|
||||
* Represents the state of a Grand Exchange offer.
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum OfferState {
|
||||
|
||||
/**
|
||||
* The player is still constructing the offer.
|
||||
*/
|
||||
PENDING,
|
||||
|
||||
/**
|
||||
* The player has confirmed the offer (the offer is being dispatched).
|
||||
*/
|
||||
REGISTERED,
|
||||
|
||||
/**
|
||||
* The offer has been aborted.
|
||||
*/
|
||||
ABORTED,
|
||||
|
||||
/**
|
||||
* The offer has been updated.
|
||||
*/
|
||||
UPDATED,
|
||||
|
||||
/**
|
||||
* The offer is completed.
|
||||
*/
|
||||
COMPLETED,
|
||||
|
||||
/**
|
||||
* The offer is outdated.
|
||||
*/
|
||||
OUTDATED,
|
||||
|
||||
/**
|
||||
* The offer has been removed.
|
||||
*/
|
||||
REMOVED;
|
||||
}
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
package org.crandor.game.content.eco.ge;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.content.global.consumable.Consumables;
|
||||
import org.crandor.game.content.global.consumable.Food;
|
||||
import org.crandor.game.content.skill.free.cooking.recipe.Recipe;
|
||||
import org.crandor.game.content.skill.free.crafting.GlassProduct;
|
||||
import org.crandor.game.content.skill.free.crafting.SilverProduct;
|
||||
import org.crandor.game.content.skill.free.crafting.TanningProduct;
|
||||
import org.crandor.game.content.skill.free.crafting.armour.LeatherCrafting;
|
||||
import org.crandor.game.content.skill.free.crafting.gem.Gems;
|
||||
import org.crandor.game.content.skill.free.crafting.jewellery.JewelleryCrafting;
|
||||
import org.crandor.game.content.skill.free.crafting.pottery.PotteryItem;
|
||||
import org.crandor.game.content.skill.free.crafting.spinning.SpinningItem;
|
||||
import org.crandor.game.content.skill.free.fishing.Fish;
|
||||
import org.crandor.game.content.skill.free.gather.SkillingResource;
|
||||
import org.crandor.game.content.skill.free.magic.Runes;
|
||||
import org.crandor.game.content.skill.free.runecrafting.Talisman;
|
||||
import org.crandor.game.content.skill.free.runecrafting.Tiara;
|
||||
import org.crandor.game.content.skill.free.smithing.Bars;
|
||||
import org.crandor.game.content.skill.member.farming.patch.Allotments;
|
||||
import org.crandor.game.content.skill.member.fletching.FletchItem;
|
||||
import org.crandor.game.content.skill.member.fletching.items.arrow.ArrowHead;
|
||||
import org.crandor.game.content.skill.member.fletching.items.bolts.Bolt;
|
||||
import org.crandor.game.content.skill.member.fletching.items.bow.StringBow;
|
||||
import org.crandor.game.content.skill.member.fletching.items.crossbow.Limb;
|
||||
import org.crandor.game.content.skill.member.fletching.items.darts.Dart;
|
||||
import org.crandor.game.content.skill.member.fletching.items.gem.Gem;
|
||||
import org.crandor.game.content.skill.member.herblore.FinishedPotion;
|
||||
import org.crandor.game.content.skill.member.herblore.GrindingItem;
|
||||
import org.crandor.game.content.skill.member.herblore.Herbs;
|
||||
import org.crandor.game.content.skill.member.herblore.UnfinishedPotion;
|
||||
import org.crandor.game.content.skill.member.summoning.SummoningPouch;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.mysql.impl.ItemConfigSQLHandler;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages several resources being "pumped" into the game by creating offers in
|
||||
* the grand exchange.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ResourceManager {
|
||||
|
||||
/**
|
||||
* The resources used for "kick-starting" the eco.
|
||||
*/
|
||||
private static final int[] RESOURCES = { 3122, 4153, 6809, 10564, 10589, 1215, 4587, 1305, 1434, 7158, 3204, 1377, 1249, 11212, 11230, 6523, 6527, 6528, 6525, 6524, 6128, 6129, 6130, 6131, 6133, 6135, 6137, 6139, 6141, 6143, 6145, 6147, 6149, 6151, 6153 };
|
||||
|
||||
/**
|
||||
* The database path.
|
||||
*/
|
||||
private static final String DB_PATH = "eco/ge_resource.emp";
|
||||
|
||||
/**
|
||||
* The current stock of resources.
|
||||
*/
|
||||
private static final List<GrandExchangeOffer> STOCK = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Loads the resources stock.
|
||||
*/
|
||||
public static void init() {
|
||||
File file = new File("data/" + DB_PATH);
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel c = raf.getChannel()) {
|
||||
ByteBuffer b = c.map(MapMode.READ_WRITE, 0, c.size());
|
||||
int itemId = -1;
|
||||
while ((itemId = b.getShort()) != -1) {
|
||||
boolean sale = b.get() == 1;
|
||||
GrandExchangeOffer offer = new GrandExchangeOffer(itemId, sale);
|
||||
offer.setAmount(b.getInt());
|
||||
offer.setCompletedAmount(b.getInt());
|
||||
offer.setOfferedValue(b.getInt());
|
||||
int value = offer.getOfferedValue();
|
||||
int shopValue = ItemDefinition.forId(itemId).getValue();
|
||||
if (value < (shopValue * 1.05)) {
|
||||
value = (int) (shopValue * 1.05);
|
||||
}
|
||||
offer.setOfferedValue(value);
|
||||
offer.setTimeStamp(b.getLong());
|
||||
offer.setState(OfferState.values()[b.get()]);
|
||||
offer.setTotalCoinExchange(b.getInt());
|
||||
offer.setPlayerUID(-1);
|
||||
offer.setUid(STOCK.size() + 1);
|
||||
STOCK.add(offer);
|
||||
}
|
||||
raf.close();
|
||||
c.close();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the current resources.
|
||||
* @param directory The directory to save to.
|
||||
*/
|
||||
public static void dump(String directory) {
|
||||
File file = new File(directory + DB_PATH);
|
||||
ByteBuffer b = ByteBuffer.allocate(50_000_000);
|
||||
for (GrandExchangeOffer offer : STOCK) {
|
||||
if (offer == null || offer.getState() == OfferState.COMPLETED) {
|
||||
continue;
|
||||
}
|
||||
b.putShort((short) offer.getItemId());
|
||||
b.put((byte) (offer.isSell() ? 1 : 0));
|
||||
b.putInt(offer.getAmount());
|
||||
b.putInt(offer.getCompletedAmount());
|
||||
b.putInt(offer.getOfferedValue());
|
||||
b.putLong(offer.getTimeStamp());
|
||||
b.put((byte) offer.getState().ordinal());
|
||||
b.putInt(offer.getTotalCoinExchange());
|
||||
}
|
||||
b.putShort((short) -1);
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel c = raf.getChannel()) {
|
||||
b.flip();
|
||||
c.write(b);
|
||||
raf.close();
|
||||
c.close();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the resource offer.
|
||||
* @param itemId The item id to clear.
|
||||
*/
|
||||
public static void clearResource(int itemId) {
|
||||
for (Iterator<GrandExchangeOffer> it = STOCK.iterator(); it.hasNext();) {
|
||||
GrandExchangeOffer offer = it.next();
|
||||
if (offer.getItemId() == itemId) {
|
||||
offer.setCompletedAmount(offer.getAmount());
|
||||
offer.setState(OfferState.COMPLETED);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new resource offer.
|
||||
* @param itemId The item id.
|
||||
* @param amount The amount.
|
||||
* @param sell If the G.E should sell the resource.
|
||||
*/
|
||||
public static void addResource(int itemId, int amount, boolean sell) {
|
||||
GrandExchangeOffer offer = new GrandExchangeOffer(itemId, sell);
|
||||
if (offer.getEntry() == null) {
|
||||
System.out.println("No Grand Exchange entry found for item " + itemId + "!");
|
||||
return;
|
||||
}
|
||||
offer.setState(OfferState.REGISTERED);
|
||||
offer.setAmount(amount);
|
||||
offer.setOfferedValue((int) (new Item(itemId).getValue() * 1.05));
|
||||
offer.setPlayerUID(-1);
|
||||
offer.setUid(STOCK.size() + 1);
|
||||
offer.setTimeStamp(System.currentTimeMillis());
|
||||
STOCK.add(offer);
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
GameWorld.prompt(false);
|
||||
kickStartEconomy();
|
||||
}
|
||||
|
||||
/**
|
||||
* "Kick starts" the economy by adding resources to the Grand Exchange.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void kickStartEconomy() {
|
||||
List<Integer> handledResources = new ArrayList<>();
|
||||
int id;
|
||||
for (int itemId : RESOURCES) {
|
||||
handledResources.add(itemId);
|
||||
}
|
||||
for (SkillingResource r : SkillingResource.values()) {
|
||||
if (!handledResources.contains(id = r.getReward())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Consumables c : Consumables.values()) {
|
||||
if (c.getConsumable() instanceof Food) {
|
||||
Food f = c.getConsumable().asFood();
|
||||
if (f.getRaw() != null && !handledResources.contains(id = f.getRaw().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
if (!handledResources.contains(id = c.getConsumable().getItem().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Recipe r : Recipe.RECIPES) {
|
||||
for (Item item : r.getIngredients()) {
|
||||
if (!handledResources.contains(id = item.getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
if (!handledResources.contains(id = r.getBase().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (LeatherCrafting.DragonHide d : LeatherCrafting.DragonHide.values()) {
|
||||
if (!handledResources.contains(id = d.getLeather())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = d.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (LeatherCrafting.SoftLeather s : LeatherCrafting.SoftLeather.values()) {
|
||||
if (!handledResources.contains(id = s.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Gems g : Gems.values()) {
|
||||
if (!handledResources.contains(id = g.getGem().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = g.getUncut().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (JewelleryCrafting.JewelleryItem d : JewelleryCrafting.JewelleryItem.values()) {
|
||||
if (!handledResources.contains(id = d.getSendItem())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
for (int item : d.getItems()) {
|
||||
if (!handledResources.contains(id = item)) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PotteryItem item : PotteryItem.values()) {
|
||||
if (!handledResources.contains(id = item.getUnfinished().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = item.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (SpinningItem s : SpinningItem.values()) {
|
||||
if (!handledResources.contains(id = s.getNeed())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = s.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (GlassProduct s : GlassProduct.values()) {
|
||||
if (!handledResources.contains(id = s.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (SilverProduct s : SilverProduct.values()) {
|
||||
if (!handledResources.contains(id = s.getNeeded())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = s.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = s.getStrung())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (TanningProduct t : TanningProduct.values()) {
|
||||
if (!handledResources.contains(id = t.getItem())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = t.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Fish f : Fish.values()) {
|
||||
if (!handledResources.contains(id = f.getItem().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Runes r : Runes.values()) {
|
||||
if (!handledResources.contains(id = r.getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Talisman t : Talisman.values()) {
|
||||
if (!handledResources.contains(id = t.getTalisman().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Tiara t : Tiara.values()) {
|
||||
if (!handledResources.contains(id = t.getTiara().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Bars b : Bars.values()) {
|
||||
if (!handledResources.contains(id = b.getProduct())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = b.getBarType().getBarType())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Allotments a : Allotments.values()) {
|
||||
if (!handledResources.contains(id = a.getFarmingNode().getSeed().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = a.getFarmingNode().getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (ArrowHead h : ArrowHead.values()) {
|
||||
if (!handledResources.contains(id = h.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Dart d : Dart.values()) {
|
||||
if (!handledResources.contains(id = d.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Bolt b : Bolt.values()) {
|
||||
if (!handledResources.contains(id = b.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (StringBow b : StringBow.values()) {
|
||||
if (!handledResources.contains(id = b.getItem().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = b.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Limb l : Limb.values()) {
|
||||
if (!handledResources.contains(id = l.getLimb().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = l.getStock().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = l.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Gem g : Gem.values()) {
|
||||
if (!handledResources.contains(id = g.getBolt().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (FletchItem f : FletchItem.values()) {
|
||||
if (!handledResources.contains(id = f.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (Herbs h : Herbs.values()) {
|
||||
if (!handledResources.contains(id = h.getHerb().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = h.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (GrindingItem g : GrindingItem.values()) {
|
||||
if (!handledResources.contains(id = g.getProduct().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
for (Item i : g.getItems()) {
|
||||
if (!handledResources.contains(id = i.getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (FinishedPotion f : FinishedPotion.values()) {
|
||||
if (!handledResources.contains(id = f.getIngredient().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = f.getPotion().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (UnfinishedPotion f : UnfinishedPotion.values()) {
|
||||
if (!handledResources.contains(id = f.getIngredient().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = f.getPotion().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
if (!handledResources.contains(id = f.getBase().getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
for (SummoningPouch s : SummoningPouch.values()) {
|
||||
for (Item item : s.getItems()) {
|
||||
if (!handledResources.contains(id = item.getId())) {
|
||||
handledResources.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int itemId : handledResources) {
|
||||
ItemDefinition def = ItemDefinition.forId(itemId);
|
||||
if (def == null) {
|
||||
System.err.println("Roar " + itemId);
|
||||
continue;
|
||||
}
|
||||
int amount = def.getConfiguration(ItemConfigSQLHandler.GE_LIMIT, 500) * 100;
|
||||
// addResource(itemId, amount, true);
|
||||
System.out.println(amount + " x " + def.getName() + " - " + (int) (new Item(itemId).getValue() * 1.05) + "gp");
|
||||
}
|
||||
// System.out.println("Added " + handledResources.size() +
|
||||
// " resources!");
|
||||
// handledResources.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stock.
|
||||
* @return The stock.
|
||||
*/
|
||||
public static List<GrandExchangeOffer> getStock() {
|
||||
return STOCK;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.entity.npc.drop.NPCDropTables;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.ChanceItem;
|
||||
import org.crandor.game.node.item.GroundItemManager;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.tools.RandomFunction;
|
||||
import org.crandor.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents a birds nest.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum BirdNest {
|
||||
SEED(new ChanceItem(5073, 1, 65), new ChanceItem(5312, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5283, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5284, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5285, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5313, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5286, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5314, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5287, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5288, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5289, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5290, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5315, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5316, 1, NPCDropTables.DROP_RATES[3]), new ChanceItem(5317, 1, NPCDropTables.DROP_RATES[3])), RING(new ChanceItem(5074, 1, 30), new ChanceItem(1635, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(1637, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(1639, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(1641, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(1643, 1, NPCDropTables.DROP_RATES[3])), RED(new ChanceItem(5070, 1, 5), new ChanceItem(5076)), GREEN(new ChanceItem(5071, 1, 5), new ChanceItem(5078)), BLUE(new ChanceItem(5072, 1, 5), new ChanceItem(5077)), RAVEN(new ChanceItem(11966, 1, 5), new ChanceItem(11964)), WYSON(new ChanceItem(7413, 1, 1), new ChanceItem(5324, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5320, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5322, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5319, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5318, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(12148, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5100, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5323, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5296, 1, NPCDropTables.DROP_RATES[0]), new ChanceItem(5321, 1, NPCDropTables.DROP_RATES[1]), new ChanceItem(5295, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5314, 1, NPCDropTables.DROP_RATES[2]), new ChanceItem(5315, 1, NPCDropTables.DROP_RATES[3]), new ChanceItem(5316, 1, NPCDropTables.DROP_RATES[3]));
|
||||
|
||||
/**
|
||||
* The random nest items.
|
||||
*/
|
||||
private static final ChanceItem[] NESTS = new ChanceItem[6];
|
||||
|
||||
/**
|
||||
* The empty birds nest item.
|
||||
*/
|
||||
private static final Item EMPTY = new Item(5075);
|
||||
|
||||
/**
|
||||
* The birds nest item.
|
||||
*/
|
||||
private final ChanceItem nest;
|
||||
|
||||
/**
|
||||
* The loot item from the nest.
|
||||
*/
|
||||
private final ChanceItem[] loot;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BirdNest} {@code Object}.
|
||||
* @param nest the nest.
|
||||
* @param loot the loot.
|
||||
*/
|
||||
private BirdNest(final ChanceItem nest, final ChanceItem... loot) {
|
||||
this.nest = nest;
|
||||
this.loot = loot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a birds nest.
|
||||
* @param player the player.
|
||||
*/
|
||||
public static void drop(final Player player) {
|
||||
final BirdNest nest = getRandomNest(false);
|
||||
player.getAudioManager().send(1997);
|
||||
GroundItemManager.create(nest.getNest(), player);
|
||||
player.getPacketDispatch().sendMessage("<col=FF0000>A bird's nest falls out of the tree.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a bird nest.
|
||||
* @param player the player.
|
||||
* @param item the item searched.
|
||||
*/
|
||||
public void search(final Player player, Item item) {
|
||||
if (player.getInventory().freeSlots() < 1) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space.");
|
||||
return;
|
||||
}
|
||||
final ChanceItem loot = ordinal() > 1 && this != WYSON ? getLoot()[0] : RandomFunction.getChanceItem(getLoot());
|
||||
final String name = loot.getName().toLowerCase();
|
||||
final String input = (StringUtils.isPlusN(name) ? "an" : "a") + " " + name;
|
||||
player.lock(1);
|
||||
player.getInventory().add(loot);
|
||||
player.getInventory().replace(EMPTY, item.getSlot());
|
||||
player.getPacketDispatch().sendMessage("You take " + input + " out of the bird's nest.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the random nest.
|
||||
* @return the nest.
|
||||
*/
|
||||
public static BirdNest getRandomNest(boolean wyson) {
|
||||
ChanceItem item = RandomFunction.getChanceItem(NESTS);
|
||||
for (BirdNest n : BirdNest.values()) {
|
||||
if (n.getNest() == item) {
|
||||
if (wyson && n == SEED) {
|
||||
return WYSON;
|
||||
} else if (!wyson && n == WYSON) {
|
||||
return SEED;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nest by the id.
|
||||
* @param nest the nest.
|
||||
* @return the nest.
|
||||
*/
|
||||
public static BirdNest forNest(final Item nest) {
|
||||
for (BirdNest n : values()) {
|
||||
if (n.getNest().getId() == nest.getId()) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nest.
|
||||
* @return The nest.
|
||||
*/
|
||||
public ChanceItem getNest() {
|
||||
return nest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the loot.
|
||||
* @return The loot.
|
||||
*/
|
||||
public ChanceItem[] getLoot() {
|
||||
return loot;
|
||||
}
|
||||
|
||||
/**
|
||||
* static-block to add nests.
|
||||
*/
|
||||
static {
|
||||
for (int i = 0; i < NESTS.length; i++) {
|
||||
NESTS[i] = values()[i].getNest();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
151
09HDscape-server/src/org/crandor/game/content/global/Bones.java
Normal file
151
09HDscape-server/src/org/crandor/game/content/global/Bones.java
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the type of bones.
|
||||
* @author Apache Ah64
|
||||
*/
|
||||
public enum Bones {
|
||||
|
||||
BONES(526, 4.5),
|
||||
WOLF_BONES(2859, 4.5),
|
||||
BURNST_BONES(528, 4.5),
|
||||
MONKEY_BONES(3183, 5),
|
||||
MONKEY_BONES2(3179, 5),
|
||||
BAT_BONES(530, 5.3),
|
||||
BIG_BONES(532, 15),
|
||||
JOGRE_BONES(3125, 15),
|
||||
ZOGRE_BONES(4812, 12.5),
|
||||
SHAIKAHAN_BONES(3123, 25),
|
||||
BABY_DRAGON_BONES(534, 30),
|
||||
WYVERN_BONES(6812, 50),
|
||||
DRAGON_BONES(536, 72),
|
||||
FAYRG(4830, 84),
|
||||
RAURG_BONES(4832, 96),
|
||||
DAGANNOTH(6729, 125),
|
||||
OURG_BONES(4834, 140),
|
||||
LAVA_DRAGON_BONES(14693, 85);
|
||||
|
||||
/**
|
||||
* Holds all bones.
|
||||
*/
|
||||
private static HashMap<Integer, Bones> bones = new HashMap<Integer, Bones>();
|
||||
|
||||
|
||||
/**
|
||||
* The bone item id.
|
||||
*/
|
||||
private int itemId;
|
||||
|
||||
/**
|
||||
* The experience given by burying the bone.
|
||||
*/
|
||||
private double experience;
|
||||
|
||||
/**
|
||||
* Construct a new {@code Bones} {@code Object}.
|
||||
* @param itemId The item id.
|
||||
* @param experience The experience given by burying the bone.
|
||||
*/
|
||||
private Bones(int itemId, double experience) {
|
||||
this.itemId = itemId;
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bone meal item.
|
||||
* @return the item.
|
||||
*/
|
||||
public Item getBoneMeal() {
|
||||
return new Item(4255 + ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bone experience given when you bury the bone.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bones for the bone meal.
|
||||
* @param itemId the item.
|
||||
* @return the bones.
|
||||
*/
|
||||
public static Bones forBoneMeal(int itemId) {
|
||||
for (Bones bone : Bones.values()) {
|
||||
if (bone.getBoneMeal().getId() == itemId) {
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the config value for the bone.
|
||||
* @param value the value.
|
||||
* @param hopper hopper.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static Bones forConfigValue(int value, boolean hopper) {
|
||||
for (Bones bone : Bones.values()) {
|
||||
if (bone.getConfigValue(hopper) == value) {
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the config value for the bone type.
|
||||
* @param hopper the hopper.
|
||||
* @return the value.
|
||||
*/
|
||||
public int getConfigValue(boolean hopper) {
|
||||
return ordinal() | (hopper ? 4 : 8) << 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bone ids.
|
||||
* @return the ids.
|
||||
*/
|
||||
public static int[] getArray() {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (int i : bones.keySet()) {
|
||||
list.add(i);
|
||||
}
|
||||
int[] array = new int[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bone.
|
||||
* @param itemId The item id.
|
||||
* @return The bone.
|
||||
*/
|
||||
public static Bones forId(int itemId) {
|
||||
return bones.get(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the bones.
|
||||
*/
|
||||
static {
|
||||
for (Bones bone : Bones.values()) {
|
||||
bones.put(bone.itemId, bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.content.skill.member.slayer.Tasks;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.portal.Perks;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.world.repository.Repository;
|
||||
import org.crandor.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* The BossKillcounter keeps track of the amount of bosses the player has slain.
|
||||
* addtoKillcount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss.
|
||||
* @author Splinter
|
||||
*/
|
||||
public enum BossKillCounter {
|
||||
|
||||
|
||||
/* ORDINAL BOUND */
|
||||
KING_BLACK_DRAGON(new int[] { 50 }, "King Black Dragon", 14649),
|
||||
BORK(new int[] { 7133, 7134 }, "Bork", -1),
|
||||
DAGANNOTH_SUPREME(new int[] { 2881 }, "Dagannoth Supreme", 14639),
|
||||
DAGANNOTH_PRIME(new int[] { 2882 }, "Dagannoth Prime", 14640),
|
||||
DAGANNOTH_REX(new int[] { 2883 }, "Dagannoth Rex", 14641),
|
||||
CHAOS_ELEMENTAL(new int[] { 3200 }, "Chaos Elemental", 14638),
|
||||
GIANT_MOLE(new int[] { 3340 }, "Giant Mole", 14642),
|
||||
SARADOMIN(new int[] { 6247 }, "Commander Zilyana", 14647),
|
||||
ZAMORAK(new int[] { 6203 }, "K'ril Tsutsaroth", 14648),
|
||||
BANDOS(new int[] { 6260 }, "General Graardor", 14646),
|
||||
ARMADYL(new int[] { 6222 }, "Kree'arra", 14645),
|
||||
JAD(new int[] { 2745 }, "Tz-Tok Jad", 14828),
|
||||
KALPHITE_QUEEN(new int[] { 1160 }, "Kalphite Queen", 14650),
|
||||
CORPOREAL_BEAST(new int[] { 8133 }, "Corporeal Beast", 14653),
|
||||
CALLISTO(new int[] { 8610 }, "Callisto", 14658),
|
||||
SCORPIA(new int[] { 8611 }, "Scorpia", 14661),
|
||||
VENENATIS(new int[] { 8612 }, "Venenatis", 14657),
|
||||
VETION(new int[] { 8613 }, "Vet'ion", 14659),
|
||||
KRAKEN(new int[] { 8614 }, "Cave Kraken", 14651),
|
||||
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* The npcs that can increase the killcounter
|
||||
*/
|
||||
private final int[] npc;
|
||||
|
||||
/**
|
||||
* The name of the NPC, to be displayed as a sendMessage
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The item ID of the pet relating to the boss.
|
||||
*/
|
||||
private final int petId;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BossKillCounter} {@code Object}.
|
||||
* @param npc the npc.
|
||||
* @param data the attribute data
|
||||
* @param name the npc's string name
|
||||
*/
|
||||
BossKillCounter(final int[] npc, final String name, final int petId) {
|
||||
this.npc = npc;
|
||||
this.name = name;
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npc.
|
||||
* @return The npc.
|
||||
*/
|
||||
public int[] getNpc() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NPC's name
|
||||
* @return their name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the petId
|
||||
* @return The petId
|
||||
*/
|
||||
public int getPetId() {
|
||||
return petId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type for the npc.
|
||||
* @param npc the npc.
|
||||
* @return the BossKillcounter
|
||||
*/
|
||||
public static BossKillCounter forNPC(final int npc) {
|
||||
for (BossKillCounter kc : BossKillCounter.values()) {
|
||||
for (int i : kc.getNpc()) {
|
||||
if (npc == i) {
|
||||
return kc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the player's killcount for that particular boss.
|
||||
* @param killer The player who killed the npc
|
||||
* @param npcid the ID of the npc that just died
|
||||
*/
|
||||
public static void addtoKillcount(Player killer, int npcid) {
|
||||
if (killer == null) {
|
||||
return;
|
||||
}
|
||||
BossKillCounter boss = BossKillCounter.forNPC(npcid);
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()]++;
|
||||
killer.getPacketDispatch().sendMessage("Your " + boss.getName() + " killcount is now: <col=ff0000>" + killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()] + "</col>.");
|
||||
addBossPet(killer, npcid, boss);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player the pet if they killed a certain boss.
|
||||
* The chance by default is 1/5000. This rate lowers to 1/2200 if the <GlobalEvents> for Boss Pets is active.
|
||||
* Note: Not all bosses have pet versions of themselves.
|
||||
*/
|
||||
private static void addBossPet(Player killer, int npcid, BossKillCounter boss){
|
||||
if(boss.getPetId() == -1){ //The boss does not have a pet version.
|
||||
return;
|
||||
}
|
||||
int number = 5000;
|
||||
if (npcid == 2745) {
|
||||
number = 200;
|
||||
if (Tasks.forValue(killer.getSlayer().getTask()) == Tasks.JAD) {
|
||||
number = 100;
|
||||
}
|
||||
} else if (npcid == 3200) {
|
||||
number = 300;
|
||||
}
|
||||
int rand = RandomFunction.random(killer.hasPerk(Perks.PET_BEFRIENDER) ? number / 2 : number);
|
||||
if(rand == 10){
|
||||
for (int i = 0; i < killer.getFamiliarManager().getInsuredPets().size(); i++) {
|
||||
if (killer.getFamiliarManager().getInsuredPets().get(i).getBabyItemId() == boss.getPetId()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(killer.getFamiliarManager().hasFamiliar() && killer.getInventory().freeSlots() < 1){
|
||||
return;
|
||||
}
|
||||
if(!killer.getFamiliarManager().hasFamiliar()){
|
||||
killer.getFamiliarManager().summon(new Item(boss.getPetId()), true);
|
||||
killer.sendNotificationMessage("You have a funny feeling like you're being followed.");
|
||||
} else if (killer.getInventory().freeSlots() > 0){
|
||||
killer.getInventory().add(new Item(boss.getPetId(), 1));
|
||||
killer.sendNotificationMessage("You feel something weird sneaking into your backpack.");
|
||||
}
|
||||
Repository.sendNews(killer.getUsername()+" now commands a miniature "+(boss.equals(CORPOREAL_BEAST) ? "Dark core" : boss.getName())+"!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the player's Barrows chest counter.
|
||||
* @param player the player
|
||||
*/
|
||||
public static void addtoBarrowsCount(Player player) {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
player.getSavedData().getGlobalData().setBarrowsLoots(player.getSavedData().getGlobalData().getBarrowsLoots() + 1);
|
||||
player.getPacketDispatch().sendMessage("Your Barrows chest count is: <col=ff0000>" + player.getSavedData().getGlobalData().getBarrowsLoots() + "</col>.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a dye.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum Dyes {
|
||||
RED(new Item(1763)), YELLOW(new Item(1765)), BLUE(new Item(1767)), ORANGE(new Item(1769)), GREEN(new Item(1771)), PURPLE(new Item(1773)), PINK(new Item(6955));
|
||||
|
||||
/**
|
||||
* The dye item.
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Dyes} {@code Object}.
|
||||
* @param item the item.
|
||||
*/
|
||||
private Dyes(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dye for the item.
|
||||
* @param item the item.
|
||||
* @return the dye.
|
||||
*/
|
||||
public static Dyes forItem(Item item) {
|
||||
for (Dyes d : values()) {
|
||||
if (d.getItem().getId() == item.getId()) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.portal.Perks;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
import org.crandor.game.world.update.flag.context.Graphics;
|
||||
|
||||
/**
|
||||
* Represents an enchanted jewellery.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum EnchantedJewellery {
|
||||
RING_OF_SLAYING(new String[] { "Slayer Tower.", "Fremmenik Slayer Dungeon.", "Pollniveach Slayer Dungeon.", "Nowhere." }, new Location[] { Location.create(3429, 3533, 0), Location.create(2793, 3615, 0), Location.create(3313, 2960, 0) }, true, 13281, 13282, 13283, 13284, 13285, 13286, 13287, 13288),
|
||||
RING_OF_DUELING(new String[] { "Al Kharid Duel Arena.", "Castle Wars Arena.", "Nowhere." }, new Location[] { Location.create(3314, 3235, 0), Location.create(2442, 3089, 0) }, true, 2552, 2554, 2556, 2558, 2560, 2562, 2564, 2566),
|
||||
AMULET_OF_GLORY(new String[] { "Edgeville", "Karamja", "Draynor Village", "Al-Kharid", "Nowhere." }, new Location[] { Location.create(3087, 3495, 0), Location.create(2919, 3175, 0), Location.create(3104, 3249, 0), Location.create(3304, 3124, 0) }, 1712, 1710, 1708, 1706, 1704),
|
||||
AMULET_OF_GLORY_T(new String[] { "Edgeville", "Karamja", "Draynor Village", "Al-Kharid", "Nowhere." }, new Location[] { Location.create(3087, 3495, 0), Location.create(2919, 3175, 0), Location.create(3081, 3250, 0), Location.create(3304, 3124, 0) }, 10354, 10356, 10358, 10360, 10362),
|
||||
GAMES_NECKLACE(new String[] { "Burthorpe", "Barbarian Assault", "Clan Wars", "Bounty Hunter", "Corporeal Beast" }, new Location[] { Location.create(2899, 3563, 0), Location.create(2520, 3571, 0), Location.create(3266, 3686, 0), Location.create(3179, 3685, 0), Location.create(2885, 4372, 2) }, true, 3853, 3855, 3857, 3859, 3861, 3863, 3865, 3867),
|
||||
DIGSITE_PENDANT(new String[] {}, new Location[] { Location.create(3342, 3445, 0) }, true, 11194, 11193, 11192, 11191, 11190),
|
||||
COMBAT_BRACELET(new String[] { "Champions' Guild", "Monastery", "Ranging Guild", "Warriors' Guild", "Nowhere." }, new Location[] { Location.create(3191, 3365, 0), Location.create(3052, 3472, 0), Location.create(2657, 3439, 0), Location.create(2878, 3546, 0) }, 11118, 11120, 11122, 11124, 11126),
|
||||
SKILLS_NECKLACE(new String[] { "Fishing Guild", "Mining Guild", "Crafting Guild", "Cooking Guild", "Nowhere." }, new Location[] { Location.create(2611, 3392, 0), Location.create(3016, 3338, 0), Location.create(2933, 3290, 0), Location.create(3143, 3442, 0) }, 11105, 11107, 11109, 11111, 11113);
|
||||
|
||||
/**
|
||||
* Represents the teleport animation.
|
||||
*/
|
||||
private static final Animation ANIMATION = new Animation(714);
|
||||
|
||||
/**
|
||||
* Represents the graphics to use.
|
||||
*/
|
||||
private static final Graphics GRAPHICS = new Graphics(308, 100, 50);
|
||||
|
||||
/**
|
||||
* Represents the charge numbers.
|
||||
*/
|
||||
private static final char[] NUMBERS = new char[] { '1', '2', '3', '4', '5', '6', '7', '8' };
|
||||
|
||||
/**
|
||||
* Represents the teleport options.
|
||||
*/
|
||||
private final String[] options;
|
||||
|
||||
/**
|
||||
* Represents the locations.
|
||||
*/
|
||||
private final Location[] locations;
|
||||
|
||||
/**
|
||||
* Represents the ids of the jewellery.
|
||||
*/
|
||||
private final int[] ids;
|
||||
|
||||
/**
|
||||
* Represents if it crumbles away into nothing.
|
||||
*/
|
||||
private final boolean crumble;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EnchantedJewelleryPlugin} {@code Object}.
|
||||
* @param options the options.
|
||||
* @param locations the locations.
|
||||
* @parma crumble if it crumbles.
|
||||
* @param ids the ids.
|
||||
*/
|
||||
EnchantedJewellery(final String[] options, final Location[] locations, final boolean crumble, final int... ids) {
|
||||
this.options = options;
|
||||
this.locations = locations;
|
||||
this.ids = ids;
|
||||
this.crumble = crumble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EnchantedJewelleryPlugin} {@code Object}.
|
||||
* @param options the options.
|
||||
* @param locations the locations.
|
||||
* @param ids the ids.
|
||||
*/
|
||||
EnchantedJewellery(final String[] options, final Location[] locations, final int... ids) {
|
||||
this(options, locations, false, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to teleport the player to the desired location.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
* @param index the index.
|
||||
* @param operate If the player is operating.
|
||||
*/
|
||||
public void use(final Player player, final Item item, final int index, boolean operate) {
|
||||
if ((index + 1) == getIds().length || item.getSlot() < 0) {
|
||||
return;
|
||||
}
|
||||
if (index > getLocations().length - 1) {
|
||||
return;
|
||||
}
|
||||
int itemIndex = getItemIndex(item);
|
||||
Item replace = item;
|
||||
if (!isLast(itemIndex)) {
|
||||
if (!(isCrumble() && itemIndex == getIds().length - 1)) {
|
||||
replace = getReplace(getNext(itemIndex));
|
||||
}
|
||||
} else {
|
||||
if (!isCrumble()) {
|
||||
replace = getReplace(getIds()[getIds().length - 1]);
|
||||
}
|
||||
}
|
||||
if (index > getLocations().length - 1) {
|
||||
return;
|
||||
}
|
||||
if (!operate && !player.getInventory().containsItem(item)) {
|
||||
player.sendMessage("Ooops, you don't have it anymore ;)");
|
||||
return;
|
||||
} else if (operate && !player.getEquipment().containsItem(item)) {
|
||||
player.sendMessage("Ooops, you don't have it anymore ;)");
|
||||
return;
|
||||
}
|
||||
if (player.getDetails().getShop().hasPerk(Perks.CHARGE_BEFRIENDER)) {
|
||||
teleport(player, 0, item, getLocation(index));
|
||||
return;
|
||||
}
|
||||
if (teleport(player, itemIndex, replace, getLocation(index))) {
|
||||
if (!isLast(itemIndex) && !(isCrumble() && itemIndex == getIds().length - 1)) {
|
||||
if (operate) {
|
||||
player.getEquipment().replace(replace, item.getSlot());
|
||||
} else {
|
||||
player.getInventory().replace(replace, item.getSlot());
|
||||
}
|
||||
} else {
|
||||
if (isCrumble()) {
|
||||
if (operate) {
|
||||
player.getEquipment().replace(null, item.getSlot());
|
||||
} else {
|
||||
if(item.getName().contains("slaying")){
|
||||
player.getInventory().replace(new Item(4155, 1), item.getSlot());
|
||||
player.sendMessage("Your Ring of Slaying reverts back into a regular enchanted gem.");
|
||||
} else {
|
||||
player.getInventory().replace(null, item.getSlot());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to teleport to a location.
|
||||
* @param player the player.
|
||||
* @param itemIndex the old item index.
|
||||
* @param item the item.
|
||||
* @param location the location.
|
||||
*/
|
||||
private boolean teleport(final Player player, final int itemIndex, final Item item, final Location location) {
|
||||
if (player.isTeleBlocked()) {
|
||||
player.sendMessage("A magical force has stopped you from teleporting.");
|
||||
return false;
|
||||
}
|
||||
if (!player.getZoneMonitor().teleport(1, item)) {
|
||||
return false;
|
||||
}
|
||||
player.lock();
|
||||
player.visualize(ANIMATION, GRAPHICS);
|
||||
player.getImpactHandler().setDisabledTicks(4);
|
||||
GameWorld.submit(new Pulse(4, player) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
player.unlock();
|
||||
player.getProperties().setTeleportLocation(location);
|
||||
if (!player.getDetails().getShop().hasPerk(Perks.CHARGE_BEFRIENDER)) {
|
||||
player.getPacketDispatch().sendMessage(isCrumble() && itemIndex == getIds().length - 1 || isLast(getItemIndex(item)) ? "<col=7f03ff>You use your " + getNameType(item) + "'s last charge." : "<col=7f03ff>Your " + getName(item) + " has " + Integer.parseInt(getCharges(item)) + " use" + (Integer.parseInt(getCharges(item)) > 1 ? "s" : "") + " left.");
|
||||
}
|
||||
player.getAnimator().reset();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the charges of an item.
|
||||
* @param item the item.
|
||||
* @return the charges.
|
||||
*/
|
||||
public static String getCharges(Item item) {
|
||||
String[] tokens = item.getName().replace("(t", "(").replace("(", " ").replace(")", "").split(" ");
|
||||
return tokens[tokens.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the replacement item.
|
||||
* @param id the id.
|
||||
* @return the item.
|
||||
*/
|
||||
public Item getReplace(int id) {
|
||||
return new Item(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @param item the item.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName(Item item) {
|
||||
String name = item.getName().toLowerCase().replace("(t", "(").replace("(", "").replace(")", "");
|
||||
for (char number : NUMBERS) {
|
||||
name = name.replace(number, '/');
|
||||
}
|
||||
return name.trim().replace("/", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name type.
|
||||
* @param item the item.
|
||||
* @return
|
||||
*/
|
||||
public String getNameType(Item item) {
|
||||
return this == GAMES_NECKLACE ? "games necklace" : this == DIGSITE_PENDANT ? "necklace" : this == COMBAT_BRACELET ? "bracelet" : this == SKILLS_NECKLACE ? "necklace" : item.getName().toLowerCase().split(" ")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the index is last.
|
||||
* @param index the index.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isLast(int index) {
|
||||
return !isCrumble() ? index == (ids.length - 1) : index == ids.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next index.
|
||||
* @param index the index.
|
||||
* @return the new id
|
||||
*/
|
||||
public int getNext(int index) {
|
||||
return ids[index + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location.
|
||||
* @param index the index.
|
||||
* @return the location.
|
||||
*/
|
||||
public Location getLocation(int index) {
|
||||
if (index > locations.length) {
|
||||
index = locations.length - 1;
|
||||
}
|
||||
return locations[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the options.
|
||||
* @return The options.
|
||||
*/
|
||||
public String[] getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the locations.
|
||||
* @return The locations.
|
||||
*/
|
||||
public Location[] getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids.
|
||||
* @return The ids.
|
||||
*/
|
||||
public int[] getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public boolean isCrumble() {
|
||||
return crumble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchanted jewellery.
|
||||
* @param item the item.
|
||||
* @return {@code EnchantedJewellery}.
|
||||
*/
|
||||
public static EnchantedJewellery forItem(final Item item) {
|
||||
for (EnchantedJewellery jewellery : values()) {
|
||||
for (int i : jewellery.getIds()) {
|
||||
if (i == item.getId()) {
|
||||
return jewellery;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index.
|
||||
* @param item the item.
|
||||
* @return the item index.
|
||||
*/
|
||||
public int getItemIndex(Item item) {
|
||||
for (int i = 0; i < getIds().length; i++) {
|
||||
if (getIds()[i] == item.getId()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* A god book.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum GodBook {
|
||||
HOLY_BOOK("Holy Book of Saradomin", new Item(3840), new Item(3839), new Item[] { new Item(1718) }, new Item(3827), new Item(3828), new Item(3829), new Item(3830)), BOOK_OF_BALANCE("Guthix's Book of Balance", new Item(3844), new Item(3843), new Item[] { new Item(1718), new Item(1724) }, new Item(3835), new Item(3836), new Item(3837), new Item(3838)), UNHOLY_BOOK("Unholy Book of Zamorak", new Item(3842), new Item(3841), new Item[] { new Item(1724) }, new Item(3831), new Item(3832), new Item(3833), new Item(3834));
|
||||
|
||||
/**
|
||||
* The books name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The god book.
|
||||
*/
|
||||
private final Item book;
|
||||
|
||||
/**
|
||||
* The damaged book.
|
||||
*/
|
||||
private final Item damagedBook;
|
||||
|
||||
/**
|
||||
* The items the book can bless.
|
||||
*/
|
||||
private final Item[] blessItems;
|
||||
|
||||
/**
|
||||
* The pages of items.
|
||||
*/
|
||||
private final Item[] pages;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GodBook} {@code Object}
|
||||
* @param book the book.
|
||||
* @param damagedBook the damged book.
|
||||
* @param name the name of the book.
|
||||
* @param blessItem the item.
|
||||
* @param pages the pages.
|
||||
*/
|
||||
private GodBook(String name, Item book, Item damagedBook, Item[] blessedItems, Item... pages) {
|
||||
this.book = book;
|
||||
this.damagedBook = damagedBook;
|
||||
this.name = name;
|
||||
this.blessItems = blessedItems;
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the god book for the item.
|
||||
* @param item the item.
|
||||
* @param damaged Flagged for the damaged book.
|
||||
* @return {@code GodBook} the god book.
|
||||
*/
|
||||
public static GodBook forItem(Item item, boolean damaged) {
|
||||
for (GodBook book : values()) {
|
||||
if ((!damaged ? book.getBook().getId() : book.getDamagedBook().getId()) == item.getId()) {
|
||||
return book;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has this god book.
|
||||
* @param player the player.
|
||||
* @param both if we are checking for the damaged/good.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasGodBook(Player player, boolean both) {
|
||||
return player.getInventory().containsItems(both ? new Item[] { book, damagedBook } : new Item[] { book });
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a good book based on the page id.
|
||||
* @param page the page.
|
||||
* @return the respective god book.
|
||||
*/
|
||||
public static GodBook forPage(Item page) {
|
||||
for (GodBook book : values()) {
|
||||
for (Item i : book.getPages()) {
|
||||
if (i.getId() == page.getId()) {
|
||||
return book;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a page into the book.
|
||||
* @param player the player.
|
||||
* @param book the book.
|
||||
* @param page the page.
|
||||
*/
|
||||
public void insertPage(Player player, Item book, Item page) {
|
||||
if (hasPage(player, book, page)) {
|
||||
player.sendMessage("The book already has that page.");
|
||||
return;
|
||||
}
|
||||
if (player.getInventory().remove(new Item(page.getId(), 1))) {
|
||||
setPageHash(player, book, getPageIndex(page));
|
||||
player.sendMessage("You add the page to the book...");
|
||||
if (isComplete(player, book)) {
|
||||
player.getSavedData().getGlobalData().setGodPages(new boolean[4]);
|
||||
player.getSavedData().getGlobalData().setGodBook(-1);
|
||||
player.getInventory().replace(this.book, book.getSlot());
|
||||
player.getSavedData().getGlobalData().setGodBook(this);
|
||||
player.sendMessage("The book is now complete!");
|
||||
String message = this == UNHOLY_BOOK ? "unholy symbols" : this == HOLY_BOOK ? "holy symbols" : "unblessed holy symbols";
|
||||
player.sendMessage("You can now use it to bless " + (message) + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this item is a page of the book.
|
||||
* @param asItem the item.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isPage(Item asItem) {
|
||||
for (Item item : pages) {
|
||||
if (item.getId() == asItem.getId()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a book is complete.
|
||||
* @param book the book.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isComplete(Player player, Item book) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!hasPage(player, book, i + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a page in a book.
|
||||
* @param book the book.
|
||||
* @param page the page.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasPage(Player player, Item book, Item page) {
|
||||
return hasPage(player, book, getPageIndex(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a page hash.
|
||||
* @param book the book.
|
||||
* @param pageId the page Id.
|
||||
*/
|
||||
public void setPageHash(Player player, Item book, int pageId) {
|
||||
// int hash = getHash(book);
|
||||
// hash |= hash | (1 << pageId);
|
||||
// book.setCharge(1000 + hash);
|
||||
player.getSavedData().getGlobalData().getGodPages()[pageId - 1] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the book has a page.
|
||||
* @param book the book.
|
||||
* @param pageId the id of the page.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasPage(Player player, Item book, int pageId) {
|
||||
// return (getHash(book) & (1 << pageId)) != 0;
|
||||
return player.getSavedData().getGlobalData().getGodPages()[pageId - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash.
|
||||
* @param book the book.
|
||||
* @return the hash.
|
||||
*/
|
||||
public int getHash(Item book) {
|
||||
return book.getCharge() - 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page index.
|
||||
* @param page the page.
|
||||
* @return the index.
|
||||
*/
|
||||
public int getPageIndex(Item page) {
|
||||
for (int i = 0; i < pages.length; i++) {
|
||||
if (pages[i].getId() == page.getId()) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the god book.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the book.
|
||||
* @return the book
|
||||
*/
|
||||
public Item getBook() {
|
||||
return book;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damagedBook.
|
||||
* @return the damagedBook
|
||||
*/
|
||||
public Item getDamagedBook() {
|
||||
return damagedBook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pages.
|
||||
* @return the pages
|
||||
*/
|
||||
public Item[] getPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blessItem.
|
||||
* @return the blessItem
|
||||
*/
|
||||
public Item[] getBlessItem() {
|
||||
return blessItems;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.content.dialogue.DialogueAction;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.GroundItem;
|
||||
import org.crandor.game.node.item.GroundItemManager;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.node.object.GameObject;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
import org.crandor.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* A god type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum GodType {
|
||||
SARADOMIN(new Item(2412), new Item(2415), 2873, 913, "The cape disappears in a flash of light as it touches the ground."), GUTHIX(new Item(2413), new Item(2416), 2875, 914, "The cape disintegrates as it touches the earth."), ZAMORAK(new Item(2414), new Item(2417), 2874, 912, "The cape ignites and burns up as it touches the ground.");
|
||||
|
||||
/**
|
||||
* The cape.
|
||||
*/
|
||||
private final Item cape;
|
||||
|
||||
/**
|
||||
* The staff.
|
||||
*/
|
||||
private final Item staff;
|
||||
|
||||
/**
|
||||
* The statue id.
|
||||
*/
|
||||
private final int statueId;
|
||||
|
||||
/**
|
||||
* The npc id.
|
||||
*/
|
||||
private final int npcId;
|
||||
|
||||
/**
|
||||
* The drop message.
|
||||
*/
|
||||
private final String dropMessage;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GodCape} {@code Object}.
|
||||
* @param cape the cape.
|
||||
* @param staff the staff.
|
||||
* @param statueId the id.
|
||||
* @param npc id the id.
|
||||
* @param drop message the drop message.
|
||||
*/
|
||||
private GodType(Item cape, Item staff, int statueId, int npcId, String dropMessage) {
|
||||
this.cape = cape;
|
||||
this.staff = staff;
|
||||
this.statueId = statueId;
|
||||
this.npcId = npcId;
|
||||
this.dropMessage = dropMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prays at a statue.
|
||||
* @param player the player.
|
||||
* @param statue the statue.
|
||||
*/
|
||||
public void pray(final Player player, final GameObject statue) {
|
||||
if (hasAny(player)) {
|
||||
player.lock(3);
|
||||
player.animate(Animation.create(645));
|
||||
player.sendMessages("You kneel and begin to chant to " + getName() + "...", "...but there is no response.");
|
||||
return;
|
||||
}
|
||||
player.getDialogueInterpreter().sendDialogue("You kneel and begin to chant to " + getName() + "...");
|
||||
player.getDialogueInterpreter().addAction(new DialogueAction() {
|
||||
|
||||
@Override
|
||||
public void handle(final Player player, int buttonId) {
|
||||
player.lock();
|
||||
player.animate(Animation.create(645));
|
||||
GameWorld.submit(new Pulse(3, player) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
Location loc = statue.getLocation().transform(0, -1, 0);
|
||||
GroundItem g = GroundItemManager.get(cape.getId(), loc, player);
|
||||
if (g == null) {
|
||||
GroundItemManager.create(cape, loc, player);
|
||||
}
|
||||
player.getPacketDispatch().sendPositionedGraphic(86, 0, 0, loc);
|
||||
player.unlock();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the god type by the statue id.
|
||||
* @param object the object.
|
||||
* @return the type.
|
||||
*/
|
||||
public static GodType forObject(int object) {
|
||||
for (GodType type : values()) {
|
||||
if (type.getStatueId() == object) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if they have a god cape & which one.
|
||||
* @param player the player.
|
||||
* @param if invy check only.
|
||||
* @return {@code GodCape} the cape.
|
||||
*/
|
||||
public static GodType getCape(Player player, boolean invyOnly) {
|
||||
for (GodType cape : values()) {
|
||||
if (invyOnly ? player.getInventory().containsItems(cape.getCape()) : (player.getEquipment().containsItem(cape.getCape()) || player.getInventory().containsItems(cape.getCape()))) {
|
||||
return cape;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if they have a god cape.
|
||||
* @param player the player.
|
||||
* @return the cape.
|
||||
*/
|
||||
public static GodType getCape(Player player) {
|
||||
return getCape(player, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a god cape type by the id.
|
||||
* @param cape the cape.
|
||||
* @return the cape.
|
||||
*/
|
||||
public static GodType forCape(final Item cape) {
|
||||
for (GodType g : values()) {
|
||||
if (g.getCape().getId() == cape.getId()) {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is friendly.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isFriendly(Player player) {
|
||||
return player.getEquipment().containsItem(cape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mage type.
|
||||
* @param id the id.
|
||||
* @return te type.
|
||||
*/
|
||||
public static GodType forId(int id) {
|
||||
for (GodType type : values()) {
|
||||
if (type.getNpcId() == id) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has any capes.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean hasAny(Player player) {
|
||||
for (GodType t : values()) {
|
||||
if (player.hasItem(t.getCape())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cape.
|
||||
* @return The cape.
|
||||
*/
|
||||
public Item getCape() {
|
||||
return cape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the staff.
|
||||
* @return The staff.
|
||||
*/
|
||||
public Item getStaff() {
|
||||
return staff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the statueId.
|
||||
* @return The statueId.
|
||||
*/
|
||||
public int getStatueId() {
|
||||
return statueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dropMessage.
|
||||
* @return The dropMessage.
|
||||
*/
|
||||
public String getDropMessage() {
|
||||
return dropMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npcId.
|
||||
* @return The npcId.
|
||||
*/
|
||||
public int getNpcId() {
|
||||
return npcId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return StringUtils.formatDisplayName(name().toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents an experience lamp.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum Lamps {
|
||||
GENIE_LAMP(new Item(2528), 10),
|
||||
STRONGHOLD_LAMP(new Item(4447), 500),
|
||||
K_ACHIEVEMENT_1(new Item(11137), 1000),
|
||||
K_ACHIEVEMENT_2(new Item(11139), 5000),
|
||||
K_ACHIEVEMENT_3(new Item(11141), 10000),
|
||||
V_ACHIEVEMENT_1(new Item(11185), 2500, 30),
|
||||
V_ACHIEVEMENT_2(new Item(11186), 7500, 40),
|
||||
V_ACHIEVEMENT_3(new Item(11187), 15000, 50),
|
||||
ULTRA_LAMP(new Item(14820), 30000, 30);
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* The experience gained.
|
||||
*/
|
||||
private final int experience;
|
||||
|
||||
/**
|
||||
* The level requirement.
|
||||
*/
|
||||
private final int levelRequirement;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Lamps} {@code Object}
|
||||
* @param item the item.
|
||||
* @param experience the exp.
|
||||
* @param levelRequirement the level requirement to meet.
|
||||
*/
|
||||
private Lamps(Item item, int experience, int levelRequirement) {
|
||||
this.item = item;
|
||||
this.experience = experience;
|
||||
this.levelRequirement = levelRequirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Lamps} {@code Object}
|
||||
* @param item the item.
|
||||
* @param experience the exp.
|
||||
*/
|
||||
private Lamps(Item item, int experience) {
|
||||
this(item, experience, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lamp by the item.
|
||||
* @param item the item.
|
||||
* @return the lamp.
|
||||
*/
|
||||
public static Lamps forItem(Item item) {
|
||||
for (Lamps l : values()) {
|
||||
if (l.getItem().getId() == item.getId()) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return the item
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mod.
|
||||
* @return the mod
|
||||
*/
|
||||
public int getExp() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the levelRequirement.
|
||||
* @return the levelRequirement
|
||||
*/
|
||||
public int getLevelRequirement() {
|
||||
return levelRequirement;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a light source.
|
||||
* @author Vexia
|
||||
* @author Emperor
|
||||
*/
|
||||
public enum LightSource {
|
||||
CANDLE(1, new Item(36, 1), new Item(33, 1), true, 98),
|
||||
BLACK_CANDLE(1, new Item(38, 1), new Item(32, 1), true, 98),
|
||||
TORCH(1, new Item(596, 1), new Item(594, 1), true, 98),
|
||||
CANDLE_LANTERN(4, new Item(4527, 1), new Item(4531, 1), false, 98),
|
||||
OIL_LAMP(12, new Item(4522, 1), new Item(4524, 1), true, 97),
|
||||
OIL_LANTERN(26, new Item(4535, 1), new Item(4539, 1), false, 97),
|
||||
BULLSEYE_LANTERN(49, new Item(4548, 1), new Item(4550, 1), false, -1),
|
||||
SAPPHIRE_LANTERN(49, new Item(4701, 1), new Item(4702, 1), false, -1),
|
||||
EMERALD_LANTERN(49, new Item(9064, 1), new Item(9065, 1), false, -1),
|
||||
MINING_HELMET(65, new Item(5014, 1), new Item(5013, 1), false, 97);
|
||||
|
||||
/**
|
||||
* Represents the level required.
|
||||
*/
|
||||
private int level;
|
||||
|
||||
/**
|
||||
* Represents the raw item.
|
||||
*/
|
||||
private Item raw;
|
||||
|
||||
/**
|
||||
* Represents the product.
|
||||
*/
|
||||
private Item product;
|
||||
|
||||
/**
|
||||
* If the light source is open (eg. candles, torches, ...).
|
||||
*/
|
||||
private final boolean open;
|
||||
|
||||
/**
|
||||
* The interface id.
|
||||
*/
|
||||
private final int interfaceId;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LightSource} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param raw the raw.
|
||||
* @param product the product.
|
||||
* @param open If it's an open light source.
|
||||
* @param interfaceId The overlay interface id to display.
|
||||
*/
|
||||
LightSource(int level, Item raw, Item product, boolean open, int interfaceId) {
|
||||
this.level = level;
|
||||
this.raw = raw;
|
||||
this.product = product;
|
||||
this.open = open;
|
||||
this.interfaceId = interfaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has a lit light source.
|
||||
* @param player The player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean hasActiveLightSource(Player player) {
|
||||
if (SkillcapePerks.hasSkillcapePerk(player, SkillcapePerks.FIREMAKING)) {
|
||||
return true;
|
||||
}
|
||||
return getActiveLightSource(player) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the light source used by the player.
|
||||
* @param player The player.
|
||||
* @return The light source object, or null if the player didn't have any
|
||||
* light source.
|
||||
*/
|
||||
public static LightSource getActiveLightSource(Player player) {
|
||||
LightSource source;
|
||||
for (Item item : player.getInventory().toArray()) {
|
||||
if (item != null && (source = forProductId(item.getId())) != null) {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
for (Item item : player.getEquipment().toArray()) {
|
||||
if (item != null && (source = forProductId(item.getId())) != null) {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
if (SkillcapePerks.hasSkillcapePerk(player, SkillcapePerks.FIREMAKING)) {
|
||||
return OIL_LANTERN;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the light source by the id.
|
||||
* @param id the id.
|
||||
* @return the source.
|
||||
*/
|
||||
public static LightSource forId(int id) {
|
||||
for (LightSource light : LightSource.values()) {
|
||||
if (light.raw.getId() == id) {
|
||||
return light;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the light souce by the product id.
|
||||
* @param id the id.
|
||||
* @return the light source.
|
||||
*/
|
||||
public static LightSource forProductId(int id) {
|
||||
for (LightSource light : LightSource.values()) {
|
||||
if (light.product.getId() == id) {
|
||||
return light;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the strength of the light source (1=dim, 2=medium, 3=bright).
|
||||
* @return The strength.
|
||||
*/
|
||||
public int getStrength() {
|
||||
switch (interfaceId) {
|
||||
case 97:
|
||||
return 1;
|
||||
case 98:
|
||||
return 2;
|
||||
case -1:
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the light source.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return super.name().toLowerCase().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw item.
|
||||
* @return the raw.
|
||||
*/
|
||||
public Item getRaw() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product.
|
||||
* @return the product.
|
||||
*/
|
||||
public Item getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return the level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the open.
|
||||
* @return The open.
|
||||
*/
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interfaceId.
|
||||
* @return The interfaceId.
|
||||
*/
|
||||
public int getInterfaceId() {
|
||||
return interfaceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids of the raw items.
|
||||
* @return The raw item ids.
|
||||
*/
|
||||
public static int[] getRawIds() {
|
||||
int array[] = new int[LightSource.values().length];
|
||||
for (int i = 0; i < LightSource.values().length -1; i++) {
|
||||
array[i] = LightSource.values()[i].getRaw().getId();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents the repair item type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum RepairItem {
|
||||
BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0), BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0), IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0), IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0), STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0), STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14), BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10), MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18), MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43), ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43), ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107), RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427), RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100), DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800);
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* The product item.
|
||||
*/
|
||||
private final Item product;
|
||||
|
||||
/**
|
||||
* The cost of the money to repair.
|
||||
*/
|
||||
private final int cost;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BobRepairItem} {@code Object}.
|
||||
* @param item the item.
|
||||
* @param product the product.
|
||||
* @param cost the cost.
|
||||
*/
|
||||
RepairItem(Item item, Item product, int cost) {
|
||||
this.item = item;
|
||||
this.product = product;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product.
|
||||
* @return The product.
|
||||
*/
|
||||
public Item getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost.
|
||||
* @return The cost.
|
||||
*/
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reapir item by the id.
|
||||
* @param id the id.
|
||||
* @return the repair item.
|
||||
*/
|
||||
public static RepairItem forId(int id) {
|
||||
for (RepairItem item : RepairItem.values())
|
||||
if (item.item.getId() == id)
|
||||
return item;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.container.Container;
|
||||
import org.crandor.game.content.dialogue.FacialExpression;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a utility class for purchasing skillcapes.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class Skillcape {
|
||||
|
||||
/**
|
||||
* Represents the amount needed to purchase a cape.
|
||||
*/
|
||||
private static final Item COINS = new Item(995, 99000);
|
||||
|
||||
/**
|
||||
* Represents the skillcapes to purchase.
|
||||
*/
|
||||
public static final int[] SKILLCAPES = { 9747, 9753, 9750, 9768, 9756, 9759, 9762, 9801, 9807, 9783, 9798, 9804, 9780, 9795, 9792, 9774, 9771, 9777, 9786, 9810, 9765, 9948, 9789, 12169 };
|
||||
|
||||
/**
|
||||
* Method used to purchase a cape of accomplisment.
|
||||
* @param player the player.
|
||||
* @param skill the skill.
|
||||
* @return {@code True} if purchased.
|
||||
*/
|
||||
public static boolean purchase(final Player player, final int skill) {
|
||||
if (!isMaster(player, skill)) {
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().freeSlots() < 2) {
|
||||
player.getDialogueInterpreter().sendDialogues(player, FacialExpression.NORMAL, "Sorry, I don't seem to have inventory space.");
|
||||
return false;
|
||||
}
|
||||
if (!player.getInventory().containsItem(COINS)) {
|
||||
player.getDialogueInterpreter().sendDialogues(player, FacialExpression.NORMAL, "Sorry, I don't seem to have enough coins with", "me at this time.");
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().remove(COINS)) {
|
||||
return player.getInventory().add(getItems(player, skill));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to trim the players skillcapes.
|
||||
* @param player the player.
|
||||
*/
|
||||
public static void trim(final Player player) {
|
||||
final Container[] containers = new Container[] { player.getInventory(), player.getEquipment(), player.getBank() };
|
||||
int skill = -1;
|
||||
for (Container container : containers) {
|
||||
for (Item item : container.toArray()) {
|
||||
if (item == null || item.getId() < 9700) {
|
||||
continue;
|
||||
}
|
||||
skill = getCapeIndex(item);
|
||||
if (skill != -1) {
|
||||
container.replace(new Item(getTrimmed(skill).getId(), item.getAmount()), item.getSlot());
|
||||
skill = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has the appropriate level.
|
||||
* @param player the player.
|
||||
* @param skill the skill.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean isMaster(final Player player, final int skill) {
|
||||
return player.getSkills().getStaticLevel(skill) == 99;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items to purchase.
|
||||
* @param player the player.
|
||||
* @param skill the skill.
|
||||
* @return {@code Items} to buy.
|
||||
*/
|
||||
public static Item[] getItems(final Player player, final int skill) {
|
||||
return new Item[] { new Item(SKILLCAPES[skill] + (player.getSkills().getMasteredSkills() > 1 ? 1 : 0)), new Item(SKILLCAPES[skill] + 2) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trimmed item.
|
||||
* @param skill the skill.
|
||||
* @return the trimmed cape.
|
||||
*/
|
||||
public static Item getTrimmed(final int skill) {
|
||||
return new Item(SKILLCAPES[skill] + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cape index by the item.
|
||||
* @param item the item.
|
||||
* @return the skill index, if not (-1).
|
||||
*/
|
||||
public static int getCapeIndex(final Item item) {
|
||||
for (int i = 0; i < SKILLCAPES.length; i++) {
|
||||
if (SKILLCAPES[i] == item.getId()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Handles the skillcape perks.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public enum SkillcapePerks {
|
||||
|
||||
ATTACK(9747, 9748),
|
||||
STRENGTH(9750, 9751),
|
||||
DEFENCE(9753, 9754),
|
||||
RANGING(9756, 9757),
|
||||
PRAYER(9759, 9760),
|
||||
MAGIC(9762, 9763),
|
||||
RUNECRAFTING(9765, 9766),
|
||||
HITPOINTS(9768, 9769),
|
||||
AGILITY(9771, 9772),
|
||||
HERBLORE(9774, 9775),
|
||||
THIEVEING(9777, 9778),
|
||||
CRAFTING(9780, 9781),
|
||||
FLETCHING(9783, 9784),
|
||||
SLAYER(9786, 9787),
|
||||
CONSTRUCTION(9789, 9790),
|
||||
MINING(9792, 9793),
|
||||
SMITHING(9795, 9796),
|
||||
FISHING(9798, 9799),
|
||||
COOKING(9801, 9802),
|
||||
FIREMAKING(9804, 9805),
|
||||
WOODCUTTING(9807, 9808),
|
||||
FARMING(9810, 9811),
|
||||
HUNTING(9948, 9949),
|
||||
MAX_CAPE(14831, 14833, 14835, 14839, 14840)
|
||||
;
|
||||
|
||||
/**
|
||||
* The skillcape Ids.
|
||||
*/
|
||||
private final int[] skillcapeIds;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new {@code SkillcapePerks} object.
|
||||
* @param skillcapeIds
|
||||
*/
|
||||
SkillcapePerks(int... skillcapeIds) {
|
||||
this.skillcapeIds = skillcapeIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* The skillcapeIds.
|
||||
* @return the skillcape ids.
|
||||
*/
|
||||
public int[] getSkillcapeIds() {
|
||||
return skillcapeIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has a skillcape perk.
|
||||
* @param player the player.
|
||||
* @param skillcapePerks the skillcapePerks
|
||||
* @return true if so.
|
||||
*/
|
||||
public static boolean hasSkillcapePerk(Player player, SkillcapePerks skillcapePerks) {
|
||||
SkillcapePerks perk = skillcapePerks;
|
||||
for (int i : perk.getSkillcapeIds()) {
|
||||
if (player.getEquipment().containsOneItem(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int j : MAX_CAPE.getSkillcapeIds()) {
|
||||
if (player.getEquipment().containsOneItem(j)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package org.crandor.game.content.global;
|
||||
|
||||
import org.crandor.game.content.skill.Skills;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.portal.Perks;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.world.repository.Repository;
|
||||
import org.crandor.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Represents the skilling pets obtained randomly.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public enum SkillingPets {
|
||||
|
||||
BABY_RED_CHINCHOMPA(new Item(14823), "Baby Chinchompa", Skills.HUNTER),
|
||||
BABY_GREY_CHINCHOMPA(new Item(14824), "Baby Chinchompa", Skills.HUNTER),
|
||||
BEAVER(new Item(14821), "Beaver", Skills.WOODCUTTING),
|
||||
GOLEM(new Item(14822), "Rock Golem", Skills.MINING),
|
||||
HERON(new Item(14827), "Heron", Skills.FISHING);
|
||||
|
||||
/**
|
||||
* The pet item drop.
|
||||
*/
|
||||
private final Item pet;
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The skill.
|
||||
*/
|
||||
private final int skill;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SkillingPets} object.
|
||||
* @param skill The skill id.
|
||||
* @param pet The pet item.
|
||||
*/
|
||||
SkillingPets(Item pet, String name, int skill) {
|
||||
this.pet = pet;
|
||||
this.name = name;
|
||||
this.skill = skill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the pet drop.
|
||||
* @param player The player.
|
||||
* @param pet The pet drop to check.
|
||||
*/
|
||||
public static void checkPetDrop(Player player, SkillingPets pet) {
|
||||
if (pet == null) {
|
||||
return;
|
||||
}
|
||||
int defaultChance = 15000;
|
||||
int newChance = (defaultChance / player.getSkills().getStaticLevel(pet.getSkill()) * 55);
|
||||
int outOf = (newChance > defaultChance ? defaultChance : newChance);
|
||||
int getChance = RandomFunction.random(player.hasPerk(Perks.PET_BEFRIENDER) ? outOf / 2 : outOf);
|
||||
if (getChance != 1) {
|
||||
return;
|
||||
}
|
||||
if (player.hasItem(pet.getPet())) {
|
||||
return;
|
||||
}
|
||||
if (player.getFamiliarManager().hasFamiliar() && player.getInventory().isFull()) {
|
||||
return;
|
||||
}
|
||||
if (player.getFamiliarManager().hasFamiliar()) {
|
||||
if (player.getFamiliarManager().getFamiliar().getName().equalsIgnoreCase(pet.getName())) {
|
||||
return;
|
||||
}
|
||||
player.getInventory().add(pet.getPet());
|
||||
player.sendNotificationMessage("You feel something weird sneaking into your backpack.");
|
||||
} else {
|
||||
player.getFamiliarManager().summon(pet.getPet(), true);
|
||||
player.sendNotificationMessage("You have a funny feeling like you're being followed.");
|
||||
}
|
||||
Repository.sendNews(player.getUsername() + " has found a " + pet.getPet().getName() + "!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the pet
|
||||
*/
|
||||
public Item getPet() {
|
||||
return pet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pet name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the skill.
|
||||
*/
|
||||
public int getSkill() {
|
||||
return skill;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.content.dialogue.DialoguePlugin;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.object.GameObject;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Direction;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.RegionManager;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
|
||||
/**
|
||||
* Handles a ladder climbing reward.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ClimbActionHandler {
|
||||
|
||||
/**
|
||||
* Represents the climb up animation of ladders.
|
||||
*/
|
||||
public static final Animation CLIMB_UP = new Animation(828);
|
||||
|
||||
/**
|
||||
* Represents the climb down animation of ladders.
|
||||
*/
|
||||
public static final Animation CLIMB_DOWN = new Animation(827);
|
||||
|
||||
/**
|
||||
* The climb dialogue.
|
||||
*/
|
||||
public static DialoguePlugin CLIMB_DIALOGUE = new ClimbDialogue();
|
||||
|
||||
/**
|
||||
* Handles the climbing of a rope.
|
||||
* @param player The player.
|
||||
* @param object The rope object.
|
||||
* @param option The option.
|
||||
*/
|
||||
public static void climbRope(Player player, GameObject object, String option) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the climbing of a trap door.
|
||||
* @param player The player.
|
||||
* @param object The trap door object.
|
||||
* @param option The option.
|
||||
*/
|
||||
public static void climbTrapdoor(Player player, GameObject object, String option) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the climbing of a ladder.
|
||||
* @param player The player.
|
||||
* @param object The game object.
|
||||
* @param option The option.
|
||||
*/
|
||||
public static void climbLadder(Player player, GameObject object, String option) {
|
||||
GameObject newLadder = null;
|
||||
Animation animation = CLIMB_UP;
|
||||
switch (option) {
|
||||
case "climb-up":
|
||||
newLadder = getLadder(object, false);
|
||||
break;
|
||||
case "climb-down":
|
||||
if (object.getName().equals("Trapdoor")) {
|
||||
animation = CLIMB_DOWN;
|
||||
}
|
||||
newLadder = getLadder(object, true);
|
||||
break;
|
||||
case "climb":
|
||||
GameObject upperLadder = getLadder(object, false);
|
||||
GameObject downLadder = getLadder(object, true);
|
||||
if (upperLadder == null && downLadder != null) {
|
||||
climbLadder(player, object, "climb-down");
|
||||
return;
|
||||
}
|
||||
if (upperLadder != null && downLadder == null) {
|
||||
climbLadder(player, object, "climb-up");
|
||||
return;
|
||||
}
|
||||
DialoguePlugin dial = CLIMB_DIALOGUE.newInstance(player);
|
||||
if (dial != null && dial.open(object)) {
|
||||
player.getDialogueInterpreter().setDialogue(dial);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Location destination = newLadder != null ? getDestination(newLadder) : null;
|
||||
if (newLadder == null || destination == null) {
|
||||
player.getPacketDispatch().sendMessage("The ladder doesn't seem to lead anywhere.");
|
||||
return;
|
||||
}
|
||||
if (object.getName().startsWith("Stair")) {
|
||||
animation = null;
|
||||
}
|
||||
climb(player, animation, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the teleport destination.
|
||||
* @param object The object to teleport to.
|
||||
* @return The teleport destination.
|
||||
*/
|
||||
public static Location getDestination(GameObject object) {
|
||||
int sizeX = object.getDefinition().sizeX;
|
||||
int sizeY = object.getDefinition().sizeY;
|
||||
if (object.getRotation() % 2 != 0) {
|
||||
int switcher = sizeX;
|
||||
sizeX = sizeY;
|
||||
sizeY = switcher;
|
||||
}
|
||||
Direction dir = Direction.forWalkFlag(object.getDefinition().getWalkingFlag(), object.getRotation());
|
||||
if (dir != null) {
|
||||
return getDestination(object, sizeX, sizeY, dir, 0);
|
||||
}
|
||||
switch (object.getRotation()) {
|
||||
case 0:
|
||||
return getDestination(object, sizeX, sizeY, Direction.SOUTH, 0);
|
||||
case 1:
|
||||
return getDestination(object, sizeX, sizeY, Direction.EAST, 0);
|
||||
case 2:
|
||||
return getDestination(object, sizeX, sizeY, Direction.NORTH, 0);
|
||||
case 3:
|
||||
return getDestination(object, sizeX, sizeY, Direction.WEST, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the destination for the given object.
|
||||
* @param object The object.
|
||||
* @param dir The preferred direction from the object.
|
||||
* @return The teleporting destination.
|
||||
*/
|
||||
private static Location getDestination(GameObject object, int sizeX, int sizeY, Direction dir, int count) {
|
||||
Location loc = object.getLocation();
|
||||
if (dir.toInteger() % 2 != 0) {
|
||||
int x = dir.getStepX();
|
||||
if (x > 0) {
|
||||
x *= sizeX;
|
||||
}
|
||||
for (int y = 0; y < sizeY; y++) {
|
||||
Location l = loc.transform(x, y, 0);
|
||||
if (RegionManager.isTeleportPermitted(l) && dir.canMove(l)) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int y = dir.getStepY();
|
||||
if (y > 0) {
|
||||
y *= sizeY;
|
||||
}
|
||||
for (int x = 0; x < sizeX; x++) {
|
||||
Location l = loc.transform(x, y, 0);
|
||||
if (RegionManager.isTeleportPermitted(l) && dir.canMove(l)) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count == 3) {
|
||||
return null;
|
||||
}
|
||||
return getDestination(object, sizeX, sizeY, Direction.get((dir.toInteger() + 1) % 4), count + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the climbing reward.
|
||||
* @param player The player.
|
||||
* @param animation The climbing animation.
|
||||
* @param destination The destination.
|
||||
*/
|
||||
public static void climb(final Player player, Animation animation, final Location destination, final String... messages) {
|
||||
player.lock(2);
|
||||
player.animate(animation);
|
||||
GameWorld.submit(new Pulse(1) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
player.getProperties().setTeleportLocation(destination);
|
||||
for (String message : messages) {
|
||||
player.getPacketDispatch().sendMessage(message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ladder the object leads to.
|
||||
* @param object The ladder object.
|
||||
* @param down If the player is going down a floor.
|
||||
* @return The ladder the current ladder object leads to.
|
||||
*/
|
||||
private static GameObject getLadder(GameObject object, boolean down) {
|
||||
int mod = down ? -1 : 1;
|
||||
GameObject ladder = RegionManager.getObject(object.getLocation().transform(0, 0, mod));
|
||||
if (ladder == null || !isLadder(ladder)) {
|
||||
if (ladder != null && ladder.getName().equals(object.getName())) {
|
||||
ladder = RegionManager.getObject(ladder.getLocation().transform(0, 0, mod));
|
||||
if (ladder != null) {
|
||||
return ladder;
|
||||
}
|
||||
}
|
||||
ladder = findLadder(object.getLocation().transform(0, 0, mod));
|
||||
if (ladder == null) {
|
||||
ladder = RegionManager.getObject(object.getLocation().transform(0, mod * -6400, 0));
|
||||
if (ladder == null) {
|
||||
ladder = findLadder(object.getLocation().transform(0, mod * -6400, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ladder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a ladder (by searching a 10x10 area around the given location).
|
||||
* @param l The location.
|
||||
* @return The ladder.
|
||||
*/
|
||||
private static GameObject findLadder(Location l) {
|
||||
for (int x = -5; x < 6; x++) {
|
||||
for (int y = -5; y < 6; y++) {
|
||||
GameObject object = RegionManager.getObject(l.transform(x, y, 0));
|
||||
if (object != null && isLadder(object)) {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the object is a ladder.
|
||||
* @param object The object.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private static boolean isLadder(GameObject object) {
|
||||
for (String option : object.getDefinition().getOptions()) {
|
||||
if (option != null && (option.contains("Climb"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return object.getName().equals("Trapdoor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the dialogue plugin used for climbing stairs or a ladder.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
static final class ClimbDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Represents the climbing dialogue id.
|
||||
*/
|
||||
public static final int ID = 8 << 16;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClimbDialogue} {@code Object}.
|
||||
*/
|
||||
public ClimbDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClimbDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public ClimbDialogue(final Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new ClimbDialogue(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the object to use.
|
||||
*/
|
||||
private GameObject object;
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
object = (GameObject) args[0];
|
||||
interpreter.sendOptions("What would you like to do?", "Climb Up.", "Climb Down.");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player.lock(1);
|
||||
GameWorld.submit(new Pulse(1) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
climbLadder(player, object, "climb-up");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
end();
|
||||
break;
|
||||
case 2:
|
||||
player.lock(1);
|
||||
GameWorld.submit(new Pulse(1) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
climbLadder(player, object, "climb-down");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
end();
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { ID };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Handles a digging reward.
|
||||
* @author Emperor
|
||||
*/
|
||||
public interface DigAction {
|
||||
|
||||
/**
|
||||
* Runs the digging reward.
|
||||
* @param player The player.
|
||||
*/
|
||||
void run(Player player);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles digging with a spade.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class DigSpadeHandler {
|
||||
|
||||
/**
|
||||
* The digging actions.
|
||||
*/
|
||||
private static final Map<Location, DigAction> ACTIONS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The digging animation.
|
||||
*/
|
||||
public static final Animation ANIMATION = Animation.create(830);
|
||||
|
||||
/**
|
||||
* Handles a digging reward.
|
||||
* @param player The player.
|
||||
* @return {@code True} if the reward got handled.
|
||||
*/
|
||||
public static boolean dig(final Player player) {
|
||||
final DigAction action = ACTIONS.get(player.getLocation());
|
||||
player.animate(ANIMATION);
|
||||
player.lock(1);
|
||||
if (action != null) {
|
||||
GameWorld.submit(new Pulse(1, player) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
action.run(player);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new digging reward.
|
||||
* @param location The location to dig on.
|
||||
* @param action The reward.
|
||||
* @return {@code True} if the reward got registered.
|
||||
*/
|
||||
public static boolean register(Location location, DigAction action) {
|
||||
if (ACTIONS.containsKey(location)) {
|
||||
System.err.println("Already contained dig reward for location " + location + ".");
|
||||
return false;
|
||||
}
|
||||
ACTIONS.put(location, action);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.node.entity.Entity;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.object.Constructed;
|
||||
import org.crandor.game.node.object.GameObject;
|
||||
import org.crandor.game.node.object.ObjectBuilder;
|
||||
import org.crandor.game.system.mysql.impl.DoorConfigSQLHandler;
|
||||
import org.crandor.game.system.mysql.impl.DoorConfigSQLHandler.Door;
|
||||
import org.crandor.game.system.task.LocationLogoutTask;
|
||||
import org.crandor.game.system.task.LogoutTask;
|
||||
import org.crandor.game.system.task.Pulse;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.Direction;
|
||||
import org.crandor.game.world.map.Location;
|
||||
import org.crandor.game.world.map.RegionManager;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Handles door actions.
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class DoorActionHandler {
|
||||
|
||||
/**
|
||||
* The charge indicating the door is already in use.
|
||||
*/
|
||||
private static final int IN_USE_CHARGE = 88;
|
||||
|
||||
/**
|
||||
* Handles a door reward.
|
||||
* @param player The player.
|
||||
* @param object The object.
|
||||
*/
|
||||
public static void handleDoor(final Player player, final GameObject object) {
|
||||
final GameObject second = (object.getId() == 1530 || object.getId() == 1531) ? null : getSecondDoor(object, player);
|
||||
GameObject o = null;
|
||||
if (object instanceof Constructed && (o = ((Constructed) object).getReplaced()) != null) {
|
||||
player.getAudioManager().send(new Audio(43));
|
||||
ObjectBuilder.replace(object, o);
|
||||
if (second instanceof Constructed && (o = ((Constructed) second).getReplaced()) != null) {
|
||||
ObjectBuilder.replace(second, o);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (object.getDefinition().hasAction("close")) {
|
||||
if (second != null) {
|
||||
player.getPacketDispatch().sendMessage("The doors appear to be stuck.");
|
||||
return;
|
||||
}
|
||||
Door d = DoorConfigSQLHandler.forId(object.getId());
|
||||
if (d == null) {
|
||||
player.getPacketDispatch().sendMessage("The door appears to be stuck.");
|
||||
return;
|
||||
}
|
||||
int firstDir = (object.getRotation() + 3) % 4;
|
||||
Point p = getCloseRotation(object);
|
||||
Location firstLoc = object.getLocation().transform((int) p.getX(), (int) p.getY(), 0);
|
||||
ObjectBuilder.replace(object, object.transform(d.getReplaceId(), firstDir, firstLoc));
|
||||
return;
|
||||
}
|
||||
Door d = DoorConfigSQLHandler.forId(object.getId());
|
||||
if (d == null) {
|
||||
handleAutowalkDoor(player, object);
|
||||
return;
|
||||
}
|
||||
player.getAudioManager().send(new Audio(81));
|
||||
if (second != null) {
|
||||
Door s = DoorConfigSQLHandler.forId(second.getId());
|
||||
open(object, second, d.getReplaceId(), s == null ? second.getId() : s.getReplaceId(), true, 500, d.isFence());
|
||||
return;
|
||||
}
|
||||
open(object, null, d.getReplaceId(), -1, true, 500, d.isFence());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the opening and walking through a door.
|
||||
* @param entity The entity walking through the door.
|
||||
* @param object The door object.
|
||||
* @return
|
||||
*/
|
||||
public static boolean handleAutowalkDoor(final Entity entity, final GameObject object, final Location endLocation) {
|
||||
if (object.getCharge() == IN_USE_CHARGE) {
|
||||
return false;
|
||||
}
|
||||
final GameObject second = (object.getId() == 3) ? null : getSecondDoor(object, entity);
|
||||
entity.lock(4);
|
||||
final Location loc = entity.getLocation();
|
||||
entity.addExtension(LogoutTask.class, new LocationLogoutTask(4, loc));
|
||||
object.setCharge(IN_USE_CHARGE);
|
||||
if (second != null) {
|
||||
second.setCharge(IN_USE_CHARGE);
|
||||
}
|
||||
if (entity instanceof Player) {
|
||||
((Player) entity).getAudioManager().send(new Audio(3419));
|
||||
}
|
||||
GameWorld.submit(new Pulse(1) {
|
||||
boolean opened = false;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (!opened) {
|
||||
open(object, second, object.getId(), second == null ? -1 : second.getId(), false, 2, false);
|
||||
Location l = endLocation;
|
||||
entity.getWalkingQueue().reset();
|
||||
entity.getWalkingQueue().addPath(l.getX(), l.getY());
|
||||
opened = true;
|
||||
return false;
|
||||
}
|
||||
object.setCharge(1000);
|
||||
if (second != null) {
|
||||
second.setCharge(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper for handling the auto walk door.
|
||||
* @param entity the entity.
|
||||
* @param object the object.
|
||||
*/
|
||||
public static boolean handleAutowalkDoor(final Entity entity, final GameObject object) {
|
||||
return handleAutowalkDoor(entity, object, getEndLocation(entity, object));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end location to walk to.
|
||||
* @param entity the entity.
|
||||
* @param object the object.
|
||||
* @return the end location.
|
||||
*/
|
||||
public static Location getEndLocation(Entity entity, GameObject object) {
|
||||
Location l = object.getLocation();
|
||||
switch (object.getRotation()) {
|
||||
case 0:
|
||||
if (entity.getLocation().getX() >= l.getX()) {
|
||||
l = l.transform(-1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (entity.getLocation().getY() <= l.getY()) {
|
||||
l = l.transform(0, 1, 0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (entity.getLocation().getX() <= l.getX()) {
|
||||
l = l.transform(1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (entity.getLocation().getY() >= l.getY()) {
|
||||
l = l.transform(0, -1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the destination for the door.
|
||||
* @param door The door.
|
||||
* @return The destination location.
|
||||
*/
|
||||
public static Location getDestination(Entity entity, GameObject door) {
|
||||
Location l = door.getLocation();
|
||||
int rotation = door.getRotation();
|
||||
if (door instanceof Constructed && door.getDefinition().hasAction("close")) {
|
||||
GameObject o = ((Constructed) door).getReplaced();
|
||||
if (o != null) {
|
||||
l = o.getLocation();
|
||||
rotation = o.getRotation();
|
||||
}
|
||||
}
|
||||
if (door.getType() == 9) { // Diagonal doors
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
case 2:
|
||||
if (entity.getLocation().getY() < l.getY() || entity.getLocation().getX() < l.getX()) {
|
||||
return l.transform(0, -1, 0);
|
||||
}
|
||||
return l.transform(0, 1, 0);
|
||||
case 1:
|
||||
case 3:
|
||||
if (entity.getLocation().getX() > l.getX() || entity.getLocation().getY() > l.getY()) {
|
||||
return l.transform(1, 0, 0);
|
||||
}
|
||||
return l.transform(-1, 0, 0);
|
||||
}
|
||||
}
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
if (entity.getLocation().getX() < l.getX()) {
|
||||
return l.transform(-1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (entity.getLocation().getY() > l.getY()) {
|
||||
return l.transform(0, 1, 0);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (entity.getLocation().getX() > l.getX()) {
|
||||
return l.transform(1, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (entity.getLocation().getY() < l.getY()) {
|
||||
return l.transform(0, -1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the doors.
|
||||
* @param object The door object.
|
||||
* @param second The second door object.
|
||||
* @param replaceId The replace id.
|
||||
* @param secondReplaceId The second replace id.
|
||||
* @param clip If clipping should be changed due to opening the door.
|
||||
* @param restoreTicks The amount of ticks before the door(s) should be
|
||||
* closed again.
|
||||
*/
|
||||
public static void open(GameObject object, GameObject second, int replaceId, int secondReplaceId, boolean clip, int restoreTicks, boolean fence) {
|
||||
object = object.getWrapper();
|
||||
int mod = object.getType() == 9 ? -1 : 1;
|
||||
int firstDir = (object.getRotation() + ((mod + 4) % 4)) % 4;
|
||||
Point p = getRotationPoint(object.getRotation());
|
||||
Location firstLoc = object.getLocation().transform((int) p.getX() * mod, (int) p.getY() * mod, 0);
|
||||
if (second == null) {
|
||||
if (replaceId == 4577) {
|
||||
replaceId = 4578;
|
||||
firstDir = 3;
|
||||
firstLoc = firstLoc.transform(0, 1, 0);
|
||||
}
|
||||
ObjectBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip);
|
||||
return;
|
||||
}
|
||||
second = second.getWrapper();
|
||||
if (fence) {
|
||||
openFence(object, second, replaceId, secondReplaceId, clip, restoreTicks);
|
||||
return;
|
||||
}
|
||||
Direction offset = Direction.getDirection(second.getLocation().getX() - object.getLocation().getX(), second.getLocation().getY() - object.getLocation().getY());
|
||||
int secondDir = (second.getRotation() + mod) % 4;
|
||||
if (firstDir == 1 && offset == Direction.NORTH) {
|
||||
firstDir = 3;
|
||||
} else if (firstDir == 2 && offset == Direction.EAST) {
|
||||
firstDir = 0;
|
||||
} else if (firstDir == 3 && offset == Direction.SOUTH) {
|
||||
firstDir = 1;
|
||||
} else if (firstDir == 0 && offset == Direction.WEST) {
|
||||
firstDir = 2;
|
||||
}
|
||||
if (firstDir == secondDir) {
|
||||
secondDir = (secondDir + 2) % 4;
|
||||
}
|
||||
Location secondLoc = second.getLocation().transform((int) p.getX(), (int) p.getY(), 0);
|
||||
ObjectBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip);
|
||||
ObjectBuilder.replace(second, second.transform(secondReplaceId, secondDir, secondLoc), restoreTicks, clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the opening of a fence.
|
||||
* @param object The fence object.
|
||||
* @param second The second fence object.
|
||||
* @param replaceId The replace id.
|
||||
* @param secondReplaceId The second replace id.
|
||||
* @param clip If clipping should be changed due to opening the door.
|
||||
* @param restoreTicks The amount of ticks before the door(s) should be
|
||||
* closed again.
|
||||
*/
|
||||
private static void openFence(GameObject object, GameObject second, int replaceId, int secondReplaceId, boolean clip, int restoreTicks) {
|
||||
Direction offset = Direction.getDirection(second.getLocation().getX() - object.getLocation().getX(), second.getLocation().getY() - object.getLocation().getY());
|
||||
int firstDir = (object.getRotation() + 3) % 4;
|
||||
Point p = getRotationPoint(object.getRotation());
|
||||
Location firstLoc = null;
|
||||
int secondDir = (second.getRotation() + 3) % 4;
|
||||
if (offset == Direction.WEST || offset == Direction.SOUTH) {
|
||||
firstLoc = second.getLocation().transform((int) p.getX(), (int) p.getY(), 0);
|
||||
int s = replaceId;
|
||||
replaceId = secondReplaceId;
|
||||
secondReplaceId = s;
|
||||
} else {
|
||||
firstLoc = object.getLocation().transform((int) p.getX(), (int) p.getY(), 0);
|
||||
}
|
||||
if (object.getRotation() == 3 || object.getRotation() == 2) {
|
||||
firstDir = (firstDir + 2) % 4;
|
||||
secondDir = (secondDir + 2) % 4;
|
||||
}
|
||||
Location secondLoc = firstLoc.transform((int) p.getX(), (int) p.getY(), 0);
|
||||
ObjectBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip);
|
||||
ObjectBuilder.replace(second, second.transform(secondReplaceId, secondDir, secondLoc), restoreTicks, clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the opening of a fence.
|
||||
* @param object The fence object.
|
||||
* @param replaceId The replace id.
|
||||
* @param secondReplaceId The second replace id.
|
||||
* closed again.
|
||||
*/
|
||||
public static boolean autowalkFence(final Entity entity, final GameObject object, final int replaceId, final int secondReplaceId) {
|
||||
final GameObject second = getSecondDoor(object, entity);
|
||||
if (object.getCharge() == IN_USE_CHARGE || second == null) {
|
||||
return false;
|
||||
}
|
||||
entity.lock(4);
|
||||
final Location loc = entity.getLocation();
|
||||
entity.addExtension(LogoutTask.class, new LocationLogoutTask(4, loc));
|
||||
object.setCharge(IN_USE_CHARGE);
|
||||
second.setCharge(IN_USE_CHARGE);
|
||||
GameWorld.submit(new Pulse(1) {
|
||||
boolean opened = false;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (!opened) {
|
||||
openFence(object, second, replaceId, secondReplaceId, false, 2);
|
||||
Location l = getEndLocation(entity, object);
|
||||
entity.getWalkingQueue().reset();
|
||||
entity.getWalkingQueue().addPath(l.getX(), l.getY());
|
||||
opened = true;
|
||||
return false;
|
||||
}
|
||||
object.setCharge(1000);
|
||||
if (second != null) {
|
||||
second.setCharge(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the closing rotation point.
|
||||
* @param object The object.
|
||||
* @return The point.
|
||||
*/
|
||||
private static Point getCloseRotation(GameObject object) {
|
||||
switch (object.getRotation()) {
|
||||
case 0:
|
||||
return new Point(0, 1);
|
||||
case 1:
|
||||
return new Point(1, 0);
|
||||
case 2:
|
||||
return new Point(0, -1);
|
||||
case 3:
|
||||
return new Point(-1, 0);
|
||||
}
|
||||
return new Point(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rotation point for the object.
|
||||
* @return The rotation point.
|
||||
*/
|
||||
public static Point getRotationPoint(int rotation) {
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
return new Point(-1, 0);
|
||||
case 1:
|
||||
return new Point(0, 1);
|
||||
case 2:
|
||||
return new Point(1, 0);
|
||||
case 3:
|
||||
return new Point(0, -1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the door next to this door.
|
||||
* @param object The door.
|
||||
* @return The second door, if any, {@code null} if no second door existed.
|
||||
*/
|
||||
public static GameObject getSecondDoor(GameObject object, Entity entity) {
|
||||
Location l = object.getLocation();
|
||||
Player player = entity instanceof Player ? (Player) entity : null;
|
||||
GameObject o = null;
|
||||
if ((o = RegionManager.getObject(l.transform(-1, 0, 0))) != null && o.getChild(player).getName().equals(object.getName())) {
|
||||
return o;
|
||||
}
|
||||
if ((o = RegionManager.getObject(l.transform(1, 0, 0))) != null && o.getChild(player).getName().equals(object.getName())) {
|
||||
return o;
|
||||
}
|
||||
if ((o = RegionManager.getObject(l.transform(0, -1, 0))) != null && o.getChild(player).getName().equals(object.getName())) {
|
||||
return o;
|
||||
}
|
||||
if ((o = RegionManager.getObject(l.transform(0, 1, 0))) != null && o.getChild(player).getName().equals(object.getName())) {
|
||||
return o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rotations to set the opened doors to.
|
||||
* @param object The first door.
|
||||
* @param second The second door.
|
||||
* @param rp The rotation point.
|
||||
* @return An int-array, with index 0 being first door rotation and index 1
|
||||
* being second door rotation.
|
||||
*/
|
||||
public static int[] getRotation(GameObject object, GameObject second, Point rp) {
|
||||
if (second == null) {
|
||||
return new int[] { (object.getRotation() + 1) % 4 };
|
||||
}
|
||||
int[] rotations = new int[] { 3, 1 };
|
||||
Location fl = object.getLocation();
|
||||
Location sl = second.getLocation();
|
||||
if (fl.getX() > sl.getX()) {
|
||||
rotations = new int[] { 2, 0 };
|
||||
}
|
||||
if (fl.getX() < sl.getX()) {
|
||||
rotations = new int[] { 0, 2 };
|
||||
}
|
||||
if (fl.getY() > sl.getY()) {
|
||||
rotations = new int[] { 1, 3 };
|
||||
}
|
||||
if (rp.getY() > 0 || rp.getX() > 0) {
|
||||
rotations = new int[] { rotations[1], rotations[0] };
|
||||
}
|
||||
return rotations;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.node.Node;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.Rights;
|
||||
import org.crandor.game.node.entity.player.info.login.PlayerParser;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.item.GroundItemManager;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.SystemLogger;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Handles the dropping of an item.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class DropItemHandler {
|
||||
|
||||
/**
|
||||
* Handles the droping of an item.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param option the option.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean handle(final Player player, Node node, String option) {
|
||||
Item item = (Item) node;
|
||||
if (item.getSlot() == -1) {
|
||||
player.getPacketDispatch().sendMessage("Invalid slot!");
|
||||
return false;
|
||||
}
|
||||
switch (option) {
|
||||
case "drop":
|
||||
case "destroy":
|
||||
case "dissolve":
|
||||
if (!player.getInterfaceManager().close()) {
|
||||
return true;
|
||||
}
|
||||
player.getDialogueInterpreter().close();
|
||||
player.getAudioManager().send(new Audio(2393, 0, 0));
|
||||
player.getPulseManager().clear();
|
||||
if (option.equalsIgnoreCase("destroy") || option.equalsIgnoreCase("dissolve")) {
|
||||
player.getDialogueInterpreter().open(9878, item);
|
||||
return true;
|
||||
}
|
||||
if (player.getAttribute("equipLock:" + item.getId(), 0) > GameWorld.getTicks()) {
|
||||
SystemLogger.log(player + ", tried to do the drop & equip dupe.");
|
||||
return true;
|
||||
}
|
||||
if (player.getInventory().replace(null, item.getSlot()) == item) {
|
||||
item = item.getDropItem();
|
||||
player.getAudioManager().send(new Audio(item.getId() == 995 ? 10 : 2739, 1, 0));
|
||||
if (!player.getDetails().getRights().equals(Rights.ADMINISTRATOR) || !player.getAttribute("tut-island", false)) {
|
||||
GroundItemManager.create(item, player.getLocation(), player);
|
||||
PlayerParser.dump(player);
|
||||
}
|
||||
} else {
|
||||
GroundItemManager.create(item, player.getLocation(), player).setDecayTime(99);
|
||||
PlayerParser.dump(player);
|
||||
}
|
||||
player.setAttribute("droppedItem:" + item.getId(), GameWorld.getTicks() + 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops an item.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
* @return
|
||||
*/
|
||||
public static boolean drop(Player player, Item item) {
|
||||
return handle(player, item, item.getDefinition().hasDestroyAction() ? "destroy" : "drop");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.cache.def.impl.ItemDefinition;
|
||||
import org.crandor.game.container.impl.EquipmentContainer;
|
||||
import org.crandor.game.content.global.tutorial.TutorialSession;
|
||||
import org.crandor.game.content.global.tutorial.TutorialStage;
|
||||
import org.crandor.game.interaction.OptionHandler;
|
||||
import org.crandor.game.node.Node;
|
||||
import org.crandor.game.node.entity.lock.Lock;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the equipment equipping handler plugin.
|
||||
* @author Emperor
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public class EquipHandler extends OptionHandler {
|
||||
|
||||
/**
|
||||
* Represents the singleton.
|
||||
*/
|
||||
public static final EquipHandler SINGLETON = new EquipHandler();
|
||||
|
||||
/**
|
||||
* The sound to send.
|
||||
*/
|
||||
private static final Audio SOUND = new Audio(2242, 1, 0);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code EquipHandler} {@code Object}.
|
||||
*/
|
||||
public EquipHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final Player player, Node node, String option) {
|
||||
final Item item = ((Item) node);
|
||||
if (item == null || player.getInventory().get(item.getSlot()) != item) {
|
||||
return true;
|
||||
}
|
||||
if (TutorialSession.getExtension(player).getStage() < 46) {
|
||||
player.getPacketDispatch().sendMessage("You'll be told how to equip items later.");
|
||||
return true;
|
||||
}
|
||||
if (TutorialSession.getExtension(player).getStage() == 46 && item.getId() == 1205) {
|
||||
TutorialStage.load(player, 47, false);
|
||||
}
|
||||
Plugin<Object> plugin = item.getDefinition().getConfiguration("equipment", null);
|
||||
if (plugin != null) {
|
||||
Boolean bool = (Boolean) plugin.fireEvent("equip", player, item);
|
||||
if (bool != null && !bool) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Lock lock = player.getLocks().getEquipmentLock();
|
||||
if (lock != null && lock.isLocked()) {
|
||||
if (lock.getMessage() != null) {
|
||||
player.getPacketDispatch().sendMessage(lock.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
player.setAttribute("equipLock:" + item.getId(), GameWorld.getTicks() + 2);
|
||||
if (player.getEquipment().add(item, item.getSlot(), true, true)) {
|
||||
player.getDialogueInterpreter().close();
|
||||
player.getAudioManager().send(SOUND);
|
||||
}
|
||||
ItemDefinition.statsUpdate(player);
|
||||
if (TutorialSession.getExtension(player).getStage() == 48) {
|
||||
if (player.getEquipment().containItems(1171, 1277)) {
|
||||
TutorialStage.load(player, 49, false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unequips an item.
|
||||
* @param player the player.
|
||||
* @param slot the slot.
|
||||
* @param itemId the item id.
|
||||
*/
|
||||
public static void unequip(Player player, int slot, int itemId) {
|
||||
if (slot < 0 || slot > 13) {
|
||||
return;
|
||||
}
|
||||
Item item = player.getEquipment().get(slot);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
Lock lock = player.getLocks().getEquipmentLock();
|
||||
if (lock != null && lock.isLocked()) {
|
||||
if (lock.getMessage() != null) {
|
||||
player.getPacketDispatch().sendMessage(lock.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (slot == EquipmentContainer.SLOT_WEAPON) {
|
||||
player.getPacketDispatch().sendString("", 92, 0);
|
||||
}
|
||||
int maximumAdd = player.getInventory().getMaximumAdd(item);
|
||||
if (maximumAdd < item.getAmount()) {
|
||||
player.getPacketDispatch().sendMessage("Not enough free space in your inventory.");
|
||||
return;
|
||||
}
|
||||
Plugin<Object> plugin = item.getDefinition().getConfiguration("equipment", null);
|
||||
if (plugin != null) {
|
||||
if (!(boolean) plugin.fireEvent("unequip", player, item)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (player.getEquipment().remove(item)) {
|
||||
player.getAudioManager().send(new Audio(2238, 10, 1));
|
||||
player.getDialogueInterpreter().close();
|
||||
player.getInventory().add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package org.crandor.game.content.global.action;
|
||||
|
||||
import org.crandor.game.content.dialogue.FacialExpression;
|
||||
import org.crandor.game.content.global.GodType;
|
||||
import org.crandor.game.content.skill.free.runecrafting.RunePouch;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.entity.player.link.diary.DiaryType;
|
||||
import org.crandor.game.node.item.GroundItem;
|
||||
import org.crandor.game.node.item.GroundItemManager;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.system.SystemLogger;
|
||||
import org.crandor.game.system.mysql.impl.GroundSpawnSQLHandler.GroundSpawn;
|
||||
import org.crandor.game.world.GameWorld;
|
||||
import org.crandor.game.world.map.RegionManager;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
|
||||
/**
|
||||
* A class used to handle the picking up of ground items.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
public final class PickupHandler {
|
||||
|
||||
/**
|
||||
* Method used to take a ground item.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
* @return {@code True} if taken.
|
||||
*/
|
||||
public static boolean take(final Player player, final GroundItem item) {
|
||||
if (item.getLocation() == null) {
|
||||
player.getPacketDispatch().sendMessage("Invalid ground item!");
|
||||
return true;
|
||||
}
|
||||
if (!GroundItemManager.getItems().contains(item)) {
|
||||
player.getPacketDispatch().sendMessage("Too late!");
|
||||
return true;
|
||||
}
|
||||
if (player.getAttribute("droppedItem:" + item.getId(), 0) > GameWorld.getTicks()) {//Splinter
|
||||
SystemLogger.log(player + ", tried to do the drop & quick pick-up Ground Item dupe.");
|
||||
return true;
|
||||
}
|
||||
if (!(item instanceof GroundSpawn) && item.isRemainPrivate() && !item.droppedBy(player)) {
|
||||
player.sendMessage("You can't take that item!");
|
||||
return true;
|
||||
}
|
||||
Item add = new Item(item.getId(), item.getAmount(), item.getCharge());
|
||||
if (!player.getInventory().hasSpaceFor(add)) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space to hold that item.");
|
||||
return true;
|
||||
}
|
||||
if (!canTake(player, item, 0)) {
|
||||
return true;
|
||||
}
|
||||
if (item.isActive() && player.getInventory().add(add)) {
|
||||
if (!RegionManager.isTeleportPermitted(item.getLocation())) {
|
||||
player.animate(Animation.create(535));
|
||||
}
|
||||
if (item instanceof GroundSpawn && item.getId() == 401 && player.getZoneMonitor().isInZone("karamja") && !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.KARAMJA, 0, 7)) {
|
||||
int seaweed = player.getAttribute("seaweed", 0);
|
||||
seaweed++;
|
||||
player.setAttribute("seaweed", seaweed);
|
||||
player.getAchievementDiaryManager().updateTask(player, DiaryType.KARAMJA, 0, 7, seaweed == 5);
|
||||
}
|
||||
GroundItemManager.destroy(item);
|
||||
player.getAudioManager().send(new Audio(2582, 10, 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can take an item.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
* @param type the type (1= ground, 2=telegrab)
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean canTake(Player player, GroundItem item, int type) {
|
||||
if (item.getDropper() != null && !item.droppedBy(player) && player.getIronmanManager().checkRestriction()) {
|
||||
return false;
|
||||
}
|
||||
if (item.getId() == 8858 || item.getId() == 8859) {
|
||||
player.getDialogueInterpreter().sendDialogues(4300, FacialExpression.ANGRY, "Hey! You can't take that, it's guild property. Take one", "from the pile.");
|
||||
return false;
|
||||
}
|
||||
if (GodType.forCape(item) != null) {
|
||||
if (GodType.hasAny(player)) {
|
||||
player.sendMessages("You may only possess one sacred cape at a time.", "The conflicting powers of the capes drive them apart.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (RunePouch.forItem(item) != null) {
|
||||
if (player.hasItem(item)) {
|
||||
player.sendMessage("A mystical force prevents you from picking up the pouch.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (item.hasItemPlugin()) {
|
||||
return item.getPlugin().canPickUp(player, item, type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
package org.crandor.game.content.global.consumable;
|
||||
|
||||
import org.crandor.game.content.skill.SkillBonus;
|
||||
import org.crandor.game.content.skill.Skills;
|
||||
import org.crandor.game.node.Node;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.world.update.flag.context.Animation;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents a dynamic consumable item.
|
||||
* @author 'Vexia
|
||||
* @date 22/12/2013
|
||||
*/
|
||||
public abstract class Consumable implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
* Represents the animation when consuming.
|
||||
*/
|
||||
protected static final Animation ANIMATION = new Animation(829);
|
||||
|
||||
/**
|
||||
* Represents the empty vial item.
|
||||
*/
|
||||
protected static final Item VIAL = new Item(229);
|
||||
|
||||
/**
|
||||
* Represents the empty bucket item.
|
||||
*/
|
||||
protected static final Item BUCKET = new Item(1925);
|
||||
|
||||
/**
|
||||
* Represents the empty jug item.
|
||||
*/
|
||||
protected static final Item JUG = new Item(1935);
|
||||
|
||||
/**
|
||||
* Represents the empty bowl item.
|
||||
*/
|
||||
protected static final Item BOWL = new Item(1923);
|
||||
|
||||
/**
|
||||
* Represents the beer glass item.
|
||||
*/
|
||||
protected static final Item BEER_GLASS = new Item(1919);
|
||||
|
||||
/**
|
||||
* Represents the message used when emptying the consumable.
|
||||
*/
|
||||
protected static final String EMPTY_MESSAGE = "You empty the contents of the @name on the floor.";
|
||||
|
||||
/**
|
||||
* Represents the consumable item.
|
||||
*/
|
||||
private Item item;
|
||||
|
||||
/**
|
||||
* Represents the food properties of this food.
|
||||
*/
|
||||
private ConsumableProperties properties;
|
||||
|
||||
/**
|
||||
* Represents the item the player gets when emptying this item.
|
||||
*/
|
||||
protected Item emptyItem;
|
||||
|
||||
/**
|
||||
* Represents the message displayed when emptying the consumable.
|
||||
*/
|
||||
protected String emptyMessage;
|
||||
|
||||
/**
|
||||
* Represents the messages to display when consumed.
|
||||
*/
|
||||
protected String[] messages = null;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Consumable} {@code Object}.
|
||||
* @param item the item.
|
||||
* @parma properties the properties.
|
||||
*/
|
||||
public Consumable(final Item item, final ConsumableProperties properties) {
|
||||
this.item = item;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Consumable} {@code Object}.
|
||||
*/
|
||||
public Consumable() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when this consumables is consumed.
|
||||
* @param player the player.
|
||||
*/
|
||||
public void consume(final Item item, final Player player) {
|
||||
consume(item, player, properties.getHealing());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when this consumable is consumed.
|
||||
* @note override if needed, generally for extra effects.
|
||||
* @param player the player consuming this consumable.
|
||||
* @param the healing amount used to override, (generally to alter amt)
|
||||
* @param messages the messages to show.
|
||||
*/
|
||||
public void consume(final Item item, final Player player, int heal, String... messages) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to handle the interaction between food and a node.
|
||||
* @note override if needed.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
*/
|
||||
public boolean interact(final Player player, final Node node) {
|
||||
return interact(player, node, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to handle the interaction between food and a node.
|
||||
* @note override if needed.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param option the option (if any)
|
||||
*/
|
||||
public boolean interact(final Player player, final Node node, String option) {
|
||||
switch (option) {
|
||||
case "empty":
|
||||
Item item = (Item) node;
|
||||
if (item.getSlot() < 0) {
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().remove(item, item.getSlot(), true)) {
|
||||
player.getPacketDispatch().sendMessage(getEmptyMessage(item));
|
||||
}
|
||||
if (getEmptyItem() != null) {
|
||||
player.getInventory().add(getEmptyItem());
|
||||
return true;
|
||||
}
|
||||
Consumable c = Consumables.forConsumable(item);
|
||||
if (c != null) {
|
||||
if (c.getEmptyItem() != null) {
|
||||
player.getInventory().add(c.getEmptyItem());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to add a skill bonus to a player.
|
||||
* @param player the player.
|
||||
* @param b the bonus.
|
||||
*/
|
||||
public void addBonus(final Player player, final SkillBonus b) {
|
||||
int level = player.getSkills().getStaticLevel(b.getSkillId());
|
||||
level = (int) (b.getBaseBonus() + level + (level * b.getBonus()));
|
||||
if (b.getBonus() < 0) {
|
||||
player.getSkills().setLevel(b.getSkillId(), level);
|
||||
return;
|
||||
}
|
||||
if (player.getSkills().getLevel(b.getSkillId()) <= level) {
|
||||
if (b.getSkillId() == Skills.HITPOINTS) {
|
||||
if (player.getSkills().getLifepoints() > player.getSkills().getStaticLevel(Skills.HITPOINTS)) {
|
||||
return;
|
||||
}
|
||||
int difference = level - player.getSkills().getStaticLevel(b.getSkillId());
|
||||
player.getSkills().setLevel(b.getSkillId(), player.getSkills().getLifepoints() + difference);
|
||||
} else {
|
||||
player.getSkills().setLevel(b.getSkillId(), level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to remove the item and heal the player.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
*/
|
||||
public void remove(final Player player, final Item item) {
|
||||
if (getProperties() == null) {
|
||||
System.err.println("VEXIA SUCKS, PROPERTIES ARE NULL " + item.getId());
|
||||
return;
|
||||
}
|
||||
if (!removed(item, player)) {
|
||||
return;
|
||||
}
|
||||
player.animate(ANIMATION);
|
||||
player.getSkills().heal(getProperties().getHealing());
|
||||
player.getAudioManager().send(this instanceof Drink ? Drink.SOUND : Food.SOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an item is removed.
|
||||
* @param item t he item.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean removed(Item item, Player player) {
|
||||
if (getProperties().hasNewItem()) {
|
||||
if (player.getInventory().replace(getProperties().getNewItem(), item.getSlot()) == null) {
|
||||
;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!player.getInventory().remove(item, item.getSlot(), true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to message the player.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
* @param initial the initial hp amount.
|
||||
*/
|
||||
public void message(final Player player, final Item item, final int initial, final String... messages) {
|
||||
if (messages == null || messages.length == 0) {
|
||||
if (this instanceof Food) {
|
||||
player.getPacketDispatch().sendMessage("You eat the " + item.getName().trim().toLowerCase() + ".");
|
||||
} else if (this instanceof Drink) {
|
||||
player.getPacketDispatch().sendMessage("You drink some of " + (item.getName().contains("brew") ? "the foul liquid" : "your " + item.getName().replace("(4)", "").replace("(3)", "").replace("(2)", "").replace("(1)", "").trim().toLowerCase()) + ".");
|
||||
}
|
||||
if (player.getSkills().getLifepoints() > initial) {
|
||||
player.getPacketDispatch().sendMessage("It heals some health.");
|
||||
}
|
||||
} else {
|
||||
for (String message : messages) {
|
||||
player.getPacketDispatch().sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public Item getItem() {
|
||||
if (item != null) {
|
||||
return item;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties.
|
||||
* @return The properties.
|
||||
*/
|
||||
public ConsumableProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value if this consumable is a food.
|
||||
* @return the <code>True</code> if so.
|
||||
*/
|
||||
public boolean isFood() {
|
||||
return this instanceof Food;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value if this consumable is a drink.
|
||||
* @return the <code>True</code> if so.
|
||||
*/
|
||||
public boolean isDrink() {
|
||||
return this instanceof Drink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this consumable as a drink.
|
||||
* @return the drink.
|
||||
*/
|
||||
public Drink asDrink() {
|
||||
return ((Drink) this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the consumable as a food instance.
|
||||
* @return the food consumable.
|
||||
*/
|
||||
public Food asFood() {
|
||||
return ((Food) this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formated name of the item.
|
||||
* @param item the item.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName(Item item) {
|
||||
return item.getName().replace("(4)", "").replace("(3)", "").replace("(2)", "").replace("(1)", "").trim().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the emptying item.
|
||||
* @return the item.
|
||||
*/
|
||||
public Item getEmptyItem() {
|
||||
return emptyItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the empty message.
|
||||
* @return the message.
|
||||
*/
|
||||
public String getEmptyMessage(final Item item) {
|
||||
return emptyMessage == null ? EMPTY_MESSAGE.replace("@name", getName(item)) : emptyMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
Consumables.add(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package org.crandor.game.content.global.consumable;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents properties of a consumable. A consumable property lists the
|
||||
* healing amount, the new item when consumed, etc...
|
||||
* @author 'Vexia
|
||||
* @date 22/12/2013
|
||||
*/
|
||||
public class ConsumableProperties {
|
||||
|
||||
/**
|
||||
* Represents the amount the food can heal.
|
||||
*/
|
||||
private final int healing;
|
||||
|
||||
/**
|
||||
* Represents the new item when consumed (if any).
|
||||
*/
|
||||
private final Item newItem;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ConsumableProperties} {@code Object}.
|
||||
* @param healing the healing amount.
|
||||
* @param newItem the new item created (if any).
|
||||
*/
|
||||
public ConsumableProperties(int healing, Item newItem) {
|
||||
this.healing = healing;
|
||||
this.newItem = newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ConsumableProperties} {@code Object}.
|
||||
* @param healing the healing amount.
|
||||
* @param newItem the new item.
|
||||
*/
|
||||
public ConsumableProperties(int healing, int newItem) {
|
||||
this(healing, new Item(newItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ConsumableProperties} {@code Object}.
|
||||
* @param healing the healing power.
|
||||
*/
|
||||
public ConsumableProperties(int healing) {
|
||||
this(healing, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the healing.
|
||||
* @return The healing.
|
||||
*/
|
||||
public int getHealing() {
|
||||
return healing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the newItem.
|
||||
* @return The newItem.
|
||||
*/
|
||||
public Item getNewItem() {
|
||||
return newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value if the new item is not null.
|
||||
* @return <code>True</code> if there is a new item.
|
||||
*/
|
||||
public boolean hasNewItem() {
|
||||
return getNewItem() != null && getNewItem().getId() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
package org.crandor.game.content.global.consumable;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a repository of active consumables in the framework.
|
||||
* @author 'Vexia
|
||||
* @date 22/12/2013
|
||||
*/
|
||||
public enum Consumables {
|
||||
/** meats */
|
||||
CHICKEN(new Food(2140, 2138, 2144, new ConsumableProperties(3), new CookingProperties(1, 30, 30))), UGTHANKI(new Food(1861, 1859, 2146, new ConsumableProperties(2), new CookingProperties(1, 40, 40))), RABBIT(new Food(3228, 3226, 7222, new ConsumableProperties(5), new CookingProperties(1, 30, 30))),
|
||||
CRAB(new Food(7521, 7518, 7520, new ConsumableProperties(10), new CookingProperties(21, 100, 100))),
|
||||
DARK_CRAB(new Food(14939, 14937, 14941, new ConsumableProperties(22), new CookingProperties(90, 215, 100))),
|
||||
/** fish */
|
||||
KARAMBWANJI(new Food(3151, 3150, 592, new ConsumableProperties(3), new CookingProperties(1, 10, 30, "You cook the karambwanji.", "You accidentally burn the karambwanji to ashes."))), SARDINE(new Food(325, 327, 369, new ConsumableProperties(4), new CookingProperties(1, 40, 38))), ANCHOVIES(new Food(319, 321, 323, new ConsumableProperties(1), new CookingProperties(1, 30, 34))), HERRING(new Food(347, 345, 357, new ConsumableProperties(5), new CookingProperties(5, 50, 41))), MACKEREL(new Food(355, 353, 357, new ConsumableProperties(6), new CookingProperties(10, 60, 45))), TROUT(new Food(333, 335, 343, new ConsumableProperties(7), new CookingProperties(15, 70, 50, 49, 50))), COD(new Food(339, 341, 343, new ConsumableProperties(7), new CookingProperties(18, 75, 52))), PIKE(new Food(351, 349, 343, new ConsumableProperties(8), new CookingProperties(20, 80, 53))), SALMON(new Food(329, 331, 343, new ConsumableProperties(9), new CookingProperties(25, 58, 90))), SLIMY_EEL(new Food(3381, 3379, 3383, new ConsumableProperties(6), new CookingProperties(28, 95, 58))), TUNA(new Food(361, 359, 367, new ConsumableProperties(10), new CookingProperties(30, 100, 64, 63, 63))), RAINBOW_FISH(new Food(10136, 10138, 10140, new ConsumableProperties(11), new CookingProperties(35, 110, 60))), CAVE_EEL(new Food(5003, 5001, 5002, new ConsumableProperties(7), new CookingProperties(38, 115, 40))), LOBSTER(new Food(379, 377, 381, new ConsumableProperties(12), new CookingProperties(40, 120, 74, 74, 68))), BASS(new Food(365, 363, 367, new ConsumableProperties(13), new CookingProperties(43, 130, 80, 80, 70))), SWORDFISH(new Food(373, 371, 375, new ConsumableProperties(14), new CookingProperties(45, 140, 86, 86, 81))), LAVA_EEL(new Food(2149, 2148, 3383, new ConsumableProperties(14), new CookingProperties(53, 30, 53))), MONKFISH(new Food(7946, 7944, 7948, new ConsumableProperties(16), new CookingProperties(62, 150, 92, 90, 89))), SHARK(new Food(385, 383, 387, new ConsumableProperties(20), new CookingProperties(80, 210, 100, 100, 94))), SEA_TURTLE(new Food(397, 395, 399, new ConsumableProperties(21), new CookingProperties(82, 212, 100))), MANTA_RAY(new Food(391, 389, 393, new ConsumableProperties(22), new CookingProperties(91, 216, 100))), KARAMBWAN(new Food(3144, 3142, 3146, new ConsumableProperties(18), new CookingProperties(1, 80, 30))),
|
||||
/** snails */
|
||||
THIN_SNAIL(new Food(3369, 3363, 3375, new ConsumableProperties(5), new CookingProperties(12, 70, 70))), LEAN_SNAIL(new Food(3371, 3365, 3375, new ConsumableProperties(8), new CookingProperties(17, 80, 80))), FAT_SNAIL(new Food(3373, 3367, 3375, new ConsumableProperties(9), new CookingProperties(22, 95, 95))),
|
||||
/** cakes */
|
||||
TWO_THIRD_CAKE(new Food(1893, new ConsumableProperties(4, 1895))), SLICE_OF_CAKE(new Food(1895, new ConsumableProperties(4))), CHOCOLATE_CAKE(new Food(1897, new ConsumableProperties(5, 1899))), TWO_THIRD_CHOCOLATE_CAKE(new Food(1899, new ConsumableProperties(5, 1901))), SLICE_OF_CHOCOLATE_CAKE(new Food(1901, new ConsumableProperties(5))),
|
||||
/** special */
|
||||
PUMPKIN(new Food(1959, 14)), EASTER_EGG(new Food(1961, 14)),
|
||||
/** fruits */
|
||||
BANANA(new Food(1963, 2)), LEMON(new Food(2102, 2)), LIME(new Food(2120, 2)), ORANGE(new Food(2108, 2)), PAPAYA_FRUIT(new Food(5972, 2)), STRAWBERRY(new Food(5504, 2)), TOMATO(new Food(1982, 2)), PEACH(new Food(6883, 8)),
|
||||
/** vegetables */
|
||||
CABAGE(new Food(1965, 2, "You eat the cabbage. Yuck!")), ONION(new Food(1957, 2, "It's always sad to see a grown man/woman cry")), EVIL_TURNIP(new Food(12134, new ConsumableProperties(15, 12136))), EVIL_TURNIP_2_3(new Food(12136, new ConsumableProperties(15, 12138))), EVIL_TURNIP_1_3(new Food(12138, 15)),
|
||||
/** misc */
|
||||
SWEET_CORN(new Food(5988, 5986, 5990, new ConsumableProperties(3), new CookingProperties(28, 104, 70))), SODA_ASH(new Food(1781, 401, 1781, null, new CookingProperties(1, 1, 1, "You burn the seaweed into soda ash."))), BAKED_POTATO(new Food(6701, 1942, 6699, new ConsumableProperties(2), new CookingProperties(7, 15, 36, "You succesfully bake the potato.", CookingProperties.FAIL_MESSAGE))), POTATO_WITH_BUTTER(new Food(6703, new ConsumableProperties(7))), POTATO_WITH_CHEESE(new Food(6705, new ConsumableProperties(9))), EGG_POTATO(new Food(7056, new ConsumableProperties(11))), MUSHROOM_POTATO(new Food(7058, new ConsumableProperties(16))), TUNA_POTATO(new Food(7060, new ConsumableProperties(22))), CHILLI_POTATO(new Food(7054, new ConsumableProperties(14))), POT_OF_FLOUR(new Food(1933, 1931, "You empty the contents of the pot onto the floor.", null)), BONE_MEAL(new Food(4255, 1931, "You empty the pot of crushed bones.", null)), BUCKET_OF_SAND(new Food(1783, 1925, "You empty the contents of the bucket onto the floor.", null)), BUCKET_OF_MILK(new Food(1927, 1925, "You empty the contents of the bucket onto the floor.", null)), BUCKET_OF_WATER(new Food(1929, 1925, "You empty the contents of the bucket onto the floor.", null)), BUCKET_OF_COMPOST(new Food(6032, 1925, "You empty the bucket of compost.", null)), BUCKET_OF_SUPERCOMPOST(new Food(6034, 1925, "You empty the bucket of supercompost.", null)), BUCKET_OF_SLIME(new Food(4286, 1925, "You empty the contents of the bucket on the floor.", null)), VIAL_OF_WATER(new Food(227, Consumable.VIAL.getId(), "You empty the vial.", null)), BOWL_OF_SAND(new Food(1921, 1923, "You empty the contents of the bowl onto the floor.", null)), JUG_OF_WATER(new Food(1937, 1935, "You empty the contents of the jug onto the floor.", null)), BURNT_PIE(new Food(2329, 2313, "You empty the pie dish.", null)), FIELD_RATION(new Food(7934, new ConsumableProperties(12))),
|
||||
/** drinks */
|
||||
CHOCOLATEY_MILK(new Drink(1977, new ConsumableProperties(2, 1925))), CUP_OF_NETTLE_TEA(new Drink(4838, new ConsumableProperties(2, 1980))), GIN(new Drink(2019, new ConsumableProperties(2, 7921))), WHISKY(new Drink(2017, new ConsumableProperties(2, 7921))), VODKA(new Drink(2015, new ConsumableProperties(2, 7921))), JUG_OF_WINE(new Drink(1993, new ConsumableProperties(7, 1935))), KARAMJAN_RUN(new Drink(431, new ConsumableProperties(2))), KHALI_BREW(new Drink(77, new ConsumableProperties(2, 7921))), NETTLE_TEA(new Drink(4239, new ConsumableProperties(4, 1923))), BOTTLE_OF_WINE(new Drink(7919, new ConsumableProperties(2, 7921))),
|
||||
/** potions */
|
||||
STRENGTH_POTION(new Potion(PotionEffect.STRENGTH_POTION)), ATTACK_POTION(new Potion(PotionEffect.ATTACK_POTION)), DEFENCE_POTION(new Potion(PotionEffect.DEFENCE_POTION)), RANGING_POTION(new Potion(PotionEffect.RANGING_POTION)), MAGIC_POTION(new Potion(PotionEffect.MAGIC_POTION)), SUPER_STRENGTH_POTION(new Potion(PotionEffect.SUPER_STRENGTH)), SUPER_ATTACK_POTION(new Potion(PotionEffect.SUPER_ATTACK)), SUPER_DEFENCE_POTION(new Potion(PotionEffect.SUPER_DEFENCE)), AGILITY_POTION(new Potion(PotionEffect.AGILITY_POTION)), HUNTER_POTION(new Potion(PotionEffect.HUNTER_POTION));
|
||||
|
||||
/**
|
||||
* Represents the consumable.
|
||||
*/
|
||||
private Consumable consumable;
|
||||
|
||||
/**
|
||||
* Represents the list of foods only. This list can be used for direct
|
||||
* searching.
|
||||
*/
|
||||
private static final List<Food> FOODS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Represents te list of drinks only. This list can be used for direct
|
||||
* searching.
|
||||
*/
|
||||
private static final List<Drink> DRINKS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Represents the list of all consumables.
|
||||
*/
|
||||
private static final List<Consumable> CONSUMABLES = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Consumables} {@code Object}.
|
||||
* @param consumable the consumbale.
|
||||
*/
|
||||
Consumables(Consumable consumable) {
|
||||
this.consumable = consumable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Consumables} {@code Object}.
|
||||
* @param consumable the consumable.
|
||||
* @param drinkSet the drinkset.
|
||||
*/
|
||||
Consumables(Drink drink) {
|
||||
this.consumable = drink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the food.
|
||||
* @return The food.
|
||||
*/
|
||||
public Consumable getConsumable() {
|
||||
return consumable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of foods.
|
||||
* @return the foods.
|
||||
*/
|
||||
public static List<Food> getFoods() {
|
||||
return FOODS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the {@link Consumable} by the item associated with it.
|
||||
* @param raw the raw item.
|
||||
* @return the consumable.
|
||||
*/
|
||||
public static Consumable forConsumable(final Item item) {
|
||||
for (Consumable consumable : CONSUMABLES) {
|
||||
if (consumable.isDrink()) {
|
||||
Consumable d = forDrink(item);
|
||||
if (d != null) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
if (consumable.getItem().getId() == item.getId()) {
|
||||
return consumable;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the {@link Food} by the item associated with it.
|
||||
* @note this is a more direct search.
|
||||
* @param item the item.
|
||||
* @return the food.
|
||||
*/
|
||||
public static Food forFood(final Item item) {
|
||||
for (Food food : FOODS) {
|
||||
if (food.getItem().getId() == item.getId()) {
|
||||
return food;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the {@link Food} by the raw item associated with it.
|
||||
* @param raw the raw item.
|
||||
* @return the food.
|
||||
*/
|
||||
public static Food forRaw(final Item raw) {
|
||||
for (Food food : FOODS) {
|
||||
if (food.hasRaw() && food.getRaw().getId() == raw.getId()) {
|
||||
return food;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the {@link Food} by the raw item associated with it.
|
||||
* @param raw the raw item.
|
||||
* @return the food.
|
||||
*/
|
||||
public static Food forRaw(final int raw) {
|
||||
for (Food food : FOODS) {
|
||||
if (food.hasRaw() && food.getRaw().getId() == raw) {
|
||||
return food;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the {@link Drink} by the item id.
|
||||
* @param item the item.
|
||||
* @return the drink.
|
||||
*/
|
||||
public static Drink forDrink(final Item item) {
|
||||
for (Drink drink : DRINKS) {
|
||||
if (item.getId() == drink.getItem().getId()) {
|
||||
return drink;
|
||||
}
|
||||
if (drink.getDrinks() == null) {
|
||||
continue;
|
||||
}
|
||||
for (Item i : drink.getDrinks()) {
|
||||
if (i.getId() == item.getId()) {
|
||||
return drink;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to add a consumable to its search engine.
|
||||
* @param consumable the consumable.
|
||||
*/
|
||||
public static void add(final Consumable consumable) {
|
||||
if (consumable.isDrink()) {
|
||||
DRINKS.add(consumable.asDrink());
|
||||
} else {
|
||||
FOODS.add(consumable.asFood());
|
||||
}
|
||||
CONSUMABLES.add(consumable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static modifier used to populate search engine lists.
|
||||
*/
|
||||
static {
|
||||
for (Consumables consumable : Consumables.values()) {
|
||||
if (consumable.getConsumable().isFood()) {
|
||||
FOODS.add(consumable.getConsumable().asFood());
|
||||
} else if (consumable.getConsumable().isDrink()) {
|
||||
DRINKS.add(consumable.getConsumable().asDrink());
|
||||
}
|
||||
CONSUMABLES.add(consumable.getConsumable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
package org.crandor.game.content.global.consumable;
|
||||
|
||||
import org.crandor.game.content.global.SkillcapePerks;
|
||||
import org.crandor.game.content.skill.Skills;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.game.node.entity.player.info.portal.Perks;
|
||||
import org.crandor.game.node.entity.player.link.audio.Audio;
|
||||
import org.crandor.game.node.item.Item;
|
||||
import org.crandor.game.node.object.GameObject;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* Represents the properties used when cooking the food.
|
||||
* @author 'Vexia
|
||||
* @date 22/12/2013
|
||||
*/
|
||||
public class CookingProperties {
|
||||
|
||||
/**
|
||||
* Represents the secure random.
|
||||
*/
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
/**
|
||||
* Represents the cooking sound.
|
||||
*/
|
||||
private static final Audio SOUND = new Audio(65, 10, 0);
|
||||
|
||||
/**
|
||||
* Represents the cooking gauntlets item.
|
||||
*/
|
||||
private static final Item GAUNTLETS = new Item(775);
|
||||
|
||||
/**
|
||||
* Represents the fail message to display when burning food.
|
||||
*/
|
||||
public static final String FAIL_MESSAGE = "Oops! You accidently burnt the @name..";
|
||||
|
||||
/**
|
||||
* Represents the level needed to cook the item.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* Represents the cooking experience gained.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* Represents the level the food stops burning at on the fire.
|
||||
*/
|
||||
private final int fireBurnLevel;
|
||||
|
||||
/**
|
||||
* Represents the level the food stops burning at on the range.
|
||||
*/
|
||||
private final int rangeBurnLevel;
|
||||
|
||||
/**
|
||||
* Represents the level the food stops burning at when wearing gauntlets.
|
||||
*/
|
||||
private final int gauntletsBurnLevel;
|
||||
|
||||
/**
|
||||
* Represents if its a range only food (meaning only can be used on a range
|
||||
* not fire).
|
||||
*/
|
||||
private final boolean range;
|
||||
|
||||
/**
|
||||
* Represents if its an iron spit roast.
|
||||
*/
|
||||
private final boolean spit;
|
||||
|
||||
/**
|
||||
* Represents the messages displayed when cooking.
|
||||
*/
|
||||
private String[] messages = null;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CookingProperties} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param fireBurnLevel the burning level.
|
||||
* @param rangeBurnLevel the burning level on the range.
|
||||
* @param gauntletsBurnLevel the burning level with gauntlets.
|
||||
* @param range if the food can only be used on a range.
|
||||
* @param spit if its an iron spit item.
|
||||
*/
|
||||
public CookingProperties(int level, double experience, int burnLevel, int rangeBurnLevel, int gauntletsBurnLevel, boolean range, boolean spit, final String... messages) {
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.fireBurnLevel = burnLevel;
|
||||
this.rangeBurnLevel = rangeBurnLevel;
|
||||
this.gauntletsBurnLevel = gauntletsBurnLevel;
|
||||
this.range = range;
|
||||
this.spit = spit;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CookingProperties} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param fireBurnLevel the burning level.
|
||||
* @param messages the messages
|
||||
*/
|
||||
public CookingProperties(final int level, final double experience, final int burnLevel, final String... messages) {
|
||||
this(level, experience, burnLevel, burnLevel, burnLevel, false, false, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CookingProperties} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param fireBurnLevel the burning level.
|
||||
* @param range if its a range item.
|
||||
* @param spit if its on an iron spit.
|
||||
* @param messages the messages
|
||||
*/
|
||||
public CookingProperties(final int level, final double experience, final int burnLevel, boolean range, boolean spit, final String... messages) {
|
||||
this(level, experience, burnLevel, burnLevel, burnLevel, false, spit, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CookingProperties} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param fireBurnLevel the burning level.
|
||||
* @param range if its only cookable on the range
|
||||
* @param messages the messages
|
||||
*/
|
||||
public CookingProperties(final int level, final double experience, final int burnLevel, final boolean range, final String... messages) {
|
||||
this(level, experience, burnLevel, burnLevel, burnLevel, range, false, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code CookingProperties} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param fireBurnLevel the burning level.
|
||||
* @param rangeBurnLevel the range burning level.
|
||||
* @param gauntLetsBurnLevel the gauntletsBurn level.
|
||||
*/
|
||||
public CookingProperties(final int level, final double experience, final int burnLevel, final int rangeBurnLevel, final int gauntletsBurnLevel) {
|
||||
this(level, experience, burnLevel, rangeBurnLevel, gauntletsBurnLevel, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to cook a food. This method can be overried to intercept the
|
||||
* way a food is cooked. A prime example of how this can be used is with the
|
||||
* sinew consumable food.
|
||||
* @param food the food we're cooking.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
* @return <code>True</code> if we we're succesfull.
|
||||
*/
|
||||
public boolean cook(final Food food, final Player player, final GameObject object) {
|
||||
return cook(food, player, object, isBurned(player, object));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to cook a food. This method can be overried to intercept the
|
||||
* way a food is cooked. A prime example of how this can be used is with the
|
||||
* sinew consumable food.
|
||||
* @param food the food we're cooking.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
* @param if it's burned.
|
||||
* @return <code>True</code> if we we're succesfull.
|
||||
*/
|
||||
public boolean cook(final Food food, final Player player, final GameObject object, final boolean burned) {
|
||||
if (player.getInventory().remove(food.getRaw())) {
|
||||
if (!burned) {
|
||||
Perks.addDouble(player, food.getItem());
|
||||
} else {
|
||||
player.getInventory().add(food.getBurnt());
|
||||
}
|
||||
player.getSkills().addExperience(Skills.COOKING, burned ? 0 : getExperience(), true);
|
||||
player.getPacketDispatch().sendMessage(getMessage(food, player, object, burned));
|
||||
player.getAudioManager().send(SOUND);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fireBurnLevel.
|
||||
* @return The fireBurnLevel.
|
||||
*/
|
||||
public int getBurnLevel() {
|
||||
return fireBurnLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the range.
|
||||
* @return The range.
|
||||
*/
|
||||
public boolean isRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fireBurnLevel.
|
||||
* @return The fireBurnLevel.
|
||||
*/
|
||||
public int getFireBurnLevel() {
|
||||
return fireBurnLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rangeBurnLevel.
|
||||
* @return The rangeBurnLevel.
|
||||
*/
|
||||
public int getRangeBurnLevel() {
|
||||
return rangeBurnLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the gauntletsBurnLevel.
|
||||
* @return The gauntletsBurnLevel.
|
||||
*/
|
||||
public int getGauntletsBurnLevel() {
|
||||
return gauntletsBurnLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the spit.
|
||||
* @return The spit.
|
||||
*/
|
||||
public boolean isSpit() {
|
||||
return spit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the burning level depicted by if the player has cooking gauntlets
|
||||
* on, or effected by the object they are interactign with.
|
||||
* @param player the player cooking.
|
||||
* @param object the object we check.
|
||||
* @return the level at which the player stops burning.
|
||||
*/
|
||||
private final int getBurnLevel(final Player player, final GameObject object) {
|
||||
return player.getEquipment().containsItem(GAUNTLETS) ? gauntletsBurnLevel : object.getName().toLowerCase().equals("fire") ? fireBurnLevel : rangeBurnLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the true/false value if the food is burned by the player.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
* @return <code>True</code> if the food is burned or not.
|
||||
*/
|
||||
public boolean isBurned(final Player player, final GameObject object) {
|
||||
if (SkillcapePerks.hasSkillcapePerk(player, SkillcapePerks.COOKING)) {
|
||||
return false;
|
||||
}
|
||||
if (player.getSkills().getLevel(Skills.COOKING) > getBurnLevel(player, object)) {
|
||||
return false;
|
||||
}
|
||||
double burn_chance = 60.0 + (object.getName().equals("fire") ? 1.00 : 0) - (object.getId() == 114 ? 1.00 : 0);
|
||||
if (player.getDetails().getShop().hasPerk(Perks.MASTER_CHEF)) {
|
||||
burn_chance -= (burn_chance * 0.20);
|
||||
}
|
||||
double cook_level = (double) player.getSkills().getLevel(Skills.COOKING);
|
||||
double lev_needed = (double) getLevel();
|
||||
double burn_stop = (double) getBurnLevel(player, object);
|
||||
double multi_a = (burn_stop - lev_needed);
|
||||
double burn_dec = (burn_chance / multi_a);
|
||||
double multi_b = (cook_level - lev_needed);
|
||||
burn_chance -= (multi_b * burn_dec);
|
||||
double randNum = RANDOM.nextDouble() * 100.0;
|
||||
return burn_chance <= randNum ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message displayed when the food is cooked or burned.
|
||||
* @param food the food we're cooking/burning.
|
||||
* @param player the player.
|
||||
* @param object the object we're cooking on.
|
||||
* @param burned if the food is burned.
|
||||
* @return the message to display.
|
||||
*/
|
||||
public String getMessage(final Food food, final Player player, final GameObject object, final boolean burned) {
|
||||
return messages != null && messages.length != 0 ? messages[burned ? 1 : 0].replace("@name", food.getItem().getName().toLowerCase()) : burned ? FAIL_MESSAGE.replace("@name", food.getItem().getName().toLowerCase()) + "." : "You successfully cook the " + food.getItem().getName().toLowerCase() + ".";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue