Players can no longer walk where there is no map data
Fixed an issue that prevented teleblock from being used in PvP Removed redundant code that prevented PvP looting in some instances Improved strictness of grave generation rules in regards to PvP Added nothing drop to the RDT (50% chance) Implemented ring of wealth effect on rare drops (removes nothing drop) Improved handling of nothing drops, preventing dwarf remains being awarded instead of nothing in some instances Added impling IDs to the ImplingNPC definition so all implings behave like implings Crystal shield and crystal bow now degrade Made cyclops room kickout on disconnect more reliable Fixed MTA Enchantment Zone items not adhering to the zone's rules
This commit is contained in:
@@ -1,96 +0,0 @@
|
||||
package content.data.tables;
|
||||
|
||||
import core.api.StartupListener;
|
||||
import core.ServerConstants;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.item.WeightedChanceItem;
|
||||
import core.tools.SystemLogger;
|
||||
import core.tools.RandomFunction;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static core.tools.SystemLogger.logInfo;
|
||||
|
||||
/**
|
||||
* Handles the rare drop table.
|
||||
* @author Ceikry
|
||||
*/
|
||||
public final class RareDropTable implements StartupListener {
|
||||
|
||||
/**
|
||||
* The item id of the item representing the rare drop table slot in a drop
|
||||
* table.
|
||||
*/
|
||||
public static final int SLOT_ITEM_ID = 31;
|
||||
|
||||
/**
|
||||
* The rare drop table.
|
||||
*/
|
||||
private static final List<WeightedChanceItem> TABLE = new ArrayList<>(20);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize needed objects for xml reading/writing
|
||||
*/
|
||||
static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
static DocumentBuilder builder;
|
||||
|
||||
static {
|
||||
try {
|
||||
builder = factory.newDocumentBuilder();
|
||||
} catch (ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public RareDropTable() throws ParserConfigurationException {}
|
||||
|
||||
@Override
|
||||
public void startup() {
|
||||
if(ServerConstants.RDT_DATA_PATH != null && !new File(ServerConstants.RDT_DATA_PATH).exists()){
|
||||
SystemLogger.logErr(this.getClass(), "Can't locate RDT file at " + ServerConstants.RDT_DATA_PATH);
|
||||
return;
|
||||
}
|
||||
parse(ServerConstants.RDT_DATA_PATH);
|
||||
logInfo(this.getClass(), "Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the xml file for the RDT.
|
||||
* @param file the .xml file containing the RDT.
|
||||
*/
|
||||
public static void parse(String file){
|
||||
try {
|
||||
Document doc = builder.parse(file);
|
||||
|
||||
NodeList itemNodes = doc.getElementsByTagName("item");
|
||||
for(int i = 0; i < itemNodes.getLength(); i++){
|
||||
Node itemNode = itemNodes.item(i);
|
||||
if(itemNode.getNodeType() == Node.ELEMENT_NODE){
|
||||
Element item = (Element) itemNode;
|
||||
int itemId = Integer.parseInt(item.getAttribute("id"));
|
||||
int minAmt = Integer.parseInt(item.getAttribute("minAmt"));
|
||||
int maxAmt = Integer.parseInt(item.getAttribute("maxAmt"));
|
||||
int weight = Integer.parseInt(item.getAttribute("weight"));
|
||||
|
||||
TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight));
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Item retrieve(){
|
||||
return RandomFunction.rollWeightedChanceTable(TABLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package content.data.tables
|
||||
|
||||
import core.ServerConstants
|
||||
import core.api.StartupListener
|
||||
import core.api.shouldRemoveNothings
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.tools.RandomFunction
|
||||
import core.tools.SystemLogger.logErr
|
||||
import core.tools.SystemLogger.logInfo
|
||||
import org.rs09.consts.Items
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.Node
|
||||
import java.io.File
|
||||
import javax.xml.parsers.DocumentBuilder
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.parsers.ParserConfigurationException
|
||||
|
||||
/**
|
||||
* Handles the rare drop table.
|
||||
* @author Ceikry
|
||||
*/
|
||||
class RareDropTable : StartupListener {
|
||||
override fun startup() {
|
||||
if (ServerConstants.RDT_DATA_PATH != null && !File(ServerConstants.RDT_DATA_PATH).exists()) {
|
||||
logErr(this.javaClass, "Can't locate RDT file at " + ServerConstants.RDT_DATA_PATH)
|
||||
return
|
||||
}
|
||||
parse(ServerConstants.RDT_DATA_PATH)
|
||||
logInfo(this.javaClass, "Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TABLE: WeightBasedTable = object : WeightBasedTable() {
|
||||
override fun roll(receiver: Entity?): ArrayList<Item> {
|
||||
val items = ArrayList(guaranteedItems)
|
||||
var effectiveWeight = totalWeight
|
||||
val p = if (receiver is Player) receiver else null
|
||||
if (p != null && shouldRemoveNothings(p))
|
||||
effectiveWeight -= nothingWeight
|
||||
|
||||
if (this.size == 1) {
|
||||
items.add(get(0))
|
||||
} else if (!this.isEmpty()) {
|
||||
var rngWeight = RandomFunction.randomDouble(effectiveWeight)
|
||||
for (item in this.shuffled()) {
|
||||
if (item.id == Items.DWARF_REMAINS_0) continue
|
||||
rngWeight -= item.weight
|
||||
if (rngWeight <= 0) {
|
||||
items.add(item)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return convertWeightedItems(items, receiver)
|
||||
}
|
||||
|
||||
private val nothingWeight: Double
|
||||
get() {
|
||||
var sum = 0.0
|
||||
for (i in this) {
|
||||
if (i.id == Items.DWARF_REMAINS_0)
|
||||
sum += i.weight
|
||||
}
|
||||
return sum
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize needed objects for xml reading/writing
|
||||
*/
|
||||
var factory = DocumentBuilderFactory.newInstance()
|
||||
var builder: DocumentBuilder? = null
|
||||
|
||||
init {
|
||||
try {
|
||||
builder = factory.newDocumentBuilder()
|
||||
} catch (e: ParserConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the xml file for the RDT.
|
||||
* @param file the .xml file containing the RDT.
|
||||
*/
|
||||
fun parse(file: String?) {
|
||||
try {
|
||||
val doc = builder!!.parse(file)
|
||||
val itemNodes = doc.getElementsByTagName("item")
|
||||
for (i in 0 until itemNodes.length) {
|
||||
val itemNode = itemNodes.item(i)
|
||||
if (itemNode.nodeType == Node.ELEMENT_NODE) {
|
||||
val item = itemNode as Element
|
||||
val itemId = item.getAttribute("id").toInt()
|
||||
val minAmt = item.getAttribute("minAmt").toInt()
|
||||
val maxAmt = item.getAttribute("maxAmt").toInt()
|
||||
val weight = item.getAttribute("weight").toInt()
|
||||
TABLE.add(WeightedItem(itemId, minAmt, maxAmt, weight.toDouble(), false))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun retrieve(receiver: Entity?): Item? {
|
||||
return TABLE.roll(receiver).getOrNull(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,19 +128,19 @@ public enum ClueLevel {
|
||||
for (; itemCount > 0; itemCount--) {
|
||||
switch (level) {
|
||||
case EASY:
|
||||
loot.addAll(ClueRewardParser.getEasyTable().roll());
|
||||
loot.addAll(ClueRewardParser.getEasyTable().roll(player));
|
||||
break;
|
||||
case MEDIUM:
|
||||
loot.addAll(ClueRewardParser.getMedTable().roll());
|
||||
loot.addAll(ClueRewardParser.getMedTable().roll(player));
|
||||
break;
|
||||
case HARD:
|
||||
loot.addAll(ClueRewardParser.getHardTable().roll());
|
||||
loot.addAll(ClueRewardParser.getHardTable().roll(player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (level == ClueLevel.HARD && RandomFunction.random(100) == 50) {
|
||||
loot.addAll(ClueRewardParser.getRareTable().roll());
|
||||
loot.addAll(ClueRewardParser.getRareTable().roll(player));
|
||||
}
|
||||
|
||||
return loot;
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package content.global.handlers.iface;
|
||||
|
||||
import core.game.component.Component;
|
||||
import core.game.component.ComponentDefinition;
|
||||
import core.game.component.ComponentPlugin;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Package -> core.game.interaction.inter
|
||||
* Created on -> 9/6/2016 @8:12 PM for 530
|
||||
*
|
||||
* @author Ethan Kyle Millard
|
||||
*/
|
||||
@Initializable
|
||||
public class PlayerExamineInterfacePlugin extends ComponentPlugin {
|
||||
|
||||
private Player node;
|
||||
|
||||
public PlayerExamineInterfacePlugin() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ComponentDefinition.put(31, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||
switch (button) {
|
||||
case 2:
|
||||
component.close(player);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void prepareInterface(Player player, Player examined) {
|
||||
Component component = new Component(31);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 7, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 8, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 15, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 18, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 2, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 14, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(component.getId(), 13, true);
|
||||
player.getInterfaceManager().open(component);
|
||||
player.getPacketDispatch().sendString("<col=" + examined.getSavedData().getSpawnData().getTitle().getTitleColor() + ">" + examined.getSavedData().getSpawnData().getTitle().getName() + "</col> " + StringUtils.formatDisplayName(examined.getName()) + " - Combat Level: " + player.getProperties().getCurrentCombatLevel(), 31, 3);
|
||||
player.getPacketDispatch().sendString("Total Level -> ", 31, 9);
|
||||
player.getPacketDispatch().sendString("Inventory items -> ", 31, 10);
|
||||
player.getPacketDispatch().sendString("Inventory value -> ", 31, 16);
|
||||
player.getPacketDispatch().sendString("Custom state-> ", 31, 19);
|
||||
player.getPacketDispatch().sendString("" + examined.getSkills().getTotalLevel(), 31, 11);
|
||||
player.getPacketDispatch().sendString("" + examined.getInventory().itemCount(), 31, 12);
|
||||
player.getPacketDispatch().sendString("" + examined.getInventory().getWealth(), 31, 17);
|
||||
player.getPacketDispatch().sendString("" + examined.getCustomState(), 31, 20);
|
||||
player.getPacketDispatch().sendString("Close", 31, 5);
|
||||
|
||||
for (int i = 0; i < 11; i++) {
|
||||
Item item = examined.getEquipment().get(i);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
System.out.println(item.getName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public final class CasketPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
final Item reward = table.roll().get(0);
|
||||
final Item reward = table.roll(player).get(0);
|
||||
player.getInventory().remove((Item) node);
|
||||
player.getDialogueInterpreter().sendItemMessage(reward, "You open the casket. Inside you find " + (reward.getAmount() > 1 ? "some" : (StringUtils.isPlusN(reward.getName()) ? "an" : "a")) + " " + reward.getName().toLowerCase() + ".");
|
||||
addItemOrDrop(player, reward.getId(), reward.getAmount());
|
||||
|
||||
@@ -16,7 +16,7 @@ class ImplingJarListener : InteractionListener {
|
||||
on(JARS, IntType.ITEM, "loot"){ player, node ->
|
||||
val jar = node.asItem()
|
||||
|
||||
val loot = ImplingLoot.forId(jar.id)?.roll()?.first() ?: return@on false
|
||||
val loot = ImplingLoot.forId(jar.id)?.roll()?.firstOrNull() ?: return@on false
|
||||
|
||||
if(removeItem(player, jar, Container.INVENTORY)) {
|
||||
addItemOrDrop(player, loot.id, loot.amount)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package content.global.handlers.item.equipment
|
||||
|
||||
import core.api.StartupListener
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class CrystalEquipmentRegister : StartupListener {
|
||||
val shield: Array<Int> = arrayOf(Items.NEW_CRYSTAL_SHIELD_4224, Items.CRYSTAL_SHIELD_FULL_4225, Items.CRYSTAL_SHIELD_9_10_4226, Items.CRYSTAL_SHIELD_8_10_4227, Items.CRYSTAL_SHIELD_7_10_4228, Items.CRYSTAL_SHIELD_6_10_4229, Items.CRYSTAL_SHIELD_5_10_4230, Items.CRYSTAL_SHIELD_4_10_4231, Items.CRYSTAL_SHIELD_3_10_4232, Items.CRYSTAL_SHIELD_2_10_4233, Items.CRYSTAL_SHIELD_1_10_4234, Items.CRYSTAL_SEED_4207)
|
||||
val bow: Array<Int> = arrayOf(Items.NEW_CRYSTAL_BOW_4212, Items.CRYSTAL_BOW_FULL_4214, Items.CRYSTAL_BOW_9_10_4215, Items.CRYSTAL_BOW_8_10_4216, Items.CRYSTAL_BOW_7_10_4217, Items.CRYSTAL_BOW_6_10_4218, Items.CRYSTAL_BOW_5_10_4219, Items.CRYSTAL_BOW_4_10_4220, Items.CRYSTAL_BOW_3_10_4221, Items.CRYSTAL_BOW_2_10_4222, Items.CRYSTAL_BOW_1_10_4223, Items.CRYSTAL_SEED_4207)
|
||||
override fun startup() {
|
||||
EquipmentDegrader.registerSet(250, shield)
|
||||
EquipmentDegrader.registerSet(250, bow)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package content.global.handlers.item.equipment
|
||||
|
||||
import core.api.addItemOrDrop
|
||||
import core.api.getNext
|
||||
import core.api.isLast
|
||||
import core.api.isNextLast
|
||||
@@ -51,6 +52,9 @@ class EquipmentDegrader{
|
||||
|
||||
fun Item.degrade(slot: Int){ //extension function that degrades items
|
||||
val set = getDegradableSet(this.id)
|
||||
val charges = itemCharges.getOrElse(this.id) {1000}
|
||||
if (this.charge > charges)
|
||||
charge = charges
|
||||
this.charge--
|
||||
if(set?.indexOf(this.id) == 0 && !this.name.contains("100")){
|
||||
charge = 0
|
||||
@@ -60,8 +64,8 @@ class EquipmentDegrader{
|
||||
if (set?.size!! > 2) {
|
||||
p?.equipment?.remove(this)
|
||||
p?.sendMessage("Your $name has degraded.")
|
||||
if (set.isNextLast(set.indexOf(this.id))) {
|
||||
p?.inventory?.add(Item(set.getNext(this.id)))
|
||||
if (set.isNextLast(this.id)) {
|
||||
p?.let { addItemOrDrop(it, set.getNext(this.id)) }
|
||||
p?.sendMessage("Your $name has broken.")
|
||||
} else {
|
||||
p?.equipment?.add(Item(set.getNext(this.id), 1, charges), slot, false, false)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package content.global.handlers.player;
|
||||
|
||||
import core.game.interaction.Option;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.global.handlers.iface.PlayerExamineInterfacePlugin;
|
||||
|
||||
/**
|
||||
* Package -> core.game.interaction.player
|
||||
* Created on -> 9/13/2016 @7:53 AM for 530
|
||||
*
|
||||
* @author Ethan Kyle Millard
|
||||
*/
|
||||
@Initializable
|
||||
public class ExamineOptionPlugin extends OptionHandler {
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
Option._P_EXAMINE.setHandler(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
PlayerExamineInterfacePlugin component = new PlayerExamineInterfacePlugin();
|
||||
component.prepareInterface(player, (Player) node);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import core.game.system.task.Pulse;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.path.Pathfinder;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.plugin.Initializable;
|
||||
import core.tools.RandomFunction;
|
||||
import core.game.system.config.NPCConfigParser;
|
||||
import core.game.world.GameWorld;
|
||||
@@ -18,6 +19,7 @@ import core.game.world.GameWorld;
|
||||
* Handles an impling npc.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public final class ImplingNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
@@ -104,7 +106,7 @@ public final class ImplingNPC extends AbstractNPC {
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] {};
|
||||
return new int[] { 1028, 6055, 1029, 6056, 1030, 6057, 1031, 6058, 1032, 6059, 1033, 6060, 1034, 6061, 1035, 6062, 6053, 6063};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,7 +112,7 @@ public final class TeleblockSpell extends CombatSpell {
|
||||
|
||||
@Override
|
||||
public void fireEffect(Entity entity, Entity victim, BattleState state) {
|
||||
if(!victim.isTeleBlocked() && victim instanceof Player && state.getStyle().getSwingHandler().isAccurateImpact(entity, victim) && state.getEstimatedHit() > 0){
|
||||
if(!victim.isTeleBlocked() && victim instanceof Player && state.getStyle().getSwingHandler().isAccurateImpact(entity, victim)){
|
||||
int ticks = 500;
|
||||
if(((Player) victim).getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)){
|
||||
ticks /= 2;
|
||||
|
||||
@@ -178,6 +178,9 @@ public class EnchantingZone extends MTAZone {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemainPrivate() {return true;}
|
||||
|
||||
@Override
|
||||
public void respawn() {
|
||||
GameWorld.getPulser().submit(getRespawnPulse(this));
|
||||
|
||||
+10
@@ -30,6 +30,11 @@ import core.game.world.map.zone.ZoneRestriction;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
|
||||
import static core.api.ContentAPIKt.clearLogoutListener;
|
||||
import static core.api.ContentAPIKt.registerLogoutListener;
|
||||
|
||||
/**
|
||||
* The cyclopes room.
|
||||
@@ -103,6 +108,7 @@ public final class CyclopesRoom extends MapZone implements Plugin<Object> {
|
||||
if (logout) {
|
||||
e.setLocation(Location.create(2846, 3540, 2));
|
||||
}
|
||||
clearLogoutListener((Player) e, "cyclopes");
|
||||
}
|
||||
return super.leave(e, logout);
|
||||
}
|
||||
@@ -199,6 +205,10 @@ public final class CyclopesRoom extends MapZone implements Plugin<Object> {
|
||||
PULSE.start();
|
||||
GameWorld.getPulser().submit(PULSE);
|
||||
}
|
||||
registerLogoutListener(player, "cyclopes", player1 -> {
|
||||
player1.setLocation(Location.create(2844, 3540, 2));
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user