MoparClassic/GameServer/src/msc/config/Formulae.java

1206 lines
41 KiB
Java
Raw Normal View History

package msc.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import msc.gs.external.EntityHandler;
import msc.gs.external.FiremakingDef;
import msc.gs.external.GameObjectLoc;
import msc.gs.external.ItemLoc;
import msc.gs.external.NPCLoc;
import msc.gs.external.ObjectFishDef;
import msc.gs.external.ObjectMiningDef;
import msc.gs.external.ObjectWoodcuttingDef;
import msc.gs.external.SpellDef;
import msc.gs.model.Entity;
import msc.gs.model.GameObject;
import msc.gs.model.InvItem;
import msc.gs.model.Mob;
import msc.gs.model.Npc;
import msc.gs.model.Player;
import msc.gs.model.Point;
import msc.gs.model.Shop;
import msc.gs.tools.DataConversions;
public class Formulae {
public static final Point[] noremoveTiles = {new Point(341,487), new Point(343,581), new Point(92,649), new Point(434,682), new Point(660,551), new Point(196,3266), new Point(59,573), new Point(560,472), new Point(140,180), new Point(285,195), new Point(243,178), new Point(394,851), new Point(388,851), new Point(512,550)};
public static final int[] arrowIDs = { 723, 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, 574, 11 };
public static final int[] bodySprites = { 2, 5 };
public static final int[] boltIDs = { 786, 592, 190 };
public static final int[] bowIDs = { 188, 189, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657 };
// spell
public static final int[] experienceArray = { 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584, 1833, 2107, 2411, 2746, 3115, 3523, 3973, 4470, 5018, 5624, 6291, 7028, 7842, 8740, 9730, 10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406, 24815, 27473, 30408, 33648, 37224, 41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014, 91721, 101333, 111945, 123660, 136594, 150872, 166636, 184040, 203254, 224466, 247886, 273742, 302288, 333804, 368599, 407015, 449428, 496254, 547953, 605032, 668051, 737627, 814445, 899257, 992895, 1096278, 1210421, 1336443, 1475581, 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373, 3258594, 3597792, 3972294, 4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614, 8771558, 9684577, 10692629, 11805606, 13034431, 14391160 };
public static final int[] headSprites = { 1, 4, 6, 7, 8 };
public static final int[] miningAxeIDs = { 1262, 1261, 1260, 1259, 1258, 156 };
public static final int[] miningAxeLvls = { 41, 31, 21, 6, 1, 1 };
/**
* Cubic P2P boundaries. MinX, MinY - MaxX, MaxY
*/
public static final java.awt.Point[][] F2PWILD_LOCS = {{new java.awt.Point(48, 96), new java.awt.Point(335, 142)} };
public static final java.awt.Point[][] P2P_LOCS = { { new java.awt.Point(436, 432), new java.awt.Point(719, 906) }, { new java.awt.Point(48, 96), new java.awt.Point(335, 142) }, { new java.awt.Point(343, 567), new java.awt.Point(457, 432) }, { new java.awt.Point(203, 3206), new java.awt.Point(233, 3265) }, { new java.awt.Point(397, 525), new java.awt.Point(441, 579), }, { new java.awt.Point(431, 0), new java.awt.Point(1007, 1007) } };
public static final int[] potions1Dose = { 224, 476, 479, 482, 485, 488, 491, 494, 497, 500, 568, 571 };
public static final int[] potions2Dose = { 223, 475, 478, 481, 484, 487, 490, 493, 496, 499, 567, 570 };
public static final int[] potions3Dose = { 222, 474, 477, 480, 483, 486, 489, 492, 495, 498, 566, 569 };
public static final int[] potionsUnfinished = { 454, 455, 456, 457, 458, 459, 460, 461, 462, 463 };
private static Random r = new Random();
public static final int[] runeIDs = { 31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 46, 619, 825 };
public static final int[] safePacketIDs = { 70, 123, 128, 255 };
public static final String[] statArray = { "attack", "defense", "strength", "hits", "ranged", "prayer", "magic", "cooking", "woodcut", "fletching", "fishing", "firemaking", "crafting", "smithing", "mining", "herblaw", "agility", "thieving" };
public static final int[] woodcuttingAxeIDs = { 405, 204, 203, 428, 88, 12, 87 };
public static final int[] xbowIDs = { 59, 60 };
public static ArrayList<Point> dray2edge = new ArrayList<Point>();
/**
* Array of items that cannot be telegrabbed.
*/
public static int[] telegrabBlocked = { 828, 831, 832, 1289, 422, 1315, 1314, 1316, 971 };
static
{
dray2edge.add(new Point(114,638));
dray2edge.add(new Point(120,621));
dray2edge.add(new Point(131,612));
dray2edge.add(new Point(159,596));
dray2edge.add(new Point(195,583));
dray2edge.add(new Point(201,562));
dray2edge.add(new Point(200,540));
dray2edge.add(new Point(227,501));
dray2edge.add(new Point(225,460));
dray2edge.add(new Point(206,448));
}
/**
* Adds the prayers together to calculate what perecntage the stat should be
* increased
*/
public static double addPrayers(boolean first, boolean second, boolean third) {
if (third) {
return 1.15D;
}
if (second) {
return 1.1D;
}
if (first) {
return 1.05D;
}
return 1.0D;
}
/**
* Returns a power to assosiate with each arrow
*/
private static double arrowPower(int arrowID) {
switch (arrowID) {
case 11: // bronze arrows
case 574: // poison bronze arrows
case 190: // crossbow bolts
case 592: // poison cross bow bolts
case 1013: // bronze throwing dart
case 1122: // poison bronze throwing dart
return 0;
case 638:// iron arrows
case 639:// poison iron arrows
case 1015: // iron throwing dart
case 1123:// poison iron throwing dart
return 0.5;
case 640:// steel arrows
case 641:// poison steel arrows
case 1024: // steel throwing dart
case 1124: // poison steel throwing dart
case 1076:// bronze throwing dart
case 1128:// poison bronze throwing knife
case 827:// bronze spear
case 1135:// poison bronze spear
return 1;
case 642:// mith arrows
case 643:// poison mith arrows
case 786:// pearle crossbow bolts
case 1068:// mith throwing dart
case 1125: // poison mith throwing dart
case 1075:// iron throwing dart
case 1129:// poison iron throwing knife
case 1088:// iron spear
case 1136:// poison iron spear
return 1.5;
case 644:// addy arrows
case 645:// poison addy arrows
case 1069:// addy throwing dart
case 1126:// poison addy throwing dart
case 1077:// steel throwing knife
case 1130:// poison steel throwing knife
case 1089:// steel spear
case 1137:// poison steel spear
return 1.75;
case 1081:// black throwing knife
case 1132:// poison black throwing knife
return 2;
case 646:// rune arrows
case 647:// poison rune arrows
case 1070:// rune throwing dart
case 1127:// poison rune throwing dart
case 1078:// mith throwing knife
case 1131:// poison mith throwing knife
case 1090:// mith spear
case 1138:// poison mith spear
return 5;
case 723:// ice arrows
case 1079:// addy throwing knife
case 1133:// poison addy throwing knife
case 1091:// addy spear
case 1139:// poison addy spear
return 6;
case 1080:// rune throwing knife
case 1134:// poison rune throwing knife
case 1092:// rune spear
case 1140:// poison rune spear
return 7;
case 785:// lit arrow (not stackable, why not?)
return 10;
default:
return 0;
}
}
public static int bitToDoorDir(int bit) {
switch (bit) {
case 1:
return 0;
case 2:
return 1;
case 4:
return -1;
case 8:
return -1;
}
return -1;
}
public static int bitToObjectDir(int bit) {
switch (bit) {
case 1:
return 6;
case 2:
return 0;
case 4:
return 2;
case 8:
return 4;
}
return -1;
}
/**
* Decide if the food we are cooking should be burned or not
*/
public static boolean burnFood(int foodId, int cookingLevel) {
int levelDiff = cookingLevel - EntityHandler.getItemCookingDef(foodId).getReqLevel();
if (levelDiff < 0) {
return true;
}
if (levelDiff >= 20) {
return false;
}
return DataConversions.random(0, levelDiff + 1) == 0;
}
/**
* Calulates what one mob should hit on another with meelee
*/
public static int calcFightHit(Mob attacker, Mob defender) {
int max = maxHit(attacker.getStrength(), attacker.getWeaponPowerPoints(), attacker.isPrayerActivated(1), attacker.isPrayerActivated(4), attacker.isPrayerActivated(10), styleBonus(attacker, 2));
int newAtt = (int)
(
addPrayers(attacker.isPrayerActivated(2), attacker.isPrayerActivated(5), attacker.isPrayerActivated(11)
)
*
(attacker.getAttack() / 0.8D)
+
(
(DataConversions.random(0, 4) == 0 ? attacker.getWeaponPowerPoints() : attacker.getWeaponAimPoints()) / 2.5D
)
+
(
attacker.getCombatStyle() == 1 && DataConversions.random(0, 2) == 0 ? 4 : 0
)
+
(
DataConversions.random(0, 100) <= 10 ? (attacker.getStrength() / 5D) : 0
)
+
(
styleBonus(attacker, 0) * 2)
);
int newDef = (int)
(
addPrayers(defender.isPrayerActivated(0), defender.isPrayerActivated(3), defender.isPrayerActivated(9))
*
(
(DataConversions.random(0, 100) <= 5 ? 0 : defender.getDefense()) * 1.1D
)
+
(
(DataConversions.random(0, 100) <= 5 ? 0 : defender.getArmourPoints()) / 2.75D
)
+
(defender.getStrength() / 4D)
+
(styleBonus(defender, 1) * 2)
);
int hitChance = DataConversions.random(0, 100) + (newAtt - newDef);
if (attacker instanceof Npc) {
hitChance -= 5;
}
if (DataConversions.random(0, 100) <= 10) {
hitChance += 20;
}
if (hitChance > (defender instanceof Npc ? 40 : 50)) {
int maxProb = 5; // 5%
int nearMaxProb = 7; // 7%
int avProb = 73; // 73%
int lowHit = 10; // 15%
// Probablities are shifted up/down based on armour
int shiftValue = (int) Math.round(defender.getArmourPoints() * 0.02D);
maxProb -= shiftValue;
nearMaxProb -= (int) Math.round(shiftValue * 1.5);
avProb -= (int) Math.round(shiftValue * 2.0);
lowHit += (int) Math.round(shiftValue * 3.5);
int hitRange = DataConversions.random(0, 100);
if (hitRange >= (100 - maxProb)) {
return max;
} else if (hitRange >= (100 - nearMaxProb)) {
return DataConversions.roundUp(Math.abs((max - (max * (DataConversions.random(0, 10) * 0.01D)))));
} else if (hitRange >= (100 - avProb)) {
int newMax = (int) DataConversions.roundUp((max - (max * 0.1D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 50) * 0.01D)))));
} else {
int newMax = (int) DataConversions.roundUp((max - (max * 0.5D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 95) * 0.01D)))));
}
}
return 0;
}
public static int calcFightHitWithNPC(Mob attacker, Mob defender) {
int max = maxHit(attacker.getStrength(), attacker.getWeaponPowerPoints(), attacker.isPrayerActivated(1), attacker.isPrayerActivated(4), attacker.isPrayerActivated(10), styleBonus(attacker, 2));
if (attacker instanceof Npc) {
Npc n = (Npc) attacker;
if (n.getID() == 3) // Chickens only doing 1 damage.
max = 1;
}
//int newAtt = (int) (addPrayers(attacker.isPrayerActivated(2), attacker.isPrayerActivated(5), attacker.isPrayerActivated(11)) * (attacker.getAttack() / 0.7D) + ((DataConversions.random(0, 4) == 0 ? attacker.getWeaponPowerPoints() : attacker.getWeaponAimPoints()) / 3D) + (attacker.getCombatStyle() == 1 && DataConversions.random(0, 2) == 0 ? 4 : 0) + (styleBonus(attacker, 0) * 2));
int newAtt = (int) (addPrayers(attacker.isPrayerActivated(2), attacker.isPrayerActivated(5), attacker.isPrayerActivated(11))
* (attacker.getAttack())
+ ((DataConversions.random(0, 4) == 0 ? attacker.getWeaponPowerPoints() : attacker.getWeaponAimPoints()) / 3D)
+ (attacker.getCombatStyle() == 1 && DataConversions.random(0, 2) == 0 ? 4 : 0)
+ (styleBonus(attacker, 0) * 2));
int newDef = (int) (addPrayers(defender.isPrayerActivated(0), defender.isPrayerActivated(3), defender.isPrayerActivated(9)) * defender.getDefense() + (defender.getArmourPoints() / 4D) + (defender.getStrength() / 4D) + (styleBonus(defender, 1) * 2));
/*
* if(defender instanceof Player) { if(defender.getCombatLevel() < 70 &&
* defender.getCombatLevel() > 45) newDef = newDef + (int)(newDef *
* 0.25); else if(defender.getCombatLevel() > 25 &&
* defender.getCombatLevel() < 45) newDef = newDef + (int)(newDef *
* 0.35);
*
* else if(defender.getCombatLevel() > 8 && defender.getCombatLevel() <
* 25) newDef = newDef + (int)(newDef * 0.45);
*
* else if(defender.getCombatLevel() > 1 && defender.getCombatLevel() <
* 8) newDef = newDef + (int)(newDef * 0.55); }
*/
if (attacker instanceof Player) {
//newDef += newDef / 8;
newDef -= newDef / 8;
}
int hitChance = DataConversions.random(0, 100) + (newAtt - newDef);
//Added this
if (attacker instanceof Player)
hitChance += (int)(DataConversions.random(0, attacker.getAttack()) + 1) / 1.33;
if (attacker instanceof Npc) {
hitChance -= 5;
}
if (hitChance > (defender instanceof Npc ? 40 : 50)) {
int maxProb = 5; // 5%
int nearMaxProb = 10; // 10%
int avProb = 80; // 70%
int lowHit = 10; // 15%
// Probablities are shifted up/down based on armour
int shiftValue = (int) Math.round(defender.getArmourPoints() * 0.02D);
maxProb -= shiftValue;
nearMaxProb -= (int) Math.round(shiftValue * 1.5);
avProb -= (int) Math.round(shiftValue * 2.0);
lowHit += (int) Math.round(shiftValue * 3.5);
int hitRange = DataConversions.random(0, 100);
if (hitRange >= (100 - maxProb)) {
return max;
} else if (hitRange >= (100 - nearMaxProb)) {
return DataConversions.roundUp(Math.abs((max - (max * (DataConversions.random(0, 10) * 0.01D)))));
} else if (hitRange >= (100 - avProb)) {
int newMax = (int) DataConversions.roundUp((max - (max * 0.1D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 50) * 0.01D)))));
} else {
int newMax = (int) DataConversions.roundUp((max - (max * 0.5D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 95) * 0.01D)))));
}
}
return 0;
}
public static int calcGodSpells(Mob attacker, Mob defender) {
if (attacker instanceof Player) {
Player owner = (Player) attacker;
int newAtt = (int) ((owner.getMagicPoints()) + owner.getCurStat(6));
int newDef = (int) ((addPrayers(defender.isPrayerActivated(0), defender.isPrayerActivated(3), defender.isPrayerActivated(9)) * defender.getDefense() / 4D) + (defender.getArmourPoints() / 4D));
int hitChance = DataConversions.random(0, 150 + (newAtt - newDef));
// int hitChance = (int)(50D + (double)owner.getMagicPoints() -
// newDef);
if (hitChance > (defender instanceof Npc ? 50 : 60)) {
// int max = owner.isCharged() ? Rand(15, 25) : Rand(0, 10);
int max;
if (owner.isCharged()) {
max = Rand(14, 25);
} else {
max = Rand(0, 10);
}
int maxProb = 5; // 5%
int nearMaxProb = 10; // 10%
int avProb = 80; // 80%
int lowHit = 5; // 5%
// Probablities are shifted up/down based on armour
int shiftValue = (int) Math.round(defender.getArmourPoints() * 0.02D);
maxProb -= shiftValue;
nearMaxProb -= (int) Math.round(shiftValue * 1.5);
avProb -= (int) Math.round(shiftValue * 2.0);
lowHit += (int) Math.round(shiftValue * 3.5);
int hitRange = DataConversions.random(0, 100);
if (hitRange >= (100 - maxProb)) {
return max;
} else if (hitRange >= (100 - nearMaxProb)) {
return DataConversions.roundUp(Math.abs((max - (max * (DataConversions.random(0, 10) * 0.01D)))));
} else if (hitRange >= (100 - avProb)) {
int newMax = (int) DataConversions.roundUp((max - (max * 0.1D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 50) * 0.01D)))));
} else {
int newMax = (int) DataConversions.roundUp((max - (max * 0.5D)));
return DataConversions.roundUp(Math.abs((newMax - (newMax * (DataConversions.random(0, 95) * 0.01D)))));
}
}
}
return 0;
}
/**
* Calculates what one mob should hit on another with range
*/
public static int calcRangeHit(int rangeLvl, int rangeEquip, int armourEquip, int arrowID) {
int armourRatio = (int) (60D + ((double) ((rangeEquip * 3D) - armourEquip) / 300D) * 40D);
if (DataConversions.random(0, 100) > armourRatio && DataConversions.random(0, 1) == 0) {
return 0;
}
int max = (int) (((double) rangeLvl * 0.15D) + 0.85D + arrowPower(arrowID));
int peak = (int) (((double) max / 100D) * (double) armourRatio);
int dip = (int) (((double) peak / 3D) * 2D);
return DataConversions.randomWeighted(0, dip, peak, max);
}
/**
* Calculates what a spell should hit based on its strength and the magic
* equipment stats of the caster
*/
public static int calcSpellHit(int spellStr, int magicEquip) {
int mageRatio = (int) (45D + (double) magicEquip);
int max = spellStr;
int peak = (int) (((double) spellStr / 100D) * (double) mageRatio);
int dip = (int) ((peak / 3D) * 2D);
return DataConversions.randomWeighted(0, dip, peak, max);
}
/**
* Should the spell cast or fail?
*/
public static boolean castSpell(SpellDef def, int magicLevel, int magicEquip) {
int levelDiff = magicLevel - def.getReqLevel();
if (magicEquip >= 30 && levelDiff >= 5)
return true;
if (magicEquip >= 25 && levelDiff >= 6)
return true;
if (magicEquip >= 20 && levelDiff >= 7)
return true;
if (magicEquip >= 15 && levelDiff >= 8)
return true;
if (magicEquip >= 10 && levelDiff >= 9)
return true;
if (levelDiff < 0) {
return false;
}
if (levelDiff >= 10) {
return true;
}
return DataConversions.random(0, (levelDiff + 2) * 2) != 0;
}
/**
* Calculate how much experience a Mob gives
*/
public static int combatExperience(Mob mob) {
double exp = ((mob.getCombatLevel() * 2) + 10) * 1.5D;
return (int) (mob instanceof Player ? (exp / 4D) : exp);
}
/*
* Should the pot crack?
*/
public static boolean crackPot(int requiredLvl, int craftingLvl) {
int levelDiff = craftingLvl - requiredLvl;
if (levelDiff < 0) {
return true;
}
if (levelDiff >= 20) {
return false;
}
return DataConversions.random(0, levelDiff + 1) == 0;
}
/**
* Should the web be cut?
*/
public static boolean cutWeb() {
return DataConversions.random(0, 4) != 0;
}
public static boolean doorAtFacing(Entity e, int x, int y, int dir) {
if (dir >= 0 && e instanceof GameObject) {
GameObject obj = (GameObject) e;
return obj.getType() == 1 && obj.getDirection() == dir && obj.isOn(x, y);
}
return false;
}
/**
* Check what level the given experience corresponds to
*/
public static int experienceToLevel(int exp) {
for (int level = 0; level < 98; level++) {
if (exp >= experienceArray[level]) {
continue;
}
return (level + 1);
}
return 99;
}
/**
* Decide if we fall off the obstacle or not
*/
public static int failObstacle(Player player, int reqLvl) {
int levelDiff = player.getCurStat(16) - reqLvl;
if (levelDiff < 0)
return 1;
if (levelDiff >= (reqLvl * 2))
return -1;
if (DataConversions.random(0, levelDiff + 1) == 0)
return DataConversions.roundUp(player.getMaxStat(3) * DataConversions.random(0.02, 0.04));
else
return -1;
}
public static int firemakingExp(int level, int baseExp) {
return DataConversions.roundUp(baseExp + (level * 1.75D));
}
/**
* Generates a session id
*/
public static long generateSessionKey(byte userByte) {
return DataConversions.getRandom().nextLong();
}
/**
* Gets the type of bar we have
*/
public static int getBarType(int barID) {
switch (barID) {
case 169:
return 0;
case 170:
return 1;
case 171:
return 2;
case 173:
return 3;
case 174:
return 4;
case 408:
return 5;
}
return -1;
}
/**
* Calculate a mobs combat level based on their stats
*/
public static int getCombatlevel(int[] stats) {
return getCombatLevel(stats[0], stats[1], stats[2], stats[3], stats[6], stats[5], stats[4]);
}
/**
* Calculate a mobs combat level based on their stats
*/
public static int getCombatLevel(int att, int def, int str, int hits, int magic, int pray, int range) {
double attack = att + str;
double defense = def + hits;
double mage = pray + magic;
mage /= 8D;
if (attack < ((double) range * 1.5D)) {
return (int) ((defense / 4D) + ((double) range * 0.375D) + mage);
} else {
return (int) ((attack / 4D) + (defense / 4D) + mage);
}
}
/**
* gets the new sprite direction to face
*
*/
public static int getDirection(Mob you, Mob them) {
if (you.getX() == them.getX() + 1 && you.getY() == them.getY() + 1) // bottom
// left
return 3;
else if (you.getX() == them.getX() + 1 && you.getY() == them.getY() - 1) // top
// left
return 1;
else if (you.getX() == them.getX() - 1 && you.getY() == them.getY() - 1) // right
// up
return 7;
else if (you.getX() == them.getX() - 1 && you.getY() == them.getY() + 1) // right/down
return 5;
else if (you.getX() == them.getX() - 1) // face right
return 6;
else if (you.getX() == them.getX() + 1) // face left
return 2;
else if (you.getY() == them.getY() + 1) // face down
return 4;
else if (you.getY() == them.getY() - 1) // face up
return 0;
return -1;
}
/**
* Gets the empty jug ID
*/
public static int getEmptyJug(int fullJug) {
switch (fullJug) {
case 50:
return 21;
case 141:
return 140;
case 342:
return 341;
}
return -1;
}
/**
* Decide what fish, if any, we should get from the water
*/
public static ObjectFishDef getFish(int waterId, int fishingLevel, int click) {
ArrayList<ObjectFishDef> fish = new ArrayList<ObjectFishDef>();
for (ObjectFishDef def : EntityHandler.getObjectFishingDef(waterId, click).getFishDefs()) {
if (fishingLevel >= def.getReqLevel()) {
fish.add(def);
}
}
if (fish.size() <= 0) {
return null;
}
ObjectFishDef thisFish = fish.get(DataConversions.random(0, fish.size() - 1));
int levelDiff = fishingLevel - thisFish.getReqLevel();
if (levelDiff < 0) {
return null;
}
return DataConversions.percentChance(offsetToPercent(levelDiff)) ? thisFish : null;
}
/**
* Returns a gem ID
*/
public static int getGem() {
int rand = DataConversions.random(0, 100);
if (rand < 10) {
return 157;
} else if (rand < 30) {
return 158;
} else if (rand < 60) {
return 159;
} else {
return 160;
}
}
/**
* Check what height we are currently at on the map
*/
public static int getHeight(int y) {
return (int) (y / 944);
}
/**
* Check what height we are currently at on the map
*/
public static int getHeight(Point location) {
return getHeight(location.getY());
}
public static int getItemPos(Shop shop, int id) {
for (int i = 0; i < shop.getItems().size(); i++) {
if (shop.getItems().get(i).getID() == id)
return i;
}
return -1;
}
public static List<InvItem> getKeyChestLoot() {
List<InvItem>[] possibleLoots = (List<InvItem>[]) EntityHandler.getKeyChestLoots();
return possibleLoots[DataConversions.random(0, possibleLoots.length - 1)];
}
/**
* Should we get a log from the tree?
*/
public static boolean getLog(ObjectWoodcuttingDef def, int woodcutLevel, int axeId) {
int levelDiff = woodcutLevel - def.getReqLevel();
if (levelDiff < 0) {
return false;
}
switch (axeId) {
case 87:
levelDiff += 0;
break;
case 12:
levelDiff += 2;
break;
case 428:
levelDiff += 4;
break;
case 88:
levelDiff += 6;
break;
case 203:
levelDiff += 8;
break;
case 204:
levelDiff += 10;
break;
case 405:
levelDiff += 12;
break;
}
if (def.getReqLevel() == 1 && levelDiff >= 40) {
return true;
}
return DataConversions.percentChance(offsetToPercent(levelDiff));
}
/*
* public static int calcFightHitWithNPC(Mob attacker, Mob defender) { int
* newAtt = (int)((addPrayers(attacker.isPrayerActivated(2),
* attacker.isPrayerActivated(5), attacker.isPrayerActivated(11)) *
* attacker.getAttack()) + (attacker.getWeaponAimPoints() / 4D) +
* styleBonus(attacker, 0)); int newDef =
* (int)((addPrayers(defender.isPrayerActivated(0),
* defender.isPrayerActivated(3), defender.isPrayerActivated(9)) *
* defender.getDefense()) + (defender.getArmourPoints() / 4D) +
* styleBonus(attacker, 1));
*
* int hitChance = DataConversions.random(0, 100) + (newAtt - newDef);
*
* if(hitChance > (defender instanceof Npc ? 50 : 60)) { int max =
* maxHit(attacker.getStrength(), attacker.getWeaponPowerPoints(),
* attacker.isPrayerActivated(1), attacker.isPrayerActivated(4),
* attacker.isPrayerActivated(10), styleBonus(attacker, 2));
*
* int maxProb = 5; // 5% int nearMaxProb = 10; // 10% int avProb = 80; //
* 80% int lowHit = 5; // 5%
*
* // Probablities are shifted up/down based on armour int shiftValue =
* (int)Math.round(defender.getArmourPoints() * 0.02D); maxProb -=
* shiftValue; nearMaxProb -= (int)Math.round(shiftValue * 1.5); avProb -=
* (int)Math.round(shiftValue * 2.0); lowHit += (int)Math.round(shiftValue *
* 3.5);
*
* int hitRange = DataConversions.random(0, 100);
*
* if(hitRange >= (100 - maxProb)) { return max; } else if(hitRange >= (100
* - nearMaxProb)) { return DataConversions.roundUp(Math.abs((max - (max *
* (DataConversions.random(0, 10) * 0.01D))))); } else if(hitRange >= (100 -
* avProb)) { int newMax = (int)DataConversions.roundUp((max - (max *
* 0.1D))); return DataConversions.roundUp(Math.abs((newMax - (newMax *
* (DataConversions.random(0, 50) * 0.01D))))); } else { int newMax =
* (int)DataConversions.roundUp((max - (max * 0.5D))); return
* DataConversions.roundUp(Math.abs((newMax - (newMax *
* (DataConversions.random(0, 95) * 0.01D))))); } } return 0; }
*/
public static String getLvlDiffColour(int lvlDiff) {
if (lvlDiff < -9) {
return "@red@";
} else if (lvlDiff < -6) {
return "@or3@";
} else if (lvlDiff < -3) {
return "@or2@";
} else if (lvlDiff < 0) {
return "@or1@";
} else if (lvlDiff > 9) {
return "@gre@";
} else if (lvlDiff > 6) {
return "@gr3@";
} else if (lvlDiff > 3) {
return "@gr2@";
} else if (lvlDiff > 0) {
return "@gr1@";
}
return "@whi@";
}
public static int getNewY(int currentY, boolean up) {
int height = getHeight(currentY);
int newHeight;
if (up) {
if (height == 3) {
newHeight = 0;
} else if (height >= 2) {
return currentY;
} else {
newHeight = height + 1;
}
} else {
if (height == 0) {
newHeight = 3;
} else if (height >= 3) {
return currentY;
} else {
newHeight = height - 1;
}
}
return (newHeight * 944) + (currentY % 944);
}
/**
* Should we can get an ore from the rock?
*/
public static boolean getOre(ObjectMiningDef def, int miningLevel, int axeId) {
int levelDiff = miningLevel - def.getReqLevel();
if (levelDiff > 50)
return Formulae.Rand(0, 9) != 1;
if (levelDiff < 0) {
return false;
}
int bonus = 0;
switch (axeId) {
case 156:
bonus = 0;
break;
case 1258:
bonus = 2;
break;
case 1259:
bonus = 6;
break;
case 1260:
bonus = 8;
break;
case 1261:
bonus = 10;
break;
case 1262:
bonus = 12;
break;
}
return DataConversions.percentChance(offsetToPercent(levelDiff + bonus));
}
public static int getPotionDose(int id) {
if (DataConversions.inArray(potions1Dose, id)) {
return 1;
}
if (DataConversions.inArray(potions2Dose, id)) {
return 2;
}
if (DataConversions.inArray(potions3Dose, id)) {
return 3;
}
return 0;
}
/**
* @author xEnt
*
* This method will calculate the new price for all items in the
* shop there are 3 different types of calculations. 1. Buy price -
* if the item is sold in the shop by default, use the base quantity
* for the calculations in the new price.
*
* 2. Buy price - if a player has sold an item to a general store,
* leaving it to have no base quantity and player driven, we perform
* some secondary calculations.
*
* 3. Sell price (this works like the second buy price, calculates
* depending on a static number of stock and does not use any type
* of base quantity calculations, may do a second one in future.
*
* @param i
* - the selected Shop item, represented as an InvItem
* @param shop
* - the shop model object
* @param buy
* - if the item is for sale, or being sold
* @return the item's calculated price of value
*/
public static int getPrice(InvItem i, Shop shop, boolean buy) {
if (buy)
return i.getDef().getBasePrice();
else
return i.getDef().getBasePrice() / 2;
/*
* final double GENERAL_STORE_BUY_MODIFIER = 0.685;
*
* int newPrice = -1; // the newly given price. boolean playerSoldItem =
* false; // If true, there is no base quantity (a // player has sold
* this item to general // store) int curAmount = i.getAmount(); //
* current quantity the selected item has int maxStockAmount =
* shop.getEquilibrium(i.getID()); // the base // quantity of // the
* selected // shop item (if // has one)
*
* if (maxStockAmount == 0 && shop.isGeneral()) playerSoldItem = true;
* // This item is an item that has no base // quantity, was sold by a
* player in general // store
*
* if (buy) { // Decide if this item is being brought if (maxStockAmount
* == 0 && !shop.isGeneral()) // this should not // happen return
* 999999999; // rofl error price if (playerSoldItem) { // General
* store, no maximum quantity for a // player sold item. (requires
* different // calculations) // cost 15% more buying a 3rd party item
* from a general store int basePrice = shop.isGeneral() ?
* i.getDef().basePrice + (int) (i.getDef().basePrice * 0.15) :
* i.getDef().basePrice; if (basePrice > 10000) // forget any items that
* are worth past // 10k return basePrice; if (curAmount > 28) // after
* 28 quantity from a player sold // item, stick to a static price
* newPrice = basePrice - (int) (basePrice *
* GENERAL_STORE_BUY_MODIFIER); else { // do calculations to decide a
* price depending on the // quantity newPrice = basePrice - (int)
* (curAmount * 5); if (newPrice < basePrice - (int) (basePrice *
* GENERAL_STORE_BUY_MODIFIER)) newPrice = basePrice - (int) (basePrice
* * GENERAL_STORE_BUY_MODIFIER); } } else { // Has a base quantity if
* (curAmount >= maxStockAmount) // leave base price is full // stock is
* avaliable newPrice = i.getDef().basePrice; else // 75-100% quantity
* is in stock if (curAmount > maxStockAmount * 0.75 && curAmount <
* maxStockAmount) newPrice = i.getDef().basePrice + (int)
* (i.getDef().basePrice * getShopPercentage( i, 0, true)); else //
* 50-75% quantity is in stock if (curAmount > maxStockAmount * 0.50 &&
* curAmount <= maxStockAmount * 0.75) newPrice = i.getDef().basePrice +
* (int) (i.getDef().basePrice * getShopPercentage( i, 1, true)); else
* // 25-50% quantity is in stock if (curAmount > maxStockAmount * 0.25
* && curAmount <= maxStockAmount * 0.50) newPrice =
* i.getDef().basePrice + (int) (i.getDef().basePrice *
* getShopPercentage( i, 2, true)); else // 0-25% quantity is in stock
* if (curAmount > maxStockAmount * 0.0 && curAmount <= maxStockAmount *
* 0.25) newPrice = i.getDef().basePrice + (int) (i.getDef().basePrice *
* getShopPercentage( i, 3, true)); } if (newPrice == -1) return
* 99999999; // error? return newPrice; } else { // Sell if (i.getID()
* == 117) System.out.println("Current stock: " + curAmount); int base =
* i.getDef().basePrice - (int) (i.getDef().basePrice / 2.5); // Sell
* price is 125% // lower than base // price to begin // with if
* (shop.isGeneral()) // 3rd party item (player sold) base = base -
* (int) (base * 0.10); // 10% less value, if general // store.
*
* if (curAmount < 1) return base;
*
* int price; // new price if (curAmount > 12) { price = base - (int)
* (base * 0.75); // 75% loss (believe it or // not, thats how it was) }
* else { price = base;
*
* if (curAmount > 1) price = base - (int) (curAmount * (base * 0.045));
* if (price < base - (int) (base * 0.75)) base = base - (int) (base *
* 0.75); } if (price < 1) // should not happen return 0; // error price
* else return price; }
*/
}
public static int getRangeDirection(Mob you, Mob them) {
if (you.getX() > them.getX() && you.getY() == them.getY()) // face right
return 6;
else if (you.getX() < them.getX() && you.getY() == them.getY()) // face
// left
return 2;
else if (you.getY() < them.getY() && you.getX() == them.getX()) // face
// down
return 4;
else if (you.getY() > them.getY() && you.getX() == them.getX()) // face
// up
return 0;
else if (you.getX() <= them.getX() && you.getY() <= them.getY()) // bottom
// left
return 3;
else if (you.getX() <= them.getX() && you.getY() >= them.getY()) // top
// left
return 1;
else if (you.getX() >= them.getX() && you.getY() >= them.getY()) // right
// up
return 7;
else if (you.getX() >= them.getX() && you.getY() <= them.getY()) // right/down
return 5;
return -1;
}
// This is needed for the above method
public static double getShopPercentage(InvItem item, int pos, boolean buy) {
int[] prices = { 0, 10, 100, 1000, 10000 }; // base prices of the items.
double[][] percentages = { { 0.5, 1.0, 1.5, 2.0 }, // in between 0 and
// 10GP.
{ 0.1, 0.3, 0.45, 0.6 }, // 10-100gp
{ 0.1, 0.2, 0.3, 0.4 }, // 100-1000gp
{ 0.5, 0.1, 0.15, 0.2 }, // 1000-10000gp
};
int key = -1;
for (int i = 0; i < prices.length - 1; i++)
if (item.getDef().basePrice > prices[i] && item.getDef().basePrice < prices[i + 1])
key = i;
if (key == -1)
return -1;
return percentages[key][pos];
}
/**
* Gets the smithing exp for the given amount of the right bars
*/
public static int getSmithingExp(int barID, int barCount) {
int[] exps = { 13, 25, 37, 50, 83, 74 };
int type = getBarType(barID);
if (type < 0) {
return 0;
}
return exps[type] * barCount;
}
public static int getStat(String stat) {
for (int i = 0; i < statArray.length; i++) {
if (statArray[i].equalsIgnoreCase(stat))
return i;
}
return -1;
}
/**
* Given a stat string get its index returns -1 on failure
*/
public static int getStatIndex(String stat) {
for (int index = 0; index < statArray.length; index++) {
if (stat.equalsIgnoreCase(statArray[index])) {
return index;
}
}
return -1;
}
public static boolean isP2P(Object... objs) {
return isP2P(false, objs);
}
/**
* Performs coordinate checks on the locations in the P2P_LOCS array to
* decide whether items/object/npc's/general x,y coordinates are in P2P area
*
* @param objs
* - ItemLoc, GameObjectLoc, NPCLoc or an Integer.
* @return - true if inside P2P area, otherwise false.
*/
public static boolean isP2P(boolean f2pwildy, Object... objs) {
int x = -1;
int y = -1;
if (objs.length == 1) {
Object obj = objs[0];
if (obj instanceof GameObjectLoc) {
x = ((GameObjectLoc) obj).x;
y = ((GameObjectLoc) obj).y;
} else if ((obj instanceof ItemLoc)) {
x = ((ItemLoc) obj).x;
y = ((ItemLoc) obj).y;
} else if (obj instanceof NPCLoc) {
x = ((NPCLoc) obj).startX;
y = ((NPCLoc) obj).startY;
}
} else {
if (objs[0] instanceof Integer && objs[1] instanceof Integer) {
x = (Integer) objs[0];
y = (Integer) objs[1];
}
}
if (x == -1)
return false;
if(!f2pwildy) {
for (int i = 0; i < P2P_LOCS.length; i++) {
for (int ele = 0; ele < 4; ele++) {
if (x >= P2P_LOCS[i][0].getX() && x <= P2P_LOCS[i][1].getX() && y >= P2P_LOCS[i][0].getY() + ((ele) * 944) && y <= P2P_LOCS[i][1].getY() + ((ele) * 944))
return true;
}
}
} else {
for (int i = 0; i < F2PWILD_LOCS.length; i++) {
for (int ele = 0; ele < 4; ele++) {
if (x >= F2PWILD_LOCS[i][0].getX() && x <= F2PWILD_LOCS[i][1].getX() && y >= F2PWILD_LOCS[i][0].getY() + ((ele) * 944) && y <= F2PWILD_LOCS[i][1].getY() + ((ele) * 944))
return true;
}
}
}
return false;
}
public static int levelToExperience(int level) {
if (level <= 1)
return 0;
return experienceArray[level];
}
/**
* Should the fire light or fail?
*/
public static boolean lightLogs(FiremakingDef def, int firemakingLvl) {
int levelDiff = firemakingLvl - def.getRequiredLevel();
if (levelDiff < 0) {
return false;
}
if (levelDiff >= 20) {
return true;
}
return DataConversions.random(0, levelDiff + 1) != 0;
}
// maxHit
/**
* Should the arrow be dropped or disappear
*/
public static boolean looseArrow(int damage) {
return DataConversions.random(0, 6) == 0;
}
/**
* Calculate the max hit possible with the given stats
*/
public static int maxHit(int strength, int weaponPower, boolean burst, boolean superhuman, boolean ultimate, int bonus) {
double newStrength = (double) ((strength * addPrayers(burst, superhuman, ultimate)) + bonus);
int fin = (int) ((newStrength * ((((double) weaponPower * 0.00175D) + 0.1D)) + 1.05D) * 0.95D);
//if (fin > 31)
// fin = 31;
return fin;
}
/**
* Gets the min level required to smith a bar
*/
public static int minSmithingLevel(int barID) {
int[] levels = { 1, 15, 30, 50, 70, 85 };
int type = getBarType(barID);
if (type < 0) {
return -1;
}
return levels[type];
}
public static boolean objectAtFacing(Entity e, int x, int y, int dir) {
if (dir >= 0 && e instanceof GameObject) {
GameObject obj = (GameObject) e;
return obj.getType() == 0 && obj.getDirection() == dir && obj.isOn(x, y);
}
return false;
}
private static int offsetToPercent(int levelDiff) {
return levelDiff > 40 ? 70 : 30 + levelDiff;
}
/**
* Calulates what one mob should hit on another with meelee
*/
public static double parseDouble(double number) {
String numberString = String.valueOf(number);
return Double.valueOf(numberString.substring(0, numberString.indexOf(".") + 2));
}
public static int Rand(int low, int high) {
return low + r.nextInt(high - low);
}
public static int styleBonus(Mob mob, int skill) {
int style = mob.getCombatStyle();
if (style == 0) {
return 1;
}
return (skill == 0 && style == 2) || (skill == 1 && style == 3) || (skill == 2 && style == 1) ? 3 : 0;
}
public static int[] rares = new int[]{828, 831, 832, 575, 576, 577, 578, 579, 580, 581, 971, 1316, 1315, 1314, 422, 1289, 1156, 677};
public static boolean isRareItem(int id) {
return DataConversions.inArray(rares,id);
}
public static int getBarIdFromItem(int itemID) {
if(DataConversions.inArray(BRONZE, itemID))
return 169;
if(DataConversions.inArray(IRON, itemID))
return 170;
if(DataConversions.inArray(STEEL, itemID))
return 171;
if(DataConversions.inArray(MITH, itemID))
return 173;
if(DataConversions.inArray(ADDY, itemID))
return 174;
if(DataConversions.inArray(RUNE, itemID))
return 408;
return -1;
}
public final static int[] IRON = {6,5,7,8,2,3,9,28, 1075,1, 71, 83, 77, 12, 1258, 89, 0, 670, 1063};
public final static int[] RUNE = {112, 399, 400, 401, 404, 403, 402, 396, 1080, 397, 75, 398, 81, 405, 1262, 93, 98, 674, 1067};
public final static int[] ADDY = {111, 107, 116, 120, 131, 127, 123, 65, 1079, 69, 74, 86, 80, 204, 1261, 92, 97, 673, 1066};
public final static int[] MITH = {110, 106, 115, 119, 130, 126, 122, 64, 1078, 68, 73, 85, 79, 203, 1260, 91, 96, 672, 1065};
public final static int[] STEEL = {109, 105, 114, 118, 129, 125, 121, 63, 1077, 67, 72, 84, 78, 88, 1259, 90, 95, 671, 1064};
public final static int[] BRONZE = {108, 104, 113, 117, 128, 124, 206, 62, 1076, 66, 70, 82, 76, 87, 156, 87, 205, 669, 1062};
}