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 dray2edge = new ArrayList(); /** * 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 fish = new ArrayList(); 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 getKeyChestLoot() { List[] possibleLoots = (List[]) 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}; }