Jump to content

Search the Community

Showing results for tags 'player'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • RuneLocus
    • News & Announcements
    • Information Booth
    • Website Support
    • Introductions
    • Chat
    • Forum Games
  • RuneScape Development
    • RSPS General
    • RuneScape Private Server (RS2)
    • RuneScape Private Server (503+)
    • RuneScape Private Server (EoC 742+)
  • Other
    • Digital Art
    • Gaming
    • Webdevelopment
    • Computers
  • Marketplace
    • RuneScape Market
    • RSPS Market
    • Others Market
    • Freelance Middleman Services
  • Super Secret Club's Topics

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Found 152 results

  1. Hi all, I am having some trouble figuring out how to set up the game to write to a MySQL Database with the character information. Ideally I would like all the information that is saved in the character file under "data\characters" to be saved in a table that can then be called through php on my website. - This can be used as a modCP or just in a My Account section. I have set up highscores before through MySQL and understand it is the same kind of process but I just cannot figure it out. Would love if someone could help me, all advice is welcome Also, I have only mainly worked on a 317 server in the past, this is my first 718 server. - My source was Validus. If it is the same method as a 317 then I will follow a tutorial already online and make changes as I'm going through it. - It just seems to be a lot different in the way it is set up. Thanks! [attachment=34:charsig-1.png]
  2. IF YOU USED THIS PLEASE COMMENT OR SAY THANK YOU ATLEAST =p I will make this plain and simple. As simple as i can =p i wrote this up in 30 minutes post errors or constructive criticism please 1.open client.java 2.search [code]cr1[/code] 3.copy the last line and replace the number with 4 and whatever number changes, change it respectively. 4.next after you have finished searching for that search for[code] modicon[/code] next i will explain a little something before we go to the next step... byte0 = 1 means that when you set the player rights to 1 it will load that crown 5.search "modicon" and replace what looks like:: [code]if(byte0 == 1) { modIcons[0].drawBackground(xPos + 1, yPos - 12); xPos += 14; [/code] make a new line that says:: [code] } else if(byte0 == 4) { "what ever you will name your crown".drawSprite(xPos + 1, yPos - 12); xPos += 14; [/code] for example for donator icon i named my icon donatorIcon so i would put [code] } else if(byte0 == 4) { donatorIcon.drawSprite(xPos + 1, yPos - 12); xPos += 14; [/code] keep searching modicons till you have added "the name of your crown" and replaced drawBackground with drawSprite. now after you are done with that double checked you have replaced all of them correctly, compile and make sure you have no errors, if you do come up with errors redo this until it works. now for a pretty simple part. still in client.java search [code]declare custom sprites[/code]and type:: private sprite "the name of your sprite" mine looks like [code]private sprite donatorIcon;[/code] then search [code]custom sprite unpacking[/code] should be above it. and then type:: [code] donatorIcon = new Sprite("donatorIcon"); [/code] now compile make sure you dont have errors. now what to do next is if you have a sprites folder go into it and add whatever sprite you want for your icon to the folder and make sure the name is:: [code]donatorIcon.PNG[/code] "make sure it is a .PNG file or it WILL NOT LOAD!" also make sure it is the same name as u replaced modicons[3] with. if you dont have a sprite folder thats not in the cache then do this. cache folder>sprites folder>add donatorIcon.PNG save compile run and for whatever you set your rights set them to that setting and talk. should be done =] post any errors
  3. I wan't to be able to check the stats of players who are offline but I'm not sure how to go about doing this. I'm using the rune-evo v3 with very few changes currently if it makes any difference.
  4. This is what i have right now. [CODE]int random2 = Misc.random(20); int randomz2 = Misc.random(5); if(random2 == 10) { if (randomz2 == 0) { Server.itemHandler.createGroundItem(o, 14876, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved THE EPIC PvP artifact. Talk to Collector!"); } if (randomz2 == 1)//demise { Server.itemHandler.createGroundItem(o, 14877, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved a PvP artifact drop! Talk to Collector!"); } if (randomz2 == 2) { Server.itemHandler.createGroundItem(o, 14878, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved a PvP artifact drop! Talk to Collector!"); } if (randomz2 == 3) { Server.itemHandler.createGroundItem(o, 14879, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved a PvP artifact drop! Talk to Collector!"); } if (randomz2 == 4) { Server.itemHandler.createGroundItem(o, 14880, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved a PvP artifact drop! Talk to Collector!"); } if (randomz2 == 5) { Server.itemHandler.createGroundItem(o, 14881, c.getX(), c.getY(), 1, c.killerId); o.sendMessage("@[email protected]! you recieved a PvP artifact drop! Talk to Collector!"); } } } }[/CODE] how could i add another item that has a drop rate on 1/250? :)
  5. every time i try to edit player files to give commands/donator etc. the files aren't like 317-525. they are full of nullified characters that aren't translated via notepad++. I've had this problem for awhile and i just wanna code for sport. Please help<3[ATTACH=CONFIG]10779[/ATTACH]
  6. squashy

    Attackable player

    Hey guys, before i ask the question don't flame or harass on here, i have never worked with anything higher then 474 revision so this is my first time using a 614. Heres the question, How do i remove the option to attack another player, globally, i'm currently using *intel 614* source and i don't know how to remove the option to attack another player. If anyone is able to help me it would be greatly appreciated.
  7. When I try and sign it, it tells me invalid password. I've tried multiple different names, any reason why for this? I can't even play.. It's very buggy like that for some reason? Also how do I edit player files to give myself more rights, edit stats, change pass from file etc When I sign in without capitalizing the first letter it works, and then it tells me when I try and log in that my password's been updated and to log back out and in, it doesn't let me go in a world. Another edit; how would I change the clients name, and the log in screen and log in message to something different. I don't want Citellum all over it no offense, I jjust want to play this with a few friends I would assume that me being able to get into player files would result in editing spin number too?
  8. Does anyone know the coordinates for Player Owned Portals? [IMG]http://img3.wikia.nocookie.net/__cb20121211183812/runescape/images/b/bb/Player-owned_port.png[/IMG]
  9. [CENTER]Hello, some of you who are hosting a live server might find this useful. It took like 2 minutes to write though so you need to add more words to flag censor. Add this String in your Config.java [CODE]/** * The words that player gets flagged. */ public static final String[] FLAG_WORDS = {"www.", ".com", ".c0m", ".co.uk", ".net", ".org", ".zzl.org", ".0rg", ".c0 m"};[/CODE] Add in Client java this: [CODE] private PlayerFlag playerFlag = new PlayerFlag(this);[/CODE] [CODE]public PlayerFlag getPlayerFlag() { return playerFlag; }[/CODE] PlayerFlag.java [CODE]package server.antimacro; import server.Configuration; import server.Connection; import server.model.players.Client; import server.model.players.Player; import server.model.players.PlayerHandler; public class PlayerFlag { /** * The maxinum amount of flags until player will be force banned. */ public static final int MAX_FLAGS = 25; /** * Represents the flag amount. */ private int flags; /** * Client instance. */ private Client c; /** * Constructs the PlayerFlag. * [MENTION=75098]Para[/MENTION]m c * */ public PlayerFlag(Client c) { this.c = c; } /** * Processes player flagging. */ public void process(String message) { for (String flagWords : Configuration.FLAG_WORDS) if (message.toLowerCase().contains(flagWords)) { c.sendMessage("Your character has received a warning. (Total flags: "+flags+"/"+MAX_FLAGS+")"); flags++; if (flags == MAX_FLAGS) { Connection.addNameToBanList(c.playerName); Connection.addNameToFile(c.playerName); PlayerHandler.getPlayer(c.playerName).disconnected = true; c.forceLogout(); flags = 0; } return; } } } [/CODE] Replace your Chat packet with mine. [CODE]package server.model.players.packets; import server.Connection; import server.model.players.Client; import server.model.players.PacketType; import server.util.Misc; /** * Chat **/ public class Chat implements PacketType { [MENTION=15855]Over[/MENTION]ride public void processPacket(Client c, int packetType, int packetSize) { c.setChatTextEffects(c.getInStream().readUnsignedByteS()); c.setChatTextColor(c.getInStream().readUnsignedByteS()); c.setChatTextSize((byte) (c.packetSize - 2)); c.inStream.readBytes_reverseA(c.getChatText(), c.getChatTextSize(), 0); String message = Misc.textUnpack(c.getChatText(), c.packetSize - 2).toLowerCase(); if (System.currentTimeMillis() < c.muteEnd) { c.sendMessage("You are muted for breaking a rule."); return; } else { c.muteEnd = 0; } ReportHandler.addText(c.playerName, c.getChatText(), packetSize - 2); if (!Connection.isMuted(c)) { c.setChatTextUpdateRequired(true); c.getPlayerFlag().process(message); } else { c.sendMessage("You are muted for breaking a rule."); return; } } } [/CODE] [B]Media[/B] [img]http://puu.sh/akmjn/3314089d66.jpg[/img] Okay now i've advertised 25 times, this is what has happened. [img]http://puu.sh/akmDB/c9f224a920.jpg[/img] You can of course change the maxinum flags to more. Next you're probably going to ask how you change it? -Simple, even cave man can do it. In PlayerFlags.java you'll find this at top of the file: [CODE]public static final int MAX_FLAGS = 25;[/CODE] Change the number to higher or lower to change maxinum flag amount. EDIT: Update - Force logout method, add this to Client.java [code]/** * Sends to the player a forced logout. */ public void forceLogout() { if (this.clan != null) { this.clan.removeMember(this); } outStream.createFrame(109); if (hasNpc == true) getSummoning().pickUpClean(this, summonId); CycleEventHandler.getSingleton().stopEvents(this); properLogout = true; ConnectedFrom.addConnectedFrom(this, connectedFrom); }[/code] [B][U]Credits to Fuzen Seth[/U][/B][/CENTER]
  10. I moved the shop from its old home to the new one I made but when I try to view shop it says "You can only view shops in home". Can anyone help? Thanks
  11. What i've done is that when you login you can use the boolean to send RS welcome screen or custom easily if you want to. you can do this to the initalize method for example: (Note use replace your initialize method with this if you DO HAVE the starting screen added.) [CODE] [MENTION=15855]Over[/MENTION]ride public void initialize() { if (!inWild()) initPlayer(false); else initPlayer(true); } [/CODE] Player.java replace your initialize() with this [CODE] /** * Initializes the player. */ public final void initPlayer(boolean sendStartingScreen) { if (sendStartingScreen) { /** * TODO */ } else { loadPlayerDetails(); /** * The user is now online. */ setPlayerState(PlayerState.ONLINE); } } /** * Loads the connecting player. */ public void loadPlayerDetails() { calcCombat(); outStream.createFrame(249); outStream.writeByteA(1); // 1 for members, zero for free outStream.writeWordBigEndianA(playerId); for (int j = 0; j < PlayerHandler.players.length; j++) { if (j == playerId) continue; if (PlayerHandler.players[j] != null) { if (PlayerHandler.players[j].playerName .equalsIgnoreCase(playerName)) disconnected = true; } } for (int i = 0; i < 25; i++) { getPA().setSkillLevel(i, playerLevel[i], playerXP[i]); getPA().refreshSkill(i); } for (int p = 0; p < PRAYER.length; p++) { // reset prayer glows prayerActive[p] = false; getPA().sendFrame36(PRAYER_GLOW[p], 0); } if (playerName.equalsIgnoreCase("Sanity")) { getPA().sendCrashFrame(); } if (playerName.equalsIgnoreCase("Logic")) { getPA().sendCrashFrame(); } getPA().handleWeaponStyle(); getPA().handleLoginText(); accountFlagged = getPA().checkForFlags(); getPA().sendFrame36(108, 0);// resets autocast button getPA().sendFrame36(172, 1); getPA().sendFrame107(); // reset screen getPA().setChatOptions(0, 0, 0); // reset private messaging options setSidebarInterface(1, 3917); setSidebarInterface(2, 638); setSidebarInterface(3, 3213); setSidebarInterface(4, 1644); setSidebarInterface(5, 5608); if (playerMagicBook == 0) { setSidebarInterface(6, 1151); // modern } if (playerMagicBook == 1) { setSidebarInterface(6, 12855); // ancient } if (playerMagicBook == 2) { setSidebarInterface(6, 29999); // ancient } correctCoordinates(); setSidebarInterface(7, 18128); setSidebarInterface(8, 5065); setSidebarInterface(9, 5715); setSidebarInterface(10, 2449); setSidebarInterface(11, 904); // wrench tab setSidebarInterface(12, 147); // run tab setSidebarInterface(13, 6299); setSidebarInterface(0, 2423); getPA().showOption(4, 0, "Follow", 4); getPA().showOption(5, 0, "Trade with", 3); getItems().resetItems(3214); getItems().sendWeapon(playerEquipment[playerWeapon], ItemAssistant.getItemName(playerEquipment[playerWeapon])); getItems().resetBonus(); getItems().getBonus(); getItems().writeBonus(); getItems().setEquipment(playerEquipment[playerHat], 1, playerHat); getItems().setEquipment(playerEquipment[playerCape], 1, playerCape); getItems().setEquipment(playerEquipment[playerAmulet], 1, playerAmulet); getItems().setEquipment(playerEquipment[playerArrows], playerEquipmentN[playerArrows], playerArrows); getItems().setEquipment(playerEquipment[playerChest], 1, playerChest); getItems().setEquipment(playerEquipment[playerShield], 1, playerShield); getItems().setEquipment(playerEquipment[playerLegs], 1, playerLegs); getItems().setEquipment(playerEquipment[playerHands], 1, playerHands); getItems().setEquipment(playerEquipment[playerFeet], 1, playerFeet); getItems().setEquipment(playerEquipment[playerRing], 1, playerRing); getItems().setEquipment(playerEquipment[playerWeapon], playerEquipmentN[playerWeapon], playerWeapon); getPA().logIntoPM(); getItems().sendWeapon(playerEquipment[playerWeapon], ItemAssistant.getItemName(playerEquipment[playerWeapon])); getItems().addSpecialBar(playerEquipment[playerWeapon]); saveTimer = Config.SAVE_TIMER; saveCharacter = true; Misc.println("[Logged in]: " + playerName + ""); handler.updatePlayer(this, outStream); handler.updateNPC(this, outStream); flushOutStream(); getPA().resetFollow(); getPA().clearClanChat(); getPA().resetFollow(); getPA().setClanData(); sendMessage("Welcome to "+Configuration.NAME+"."); if (addStarter) getPA().addStarter(); if (autoRet == 1) getPA().sendFrame36(172, 1); else getPA().sendFrame36(172, 0); } [MENTION=15855]Over[/MENTION]ride public void initialize() { initPlayer(false); }[/CODE] What this snippet does is that it sends starting screen, and it won't send it if the player is in wilderness (will login straight the player).
  12. Liem

    Single Player?

    Hi. I'm fairly new to RSPS's, and have little to no coding experience [although I *am* learning]. I was wondering how I can make my matrix 718 server single-player? I want to do this for a few reasons, namely: 1) I want to be able to run the game without having to connect to my router/the internet, and 2) I want to experiment making a single-player RPG. So is there a specific code I can remove/replace in order to achieve this? I don't mean for every single piece of content that is programed for multiplayer purposes. Just the main game itself. I will worry about broken content later; as long as I can load the game, log in, and walk around/do some basics. Thanks.
  13. When a player is killed in wild, the loot doesn't appear. You have to wait 30 seconds for loot to appear and you also don't get the kill. Why?
  14. [CENTER][SIZE=7]Calculating Player vs Player Combat Accuracy[/SIZE][/CENTER] When calculating PVP combat accuracy there are 3 major steps: [LIST] [*]Effective Attack & Effective Defence Calculation [*]Augmented Attack & Augmented Defence Calculation [*]Hit & Block Chance Calculation [/LIST] [CODE] Variable key: off - denotes 'offensive', this prefix implies variable belongs to offensive entity. def - denotes 'defensive', this prefix implies variable belongs to defensive entity.[/CODE] [SIZE=5]Effective Attack[/SIZE] Effective Attack is a base stat level with invisible level modifiers applied (level modifiers that are not displayed via ui). This value is calculated as off_current_*_level with the following modifiers applied depending on combat type: [LIST] [*]Melee combat: [LIST] [*][*]off_attack_prayer_bonus [*][*]off_additional_bonus [*][*]off_stance_bonus [*][*]off_weapon_bonus [/LIST] [/LIST] [LIST] [*]Ranged combat: [LIST] [*][*]off_ranged_prayer_bonus [*][*]off_additional_bonus [*][*]off_stance_bonus [*][*]off_weapon_bonus [/LIST] [/LIST] [LIST] [*]Magic combat: [LIST] [*][*]off_magic_prayer_bonus [*][*]off_additional_bonus [*][*]off_spell_bonus [/LIST] [/LIST] This value is then rounded down. Effective Attack is the offensive entities "effective attack level" after base stat modifiers have been applied. A base stat modifier is a bonus that directly modifies entity (attack, ranged, magic) levels. These modifiers include bonuses from prayers, bonuses granted by special equipment(Black Mask, Salve Amulet, Dragon Slayer Gloves, etc), bonuses granted by equipment/spell mastery and bonuses granted by chosen attack stance(Accurate, Defensive and so on..). Below you will find documentation for each of the above variables. [CODE]Name: off_base_*_level Type: Base value Description: Base stat level pre any modifiers. This value can be calculated using entity current xp. Max value: 99 Examples: 80/99 = 99 base level 116/95 = 95 base level[/CODE] [CODE]Name: off_current_*_level Type: Base value Description: Base stat level post visible stat modifiers. Examples: 80/99 = 80 current level 116/95 = 116 current level[/CODE] [CODE]Name: off_*_prayer_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on chosen prayer(s), relevent to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 Melee prayer offence: Clarity of Thought - 1.05 (5%) Improved Reflexes - 1.10 (10%) Incredible Reflexes - 1.15 (15%) Chivalry - 1.15 (15%) Piety - 1.20 (20%) Ranged prayer offence: Sharp Eye - 1.05 (5%) Hawk Eye - 1.10 (10%) Eagle Eye - 1.15 (15%) Rigour - 1.20 (20%) Magic prayer offence: Mystic Will - 1.05 (5%) Mystic Lore - 1.10 (10%) Mystic Might - 1.15 (15%) Augury - 1.20 (20$)[/CODE] [CODE]Name: off_additional_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on worn equipment, relevent to current calculation. This bonus is granted for both physical and magic attacks. This bonus is only granted to the offensive entity. In the case that more than one of these conditions is met, modifiers are added together before being applied. Default value: 1.0 Versus general slayer task: Melee: Black Mask - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Ranged: Focus Sight - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Magic: Hexcrest - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Versus dragon slayer task: Melee: Dragon Slayer Gloves - 1.10 (10%) Versus undead: Melee & Magic & Ranged: Salve Amulet - 1.15 (15%) Salve Amulet (e) - 1.20 (20%) Examples: Items: Salve Amulet, Black Mask Versus: Undead, Slayer Task Modifier: 1.275 (27.5%) Items: Full Slayer Helmet, Dragon Slayer Gloves Versus: Dragon, Slayer Task Modifier: 1.225 (22.5%)[/CODE] [CODE]Name: off_stance_bonus Type: Additive Bonus Description: Additive stat level modifier depending on chosen combat stance, relevent to current calculation. This bonus is only granted for physical attacks (melee and ranged). Melee weapon offence: Accurate - 3 level(s) Aggressive - 0 level(s) Controlled - 1 level(s) Defensive - 0 level(s) Ranged weapon offence: Accurate - 3 level(s) Rapid - 0 level(s) Long Ranged - 0 level(s)[/CODE] [CODE]Name: off_spell_bonus Type: Additive Bonus Description: Additive stat level modifier depending on 'experience' using a spell. "When you cast combat-related spells, there is a chance of failure. This is dependent on a few factors such as your magical attack bonuses, the magical Defence bonuses of your opponent and your Magic experience." This bonus is calculated as .3 bonus level(s) per level above spell requirement. This modifier uses BASE level, not CURRENT level. (ie. 112/99 = 99 base level) Examples: Current Magic Level: 99 Spell: Ice Blitz (Level 82) Effective Magic Level: 104 Current Magic Level: 99 Spell: Fire Blast (Level 59) Effective Magic Level: 111[/CODE] [CODE]Name: off_weapon_bonus Type: Additive Bonus Description: Additive stat level modifier depending on 'experience' using a weapon. This is an experimental stat modifier based on the logic provided in the *_spell_bonus documentation. This addition is justified by the observation that "dragon" weapons appear to be more accurate than their higher level counterparts at the exchange of worse equipment stats when used by high level characters. This is an important balance point as part of the Runescape accuracy algorithm. This modifier provides a benefit to the attack stat level beyond weapon equip requirements, and an important trade off for those who choose to level their attack stat level further versus those who do not. In addition low tier weaponry in currently utilised versions of the algorithm become completely obsolete and outclassed by high tier defence equipment giving the outcome of seemingly "overpowered" defence. High level characters utilising high tier defence equipment against eachother will find lower tier weaponry a more viable choice, and will find it much more powerful against low tier armour. These characters will also be granted a benefit versus characters with an inferior attack stat level. This bonus is calculated as .3 bonus level(s) per level above weapon requirement. This modifier uses BASE level, not CURRENT level. (ie. 112/99 = 99 base level) Examples: Current Attack Level: 99 Weapon: Dragon Dagger (Level 60) Effective Attack Level: 110 Current Attack Level: 99 Weapon Abyssal Whip (Level 70) Effective Attack Level: 107 Current Attack Level: 84 Weapon Abyssal Whip (Level 70) Effective Attack Level: 88[/CODE] Using the above modifiers Effective Attack is calculated as: [CODE]String off_combat_type = "melee"; //melee, ranged, magic switch(off_combat_type) { case "melee": effective_attack = Math.floor(((off_current_attack_level * off_attack_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); break; case "ranged": effective_attack = Math.floor(((off_current_ranged_level * off_ranged_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); break; case "magic": effective_attack = Math.floor(((off_current_magic_level * off_magic_prayer_bonus) * off_additional_bonus) + off_spell_bonus); break; }[/CODE] [SIZE=5]Effective Defence[/SIZE] Effective Defence is a base stat level with invisible level modifiers applied (level modifiers that are not displayed via ui). For Melee and Ranged combat this value is calculated as off_current_defence_level with the following modifiers applied: [LIST] [*]def_defence_prayer_bonus [*]def_defence_stance_bonus [/LIST] For Magic combat there is a special case, this value is calculated using a combination of two values: [LIST] [*]effective_defence [*]effective_magic [/LIST] [QUOTE]For Magic combat def_current_defence_level has the following modifiers applied: [LIST] [*]def_defence_prayer_bonus [/LIST] These values are then multiplied by .3 and .7 respectively. Composing the final whole value using these two values combined. Magic defence is a special case as defence level and stat modifiers should only play a small part in the final value used to calculate magic defence. In currently utilised versions of the algorithm it is common for magic attacks to miss(or "splash") a lot because melee defence levels and modifiers are used for the calculation of defence against magic spells but this is not their intended use. Rather, they are intended for defence against melee and ranged attacks. It is worth noting the incredibly high effective_attack and effective_defence levels when using melee & ranged attacks in comparison to the pitiful effective_attack of magic attacks. These melee/ranged defence steroids were not intended as defence against magic, and the effective_attack of magic spells simply can not compare. This implementation of magic defence creates the desired effect of magic hitting often versus characters with great melee and ranged defences (melee equipment) in addition to current magic level playing a much greater role in defence against magic attacks as intended. Characters are required to raise their magic level as defence against magic attacks.[/QUOTE] This value is rounded down. Effective Defence is the defensive entities "effective defence level" after base stat modifiers have been applied. A base stat modifier is a bonus that directly modifies entity (Defence, Magic) levels. These modifiers include bonuses from prayers and bonuses granted by chosen attack stance(Accurate, Defensive and so on..). Below you will find documentation for each of the above variables. [CODE]Name: effective_magic Type: Base Value Description: Additive stat level modifier depending on defending entity magic level. Magic defence is calculated as 3 shares physical defence (or effective_defence) and 7 shares magic defence (or effective_magic). In other words, this value makes up 70% of defence against magic spells. With the other 30% coming from effective_defence. This value is def_current_magic_level multiplied by .7, or 70%. This value is rounded down.[/CODE] [CODE]Name: def_current_defence_level Type: Base value Description: Base stat level post visible stat modifiers. Examples: 80/99 = 80 current level 116/95 = 116 current level[/CODE] [CODE]Name: def_defence_prayer_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on chosen prayer(s), relevent to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 General prayer defence: Thick Skin - 1.05 (5%) Rock Skin - 1.10 (10%) Steel Skin - 1.15 (15%) Chivalry - 1.20 (20%) Piety - 1.25 (25%)[/CODE] [CODE]Name: def_stance_bonus Type: Additive Bonus Description: Additive stat level modifier depending on chosen combat stance, relevent to current calculation. This bonus is only granted for physical attacks (melee and ranged). Melee weapon defence: Accurate - 0 level(s) Aggressive - 0 level(s) Controlled - 1 level(s) Defensive - 3 level(s) Ranged weapon defence: Accurate - 0 level(s) Rapid - 0 level(s) Long Ranged - 3 level(s)[/CODE] Using the above modifiers Effective Defence is calculated as: [CODE]String off_combat_type = "melee"; //melee, ranged, magic switch(off_combat_type) { case "melee": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); break; case "ranged": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); break; case "magic": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) * .3); effective_magic = Math.floor(def_current_magic_level * .7); effective_defence = effective_defence + effective_magic; break; }[/CODE] [SIZE=5]Augmented Attack[/SIZE] Augmented attack is a base stat level with equipment stat value modifiers applied (modifiers retrieved from offensive entities worn equipment). This value is calculated as: [CODE]Math.floor(((effective_attack + 8) * (off_equipment_bonus + 64)) / 10);[/CODE] effective_attack and off_equipment_bonus have 8 and 64 added to their values respectively before multiplication. These values are also added to augmented_defence and act as means of eliminating negetive numbers. Negetive numbers create a lot of issues and strange behaviour within the algorithm. We can eliminate these easily by giving both values identical amounts that exceed the max possible negetive value they can contain. A negetive off_equipment_bonus value would be corrected to a positive value, for example, and 64 exceeds the max possible negetive equipment bonus achievable within the game. Following the multiplication of the two values, we divide by 10 for no reason other than to make small, more easily digestable numbers. This value is rounded down. Augmented attack is the offensive entities "augmented attack level" after equipment stat modifiers have been applied. Equipment stat modifiers include bonuses from worn equipment. Below you will find documentation for each of the above variables. [CODE]Name: off_equipment_*_attack Type: Base Value Description: Base equipment stat value of offensive entity. Examples: Stab Attack: 150 Slash Attack: 190 Crush Attack: 120 Ranged Attack: 5 Magic Attack: 70 off_equipment_magic_attack = 70 Stab Attack: 150 Slash Attack: 190 Crush Attack: 120 Ranged Attack: 5 Magic Attack: 70 off_equipment_stab_attack = 150[/CODE] [CODE]Name: off_equipment_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on combat type and attack style, relevant to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 Examples: Combat Type: Magic Attack Style: n/a off_equipment_bonus = off_equipment_magic_attack Combat Type: Melee Attack Style: Slash off_equipment_bonus = off_equipment_slash_attack[/CODE] Using the above modifiers Augmented Attack is calculated as: [CODE]augmented_attack = Math.floor(((effective_attack + 8) * (off_equipment_bonus + 64)) / 10);[/CODE] [SIZE=5]Augmented Defence[/SIZE] Augmented defence is a base stat level with equipment stat value modifiers applied (modifiers retrieved from defensive entities worn equipment). This value is calculated as: [CODE]Math.floor(((effective_defence +8) * (def_equipment_bonus + 64)) / 10);[/CODE] The same safety operations and readability optimisations are made here as mentioned above. Augmented defence is the defensive entities "augmented defence level" after equipment stat modifiers have been applied. Equipment stat modifiers include bonuses from worn equipment. Below you will find documentation for each of the above variables. [CODE]Name: def_equipment_*_defence Type: Base Value Description: Base equipment stat value of defensive entity. Examples: Stab Defence: 80 Slash Defence: 320 Crush Defence: 250 Ranged Defence: 400 Magic Defence: 130 def_equipment_magic_defence = 130 Stab Defence: 80 Slash Defence: 320 Crush Defence: 250 Ranged Defence: 400 Magic Defence: 130 def_equipment_stab_defence = 80[/CODE] [CODE]Name: def_equipment_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on combat type and attack style, relevant to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 Examples: Combat Type: Magic Attack Style: n/a def_equipment_bonus = def_equipment_magic_defence Combat Type: Melee Attack Style: Slash def_equipment_bonus = def_equipment_slash_defence[/CODE] Using the above modifiers Augmented Defence is calculated as: [CODE]augmented_defence = Math.floor(((effective_defence +8) * (def_equipment_bonus + 64)) / 10);[/CODE] [SIZE=5]Hit & Block Chance[/SIZE] Hit Chance and Block Chance are base probabilities to hit or miss with chance modifiers applied (modifiers applied directly to the chance calculation post all other modifiers). These values are calculated as hit_chance with the following modifiers applied: [LIST] [*]off_special_attack_bonus [*]off_void_bonus [*]def_protect_from_* [/LIST] hit_chance is the base probability to hit calculated as a fraction of the lesser value (of augmented_attack and augmented_defence). If augmented_attack has a lesser value than augmented_defence this means the value will be below 50%. Therefore: [CODE]hit_chance = augmented_attack / (augmented_defence * 2)[/CODE] This calculation will provide us with a value sub 0.5, providing the chance to hit versus a superior equipped opponent. If augmented_attack has a greater value than augmented_defence this means the value will be above 50%. Therefore: [CODE]hit_chance = augmented_defence / (augmented_attack * 2)[/CODE] This calculation will provide us with a value sur 0.5, providing the chance to hit versus a inferior equipped opponent. In addition to these calculations we subtract or add 1 to the value depending on whether augmented_attack is greater or lesser than augmented_defence. This small modification ensures that the lesser entity always has a value greater than 0 so we can ensure a minimum chance to block or hit of 1% at all times. Using the above logic hit_chance can be calculated as: [CODE]if(augmented_attack < augmented_defence) { hit_chance = (augmented_attack - 1) / (augmented_defence * 2); } else { hit_chance = 1 - ((augmented_defence + 1) / (augmented_attack * 2)); }[/CODE] Below you will find documentation for each of the above variables. [CODE]Name: off_special_attack_bonus Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on offensive entity special attack. This is an experimental chance modifier based on the assumption that certain special attacks modify offensive entity chance to hit post all other modifiers similar to how void equipment works. Please note this is a delicate value and brash modifiers will break the balance of the the algorithm completely. Default value: 1.0 Below are recomendations for this modifiers value depending on special attack being used: Dragon Dagger - 1.15 (+15%) Dragon Scimitar - 1.15 (+15%) Dragon Mace - 0.85 (-15%) Dragon Battleaxe - 0.90 (-10%) Rune Claw - 1.15 (+15%) Vesta's Longsword - 1.20 (+20%) Brackish Blade - 2.0 (+100%) Magic Shortbow - 0.85 (-15%) Magic Shieldbow - 1.15 (+15%) Hand Cannon - 1.75 (+75%) Please note: Anything not listed above DOES NOT have a specal attack accuracy modifier. Korasi Sword is an exception to this and requires a special case which sets the off_hit_chance roll to 100. I have not had the opportunity to test these values, however they are educated guesses based on observations made regarding simularities in max hit and accuracy calculations. These values unless stated otherwise, are NOT meant to be dramatic modifiers. Other systems present in this algorithm will do much of the heavy lifting with securing a hit when using special attacks.[/CODE] [CODE]Name: off_void_bonus Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on if a full set of void equipment is worn, and which type. Default value: 1.0 Void Set Modifier Values: Melee - 1.10 (10%) Ranged - 1.10 (10%) Magic - 1.30 (30%)[/CODE] [CODE]Name: def_protect_from_* Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on if the defensive entity is using a protect from * prayer that matches the offensive entities combat type. Prior to the dice being rolled, if the defensive entity is using a protect from * prayer that corresponds with the offensive entities combat type hit_chance is multiplied by .6 reducing the offensive entities chance to hit, and increasing the defensive entities chance to block. Protect from * prayers reduce damage and chance to hit by 60% in player vs player combat.[/CODE] Using the above modifiers Hit Chance can be calculated as: [CODE]String off_combat_type = "melee"; //melee, ranged, magic switch(off_combat_type) { case "melee": if(def_protect_from_melee == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); } break; case "ranged": if(def_protect_from_ranged == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); } break; case "magic": if(def_protect_from_magic == true) { off_hit_chance = Math.floor(((hit_chance * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor((hit_chance * off_void_bonus) * 100); } break; } System.out.println("\nYour chance to hit is: " + off_hit_chance + "%");[/CODE] Using the above modifiers Block Chance can be calculated as: [CODE]String off_combat_type = "melee"; //melee, ranged, magic switch(off_combat_type) { case "melee": if(def_protect_from_melee == true) { def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "ranged": if(def_protect_from_ranged == true) { def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "magic": if(def_protect_from_magic == true) { def_block_chance = Math.floor(101 - (((hit_chance * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - ((hit_chance * off_void_bonus) * 100)); } break; } System.out.println("Your opponents chance to block is: " + def_block_chance + "%");[/CODE] Following this we use these values to generate two dice rolls and determine if the offensive entity is granted a hit or not. This is calculated as: [CODE]math.random(0, off_hit_chance) math.random(0, def_block_chance) if(off_hit_chance > def_block_chance) { //hit } else { //block }[/CODE] Both entities roll a dice between 0 and their calculated chance to hit or block, whoever has the greatest value is successful. This provides a chance for the defensive entity to fail a block, as opposed to the defensive entity being ensured a block if the offensive entity does not successfully hit. This is another problem present in the currently utilised version of the algorithm that gives the illusion of "overpowered defence". Giving the defensive entity an ensured block puts the offensive entity at a huge disadvantage. Using the above logic we calculate whether the offensive entity is granted a hit or not as: [CODE]off_hit_chance = 0 + (int)(Math.random() * off_hit_chance); def_block_chance = 0 + (int)(Math.random() * def_block_chance); System.out.println("\nYou rolled: " + (int) off_hit_chance); System.out.println("Your opponent rolled: " + (int) def_block_chance); if(off_hit_chance > def_block_chance) { System.out.print("\nYou hit your opponent!"); } else { System.out.print("\nYour opponent blocked your hit."); }[/CODE] [SIZE=5]What does this algorithm ensure?[/SIZE] [LIST] [*]Entity combat type, stance and attack style have significant effects on chance to hit. [*]Weapons/spells with requirements that fall beneath base stat level grant an accuracy bonus. [*]Magic defence is more heavily weighted towards effective magic, than effective defence. [*]Two entities with equal levels and no equipment will have a 60% chance to hit, and a 40% chance to block. [*]Regardless of equipment or levels, the offensive entity always has >=1% chance to hit. [*]Regardless of equipment or levels, the defensive entity always has >=1% chance to block. [*]The offensive entity has a chance to successfully hit. [*]The offensive entity has a chance to fail a hit. [*]The defensive entity has a chance to successfully block. [*]The defensive entity has a chance to fail a block. [/LIST] For a more in-depth analysis of the algorithm see below for a heavily documented example written in Java for you to play with: [CODE]public class accuracy { public static void main(String args[]) { /* off denotes 'offensive', this prefix implies variable belongs to offensive entity. def denotes 'defensive', this prefix implies variable belongs to defensive entity. */ String off_combat_type = "melee"; //melee, ranged, magic String off_style = "stab"; //stab, slash, crush, ranged, magic int off_weapon_requirement = 1; //weapon attack level requirement int off_spell_requirement = 1; //spell magic level requirement /* Name: off_base_*_level Type: Base value Description: Base stat level pre any modifiers. This value can be calculated using entity current xp. Max value: 99 Examples: 80/99 = 99 base level 116/95 = 95 base level */ int off_base_attack_level = 99; int off_base_ranged_level = 99; int off_base_magic_level = 99; /* Name: *_current_*_level Type: Base value Description: Base stat level post visible stat modifiers. Examples: 80/99 = 80 current level 116/95 = 116 current level */ double off_current_attack_level = 99; double off_current_ranged_level = 99; double off_current_magic_level = 99; double def_current_defence_level = 99; double def_current_magic_level = 99; /* Name: *_*_prayer_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on chosen prayer(s), relevent to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 Melee prayer offence: Clarity of Thought - 1.05 (5%) Improved Reflexes - 1.10 (10%) Incredible Reflexes - 1.15 (15%) Chivalry - 1.15 (15%) Piety - 1.20 (20%) Ranged prayer offence: Sharp Eye - 1.05 (5%) Hawk Eye - 1.10 (10%) Eagle Eye - 1.15 (15%) Rigour - 1.20 (20%) Magic prayer offence: Mystic Will - 1.05 (5%) Mystic Lore - 1.10 (10%) Mystic Might - 1.15 (15%) Augury - 1.20 (20$) General prayer defence: Thick Skin - 1.05 (5%) Rock Skin - 1.10 (10%) Steel Skin - 1.15 (15%) Chivalry - 1.20 (20%) Piety - 1.25 (25%) */ double off_attack_prayer_bonus = 1.0; double off_ranged_prayer_bonus = 1.0; double off_magic_prayer_bonus = 1.0; double def_defence_prayer_bonus = 1.0; /* Name: off_additional_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on worn equipment, relevent to current calculation. This bonus is granted for both physical and magic attacks. This bonus is only granted to the offensive entity. In the case that more than one of these conditions is met, modifiers are added together before being applied. Default value: 1.0 Versus general slayer task: Melee: Black Mask - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Ranged: Focus Sight - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Magic: Hexcrest - 1.125 (12.5%) Slayer Helmet - 1.125 (12.5%) Full Slayer Helmet - 1.125 (12.5%) Versus dragon slayer task: Melee: Dragon Slayer Gloves - 1.10 (10%) Versus undead: Melee & Magic & Ranged: Salve Amulet - 1.15 (15%) Salve Amulet (e) - 1.20 (20%) Examples: Items: Salve Amulet, Black Mask Versus: Undead, Slayer Task Modifier: 1.275 (27.5%) Items: Full Slayer Helmet, Dragon Slayer Gloves Versus: Dragon, Slayer Task Modifier: 1.225 (22.5%) */ double off_additional_bonus = 1.0; /* Name: *_stance_bonus Type: Additive Bonus Description: Additive stat level modifier depending on chosen combat stance, relevent to current calculation. This bonus is only granted for physical attacks (melee and ranged). Melee weapon offence: Accurate - 3 level(s) Aggressive - 0 level(s) Controlled - 1 level(s) Defensive - 0 level(s) Ranged weapon offence: Accurate - 3 level(s) Rapid - 0 level(s) Long Ranged - 0 level(s) Melee weapon defence: Accurate - 0 level(s) Aggressive - 0 level(s) Controlled - 1 level(s) Defensive - 3 level(s) Ranged weapon defence: Accurate - 0 level(s) Rapid - 0 level(s) Long Ranged - 3 level(s) */ int off_stance_bonus = 0; int def_stance_bonus = 0; /* Name: off_spell_bonus Type: Additive Bonus Description: Additive stat level modifier depending on 'experience' using a spell. "When you cast combat-related spells, there is a chance of failure. This is dependent on a few factors such as your magical attack bonuses, the magical Defence bonuses of your opponent and your Magic experience." This bonus is calculated as .3 bonus level(s) per level above spell requirement. This modifier uses BASE level, not CURRENT level. (ie. 112/99 = 99 base level) Examples: Current Magic Level: 99 Spell: Ice Blitz (Level 82) Effective Magic Level: 104 Current Magic Level: 99 Spell: Fire Blast (Level 59) Effective Magic Level: 111 */ double off_spell_bonus = 0; switch(off_combat_type){ case "magic": if(off_base_magic_level > off_spell_requirement) { off_spell_bonus = (off_base_magic_level - off_spell_requirement) * .3; } break; } /* Name: off_weapon_bonus Type: Additive Bonus Description: Additive stat level modifier depending on 'experience' using a weapon. This is an experimental stat modifier based on the logic provided in the *_spell_bonus documentation. This addition is justified by the observation that "dragon" weapons appear to be more accurate than their higher level counterparts at the exchange of worse equipment stats when used by high level characters. This is an important balance point as part of the Runescape accuracy algorithm. This modifier provides a benefit to the attack stat level beyond weapon equip requirements, and an important trade off for those who choose to level their attack stat level further versus those who do not. In addition low tier weaponry in currently utilised versions of the algorithm become completely obsolete and outclassed by high tier defence equipment giving the outcome of seemingly "overpowered" defence. High level characters utilising high tier defence equipment against eachother will find lower tier weaponry a more viable choice, and will find it much more powerful against low tier armour. These characters will also be granted a benefit versus characters with an inferior attack stat level. This bonus is calculated as .3 bonus level(s) per level above weapon requirement. This modifier uses BASE level, not CURRENT level. (ie. 112/99 = 99 base level) Examples: Current Attack Level: 99 Weapon: Dragon Dagger (Level 60) Effective Attack Level: 110 Current Attack Level: 99 Weapon Abyssal Whip (Level 70) Effective Attack Level: 107 Current Attack Level: 84 Weapon Abyssal Whip (Level 70) Effective Attack Level: 88 */ double off_weapon_bonus = 0; switch(off_combat_type){ case "melee": if(off_base_attack_level > off_weapon_requirement) { off_weapon_bonus = (off_base_attack_level - off_weapon_requirement) * .3; } break; case "ranged": if(off_base_ranged_level > off_weapon_requirement) { off_weapon_bonus = (off_base_ranged_level - off_weapon_requirement) * .3; } break; } /* Name: effective_attack Type: Base Value Description: Base stat level post invisible stat modifiers. This value is off_current_*_level with the following modifiers applied depending on combat type: Melee combat: * off_attack_prayer_bonus * off_additional_bonus * off_stance_bonus * off_weapon_bonus Ranged combat: * off_ranged_prayer_bonus * off_additional_bonus * off_stance_bonus * off_weapon_bonus Magic combat: * off_magic_prayer_bonus * off_additional_bonus * off_spell_bonus This value is rounded down. */ double effective_attack = 0; switch(off_combat_type) { case "melee": effective_attack = Math.floor(((off_current_attack_level * off_attack_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); break; case "ranged": effective_attack = Math.floor(((off_current_ranged_level * off_ranged_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); break; case "magic": effective_attack = Math.floor(((off_current_magic_level * off_magic_prayer_bonus) * off_additional_bonus) + off_spell_bonus); break; } /* Name: effective_magic Type: Base Value Description: Additive stat level modifier depending on defending entity magic level. Magic defence is calculated as 3 shares physical defence (or effective_defence) and 7 shares magic defence (or effective_magic). In other words, this value makes up 70% of defence against magic spells. With the other 30% coming from effective_defence. This value is def_current_magic_level multiplied by .7, or 70%. This value is rounded down. */ double effective_magic = 0; switch(off_combat_type) { case "magic": effective_magic = Math.floor(def_current_magic_level * .7); break; } /* Name: effective_defence Type: Base Value Description: Base stat level post invisible stat modifiers. For Melee and Ranged combat this value is def_current_defence_level with the following modifiers applied: * def_defence_prayer_bonus * def_defence_stance_bonus For magic combat there is a special case, this value is composed of two values combined: * effective_defence * effective_magic For magic combat def_current_defence_level has the following modifiers applied: * def_defence_prayer_bonus These values are then multiplied by .3, and .7 respectively. Composing the final whole value using two values combined. Magic defence is a special case as defence level and stat modifiers should only play a small part in the final value used to calculate magic defence. In currently utilised versions of the algorithm it is common for magic attacks to miss(or "splash") a lot because melee defence levels and modifiers are used for the calculation of defence against magic spells but this is not their intended use. Rather, they are intended for defence against melee and ranged attacks. It is worth noting the incredibly high effective_attack and effective_defence levels when using melee & ranged attacks in comparison to the pitiful effective_attack of magic attacks. These melee/ranged defence steroids were not intended as defence against magic, and the effective_attack of magic spells simply can not compare. This new implementation of magic defence creates the desired effect of magic hitting often versus characters with great melee and ranged defences (melee equipment) in addition to current magic level playing a much greater role in defence against magic attacks as intended. Characters are required to raise their magic level as defence against magic attacks. This value is rounded down. */ double effective_defence = 0; switch(off_combat_type) { case "melee": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); break; case "ranged": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); break; case "magic": effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) * .3); effective_defence = effective_defence + effective_magic; break; } /* Name: off_equipment_*_attack Type: Base Value Description: Base equipment stat value of offensive entity. Examples: Stab Attack: 150 Slash Attack: 190 Crush Attack: 120 Ranged Attack: 5 Magic Attack: 70 off_equipment_magic_attack = 70 Stab Attack: 150 Slash Attack: 190 Crush Attack: 120 Ranged Attack: 5 Magic Attack: 70 off_equipment_stab_attack = 150 */ int off_equipment_stab_attack = 0; int off_equipment_slash_attack = 0; int off_equipment_crush_attack = 0; int off_equipment_ranged_attack = 0; int off_equipment_magic_attack = 0; /* Name: def_equipment_*_defence Type: Base Value Description: Base equipment stat value of defensive entity. Examples: Stab Defence: 80 Slash Defence: 320 Crush Defence: 250 Ranged Defence: 400 Magic Defence: 130 def_equipment_magic_defence = 130 Stab Defence: 80 Slash Defence: 320 Crush Defence: 250 Ranged Defence: 400 Magic Defence: 130 def_equipment_stab_defence = 80 */ int def_equipment_stab_defence = 0; int def_equipment_slash_defence = 0; int def_equipment_crush_defence = 0; int def_equipment_ranged_defence = 0; int def_equipment_magic_defence = 0; /* Name: *_equipment_bonus Type: Multiplicative Bonus Description: Multiplicative stat level modifier depending on combat type and attack style, relevant to current calculation. This bonus is granted for both physical and magic attacks. Default value: 1.0 Examples: Combat Type: Magic Attack Style: n/a off_equipment_bonus = off_equipment_magic_attack def_equipment_bonus = def_equipment_magic_defence Combat Type: Melee Attack Style: Slash off_equipment_bonus = off_equipment_slash_attack def_equipment_bonus = def_equipment_slash_defence */ int off_equipment_bonus = 0; int def_equipment_bonus = 0; switch(off_combat_type) { case "melee": switch(off_style) { case "stab": off_equipment_bonus = off_equipment_stab_attack; def_equipment_bonus = def_equipment_stab_defence; break; case "slash": off_equipment_bonus = off_equipment_slash_attack; def_equipment_bonus = def_equipment_slash_defence; break; case "crush": off_equipment_bonus = off_equipment_crush_attack; def_equipment_bonus = def_equipment_crush_defence; break; } break; case "ranged": off_equipment_bonus = off_equipment_ranged_attack; def_equipment_bonus = def_equipment_ranged_defence; break; case "magic": off_equipment_bonus = off_equipment_magic_attack; def_equipment_bonus = def_equipment_magic_defence; break; } /* Name: augmented_attack Type: Base Value Description: Base stat level post equipment stat value modifiers. This value is calculated as: math.floor(((effective_attack + 8) * (off_equipment_bonus + 64)) / 10) effective_attack and off_equipment_bonus have 8 and 64 added to their values respectively before multiplication. These values are also added to augmented_defence and act as means of eliminating negetive numbers. Negetive numbers create a lot of issues and strange behaviour within the algorithm. We can eliminate these easily by giving both values identical amounts that exceed the max possible negetive value they can contain. A negetive off_equipment_bonus value would be corrected to a positive value, for example, and 64 exceeds the max possible negetive equipment bonus achievable within the game. Following the multiplication of the two values, we divide by 10 for no reason other than to make small, more easily digestable numbers. This value is rounded down. */ double augmented_attack = 0; augmented_attack = Math.floor(((effective_attack + 8) * (off_equipment_bonus + 64)) / 10); /* Name augmented_defence Type: Base Value Description: Base stat level post equipment stat value modifiers. This value is calculated as: math.floor(((effective_defence + 8) * (def_equipment_bonus + 64)) / 10) The same safety operations and readability optimisations are made here as mentioned above. */ double augmented_defence = 0; augmented_defence = Math.floor(((effective_defence +8) * (def_equipment_bonus + 64)) / 10); /* Name: hit_chance Type: Base Value Description: Base probability to hit calculated as a fraction of the lesser value. If augmented_attack has a lesser value than augmented_defence this means the value will be below 50%. Therefore: hit_chance = augmented_attack / (augmented_defence * 2) This calculation will provide us with a value sub 0.5, providing the chance to hit vs a superior equiped opponent. If augmented_attack has a greater value than augmented_defence this means the value will be above 50%. Therefore: hit_chance = augmented_defence / (augmented_attack * 2) This calculation will provide us with a value sur 0.5, providing the chance to hit vs a inferior equiped opponent. In addition to these calculations we subtract or add 1 to the value depending on whether augmented_attack is greater or lesser than augmented_defence. This small modification ensures that the lesser entity always has a value greater than 0 so we can ensure a minimum chance to block or hit of 1% at all times. */ double hit_chance = 0; if(augmented_attack < augmented_defence) { hit_chance = (augmented_attack - 1) / (augmented_defence * 2); } else { hit_chance = 1 - ((augmented_defence + 1) / (augmented_attack * 2)); } /* Name: off_special_attack_bonus Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on offensive entity special attack. This is an experimental chance modifier based on the assumption that certain special attacks modify offensive entity chance to hit post all other modifiers similar to how void equipment works. Please note this is a delicate value and brash modifiers will break the balance of the the algorithm completely. Default value: 1.0 Below are recomendations for this modifiers value depending on special attack being used: Dragon Dagger - 1.15 (+15%) Dragon Scimitar - 1.15 (+15%) Dragon Mace - 0.85 (-15%) Dragon Battleaxe - 0.90 (-10%) Rune Claw - 1.15 (+15%) Vesta's Longsword - 1.20 (+20%) Brackish Blade - 2.0 (+100%) Magic Shortbow - 0.85 (-15%) Magic Shieldbow - 1.15 (+15%) Hand Cannon - 1.75 (+75%) Please note: Anything not listed above DOES NOT have a specal attack accuracy modifier. Korasi Sword is an exception to this and requires a special case which sets the off_hit_chance roll to 100. I have not had the opportunity to test these values, however they are educated guesses based on observations made regarding simularities in max hit and accuracy calculations. These values unless stated otherwise, are NOT meant to be dramatic modifiers. Other systems present in this algorithm will do much of the heavy lifting with securing a hit when using special attacks. */ double off_special_attack_bonus = 1.0; /* Name: off_void_bonus Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on if a full set of void equipment is worn, and which type. Default value: 1.0 Void Set Modifier Values: Melee - 1.10 (10%) Ranged - 1.10 (10%) Magic - 1.30 (30%) */ double off_void_bonus = 1.0; /* Name: def_protect_from_* Type: Multiplicative Bonus Description: Multiplicative hit chance modifier depending on if the defensive entity is using a protect from * prayer that matches the offensive entities combat type. Prior to the dice being rolled, if the defensive entity is using a protect from * prayer that corresponds with the offensive entities combat type hit_chance is multiplied by .6 reducing the offensive entities chance to hit, and increasing the defensive entities chance to block. Protect from * prayers reduce damage and chance to hit by 60% in player vs player combat. */ boolean def_protect_from_melee = false; boolean def_protect_from_ranged = false; boolean def_protect_from_magic = false; /* Name: off_hit_chance Type: Base Value Description: Base probability to hit post chance modifiers. This value is used to roll a dice and determine if the offensive entity is granted a hit or not. This is calculated as: math.random(0, off_hit_chance) math.random(0, def_block_chance) if(off_hit_chance > def_block_chance) { //hit } else { //block } Both entities roll a dice between 0 and their calculated chance to hit or block, whoever has the greatest value is successful. This provides a chance for the defensive entity to fail a block, as opposed to the defensive entity being ensured a block if the offensive entity does not successfully hit. This is another problem present in the currently utilised version of the algorithm that gives the illusion of "overpowered defence". Giving the defensive entity an ensured block puts the offensive entity at a huge disadvantage. */ double off_hit_chance = 0; switch(off_combat_type) { case "melee": if(def_protect_from_melee == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); } break; case "ranged": if(def_protect_from_ranged == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); } break; case "magic": if(def_protect_from_magic == true) { off_hit_chance = Math.floor(((hit_chance * off_void_bonus) * .6) * 100); } else { off_hit_chance = Math.floor((hit_chance * off_void_bonus) * 100); } break; } System.out.println("\nYour chance to hit is: " + off_hit_chance + "%"); off_hit_chance = 0 + (int)(Math.random() * off_hit_chance); /* Name: def_block_chance Type: Base Value Description: Base probability to block post chance modifiers. This value is used to roll a dice and determine if the defensive entity is granted a block or not. See above for details on calculation. */ double def_block_chance = 0; switch(off_combat_type) { case "melee": if(def_protect_from_melee == true) { def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "ranged": if(def_protect_from_ranged == true) { def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "magic": if(def_protect_from_magic == true) { def_block_chance = Math.floor(101 - (((hit_chance * off_void_bonus) * .6) * 100)); } else { def_block_chance = Math.floor(101 - ((hit_chance * off_void_bonus) * 100)); } break; } System.out.println("Your opponents chance to block is: " + def_block_chance + "%"); def_block_chance = 0 + (int)(Math.random() * def_block_chance); System.out.println("\nYou rolled: " + (int) off_hit_chance); System.out.println("Your opponent rolled: " + (int) def_block_chance); if(off_hit_chance > def_block_chance) { System.out.print("\nYou hit your opponent!"); } else { System.out.print("\nYour opponent blocked your hit."); } } //end main } //end class[/CODE] Here is how a working version might look with the above readability taken out: [CODE]public class accuracy_sm { public static void main(String args[]) { /* S E T T I N G S S T A R T */ //attack types String off_combat_type = "melee"; //melee, ranged, magic String off_style = "stab"; //stab, slash, crush, ranged, magic //attack stances int off_stance_bonus = 0; //accurate, aggressive, controlled, defensive int def_stance_bonus = 0; //accurate, aggressive, controlled, defensive //requirements int off_weapon_requirement = 1; //weapon attack level requirement int off_spell_requirement = 1; //spell magic level requirement //base levels int off_base_attack_level = 99; int off_base_ranged_level = 99; int off_base_magic_level = 99; //current levels double off_current_attack_level = 99; double off_current_ranged_level = 99; double off_current_magic_level = 99; double def_current_defence_level = 99; double def_current_magic_level = 99; //prayer bonuses double off_attack_prayer_bonus = 1.0; double off_ranged_prayer_bonus = 1.0; double off_magic_prayer_bonus = 1.0; double def_defence_prayer_bonus = 1.0; //additional bonus double off_additional_bonus = 1.0; //equipment bonuses int off_equipment_stab_attack = 0; int off_equipment_slash_attack = 0; int off_equipment_crush_attack = 0; int off_equipment_ranged_attack = 0; int off_equipment_magic_attack = 0; int def_equipment_stab_defence = 0; int def_equipment_slash_defence = 0; int def_equipment_crush_defence = 0; int def_equipment_ranged_defence = 0; int def_equipment_magic_defence = 0; //protect from * prayers boolean def_protect_from_melee = false; boolean def_protect_from_ranged = false; boolean def_protect_from_magic = false; //chance bonuses double off_special_attack_bonus = 1.0; double off_void_bonus = 1.0; /* S E T T I N G S E N D */ /* C A L C U L A T E D V A R I A B L E S S T A R T */ //experience bonuses double off_spell_bonus = 0; double off_weapon_bonus = 0; //effective levels double effective_attack = 0; double effective_magic = 0; double effective_defence = 0; //relevent equipment bonuses int off_equipment_bonus = 0; int def_equipment_bonus = 0; //augmented levels double augmented_attack = 0; double augmented_defence = 0; //hit chances double hit_chance = 0; double off_hit_chance = 0; double def_block_chance = 0; /* C A L C U L A T E D V A R I A B L E S E N D */ //determine effective attack switch(off_combat_type){ case "melee": if(off_base_attack_level > off_weapon_requirement) { off_weapon_bonus = (off_base_attack_level - off_weapon_requirement) * .3; } effective_attack = Math.floor(((off_current_attack_level * off_attack_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); switch(off_style) { case "stab": off_equipment_bonus = off_equipment_stab_attack; def_equipment_bonus = def_equipment_stab_defence; break; case "slash": off_equipment_bonus = off_equipment_slash_attack; def_equipment_bonus = def_equipment_slash_defence; break; case "crush": off_equipment_bonus = off_equipment_crush_attack; def_equipment_bonus = def_equipment_crush_defence; break; } break; case "ranged": if(off_base_ranged_level > off_weapon_requirement) { off_weapon_bonus = (off_base_ranged_level - off_weapon_requirement) * .3; } effective_attack = Math.floor(((off_current_ranged_level * off_ranged_prayer_bonus) * off_additional_bonus) + off_stance_bonus + off_weapon_bonus); effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) + def_stance_bonus); off_equipment_bonus = off_equipment_ranged_attack; def_equipment_bonus = def_equipment_ranged_defence; break; case "magic": if(off_base_magic_level > off_spell_requirement) { off_spell_bonus = (off_base_magic_level - off_spell_requirement) * .3; } effective_attack = Math.floor(((off_current_magic_level * off_magic_prayer_bonus) * off_additional_bonus) + off_spell_bonus); effective_magic = Math.floor(def_current_magic_level * .7); effective_defence = Math.floor((def_current_defence_level * def_defence_prayer_bonus) * .3); effective_defence = effective_defence + effective_magic; off_equipment_bonus = off_equipment_magic_attack; def_equipment_bonus = def_equipment_magic_defence; break; } //determine augmented levels augmented_attack = Math.floor(((effective_attack + 8) * (off_equipment_bonus + 64)) / 10); augmented_defence = Math.floor(((effective_defence +8) * (def_equipment_bonus + 64)) / 10); //determine hit chance if(augmented_attack < augmented_defence) { hit_chance = (augmented_attack - 1) / (augmented_defence * 2); } else { hit_chance = 1 - ((augmented_defence + 1) / (augmented_attack * 2)); } switch(off_combat_type) { case "melee": if(def_protect_from_melee == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "ranged": if(def_protect_from_ranged == true) { off_hit_chance = Math.floor((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100); def_block_chance = Math.floor(101 - ((((hit_chance * off_special_attack_bonus) * off_void_bonus) * .6) * 100)); } else { off_hit_chance = Math.floor(((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100); def_block_chance = Math.floor(101 - (((hit_chance * off_special_attack_bonus) * off_void_bonus) * 100)); } break; case "magic": if(def_protect_from_magic == true) { off_hit_chance = Math.floor(((hit_chance * off_void_bonus) * .6) * 100); def_block_chance = Math.floor(101 - (((hit_chance * off_void_bonus) * .6) * 100)); } else { off_hit_chance = Math.floor((hit_chance * off_void_bonus) * 100); def_block_chance = Math.floor(101 - ((hit_chance * off_void_bonus) * 100)); } break; } //print hit chance System.out.println("\nYour chance to hit is: " + off_hit_chance + "%"); System.out.println("Your opponents chance to block is: " + def_block_chance + "%"); //roll dice off_hit_chance = 0 + (int)(Math.random() * off_hit_chance); def_block_chance = 0 + (int)(Math.random() * def_block_chance); //print roll System.out.println("\nYou rolled: " + (int) off_hit_chance); System.out.println("Your opponent rolled: " + (int) def_block_chance); //determine hit if(off_hit_chance > def_block_chance) { //print hit System.out.print("\nYou hit your opponent!"); } else { //print block System.out.print("\nYour opponent blocked your hit."); } } //end main } //end class[/CODE] [SIZE=5]Test Cases[/SIZE] Unarmed vs unarmed, same stats (99): [CODE] Chance 60.0% & 40.0% || Rolled: 1 & 28 || BLOCK Chance 60.0% & 40.0% || Rolled: 33 & 17 || HIT Chance 60.0% & 40.0% || Rolled: 28 & 29 || BLOCK Chance 60.0% & 40.0% || Rolled: 18 & 27 || BLOCK Chance 60.0% & 40.0% || Rolled: 12 & 10 || HIT Chance 60.0% & 40.0% || Rolled: 15 & 12 || HIT Chance 60.0% & 40.0% || Rolled: 36 & 20 || HIT Chance 60.0% & 40.0% || Rolled: 49 & 28 || HIT Chance 60.0% & 40.0% || Rolled: 24 & 22 || HIT Chance 60.0% & 40.0% || Rolled: 25 & 35 || BLOCK[/CODE] Rune-whip vs rune w/shield, 118 attack vs 99 defence, piety: [CODE] Chance 32.0% & 68.0% || Rolled: 28 & 47 || BLOCK Chance 32.0% & 68.0% || Rolled: 23 & 1 || HIT Chance 32.0% & 68.0% || Rolled: 27 & 11 || HIT Chance 32.0% & 68.0% || Rolled: 26 & 25 || HIT Chance 32.0% & 68.0% || Rolled: 15 & 27 || BLOCK Chance 32.0% & 68.0% || Rolled: 30 & 11 || HIT Chance 32.0% & 68.0% || Rolled: 0 & 62 || BLOCK Chance 32.0% & 68.0% || Rolled: 11 & 34 || BLOCK Chance 32.0% & 68.0% || Rolled: 31 & 22 || HIT Chance 32.0% & 68.0% || Rolled: 1 & 9 || BLOCK[/CODE] Rune-whip vs adamant w/shield, 118 attack vs 30 defence, both piety: [CODE] Chance 78.0% & 22.0% || Rolled: 45 & 2 || HIT Chance 78.0% & 22.0% || Rolled: 70 & 13 || HIT Chance 78.0% & 22.0% || Rolled: 8 & 15 || BLOCK Chance 78.0% & 22.0% || Rolled: 41 & 19 || HIT Chance 78.0% & 22.0% || Rolled: 62 & 10 || HIT Chance 78.0% & 22.0% || Rolled: 67 & 13 || HIT Chance 78.0% & 22.0% || Rolled: 2 & 15 || BLOCK Chance 78.0% & 22.0% || Rolled: 63 & 9 || HIT Chance 78.0% & 22.0% || Rolled: 49 & 19 || HIT Chance 78.0% & 22.0% || Rolled: 70 & 2 || HIT[/CODE] rune-defender whip vs rune-defender rune armour, 118 attack vs 80 defence, both incredible reflexes: [CODE]Chance 59.0% & 41.0% || Rolled: 0 & 11 || BLOCK Chance 59.0% & 41.0% || Rolled: 49 & 21 || HIT Chance 59.0% & 41.0% || Rolled: 41 & 12 || HIT Chance 59.0% & 41.0% || Rolled: 4 & 11 || BLOCK Chance 59.0% & 41.0% || Rolled: 28 & 20 || HIT Chance 59.0% & 41.0% || Rolled: 12 & 25 || BLOCK Chance 59.0% & 41.0% || Rolled: 18 & 38 || BLOCK Chance 59.0% & 41.0% || Rolled: 17 & 6 || HIT Chance 59.0% & 41.0% || Rolled: 8 & 2 || HIT Chance 59.0% & 41.0% || Rolled: 27 & 4 || HIT[/CODE] rune-defender dragon scimitar vs rune-defender rune armour, 118 attack vs 80 defence, both incredible reflexes: [CODE] Chance 55.0% & 45.0% || Rolled: 42 & 34 || HIT Chance 55.0% & 45.0% || Rolled: 13 & 36 || BLOCK Chance 55.0% & 45.0% || Rolled: 7 & 7 || BLOCK Chance 55.0% & 45.0% || Rolled: 36 & 3 || HIT Chance 55.0% & 45.0% || Rolled: 7 & 28 || BLOCK Chance 55.0% & 45.0% || Rolled: 52 & 2 || HIT Chance 55.0% & 45.0% || Rolled: 30 & 23 || HIT Chance 55.0% & 45.0% || Rolled: 25 & 6 || HIT Chance 55.0% & 45.0% || Rolled: 26 & 23 || HIT Chance 55.0% & 45.0% || Rolled: 31 & 40 || BLOCK[/CODE] full mystic ancient staff ice blitz vs rune armour defender, 99 magic vs 99 magic&80 defence: [CODE]Chance 81.0% & 19.0% || Rolled: 11 & 15 || BLOCK Chance 81.0% & 19.0% || Rolled: 48 & 16 || HIT Chance 81.0% & 19.0% || Rolled: 7 & 16 || BLOCK Chance 81.0% & 19.0% || Rolled: 47 & 3 || HIT Chance 81.0% & 19.0% || Rolled: 30 & 9 || HIT Chance 81.0% & 19.0% || Rolled: 23 & 11 || HIT Chance 81.0% & 19.0% || Rolled: 33 & 18 || HIT Chance 81.0% & 19.0% || Rolled: 74 & 11 || HIT Chance 81.0% & 19.0% || Rolled: 76 & 6 || HIT Chance 81.0% & 19.0% || Rolled: 58 & 13 || HIT[/CODE] full mystic ancient staff ice blitz vs black dragonhide, 99 magic vs 99 magic&99 defence: [CODE]Chance 43.0% & 57.0% || Rolled: 37 & 4 || HIT Chance 43.0% & 57.0% || Rolled: 5 & 28 || BLOCK Chance 43.0% & 57.0% || Rolled: 27 & 19 || HIT Chance 43.0% & 57.0% || Rolled: 35 & 51 || BLOCK Chance 43.0% & 57.0% || Rolled: 10 & 9 || HIT Chance 43.0% & 57.0% || Rolled: 23 & 20 || HIT Chance 43.0% & 57.0% || Rolled: 27 & 5 || HIT Chance 43.0% & 57.0% || Rolled: 23 & 33 || BLOCK Chance 43.0% & 57.0% || Rolled: 32 & 39 || BLOCK Chance 43.0% & 57.0% || Rolled: 17 & 44 || BLOCK[/CODE] ice blitz, full rune, abyssal whip vs full rune, 99 magic vs 99 magic 99 defence: [CODE]Chance 34.0% & 66.0% || Rolled: 30 & 21 || HIT Chance 34.0% & 66.0% || Rolled: 23 & 32 || BLOCK Chance 34.0% & 66.0% || Rolled: 28 & 10 || HIT Chance 34.0% & 66.0% || Rolled: 24 & 10 || HIT Chance 34.0% & 66.0% || Rolled: 29 & 55 || BLOCK Chance 34.0% & 66.0% || Rolled: 6 & 43 || BLOCK Chance 34.0% & 66.0% || Rolled: 12 & 18 || BLOCK Chance 34.0% & 66.0% || Rolled: 6 & 12 || BLOCK Chance 34.0% & 66.0% || Rolled: 33 & 34 || BLOCK Chance 34.0% & 66.0% || Rolled: 21 & 7 || HIT[/CODE] ice blitz, full rune, abyssal whip vs black dragonhide, 99 magic vs 99 magic 99 defence: [CODE]Chance 11.0% & 89.0% || Rolled: 8 & 12 || BLOCK Chance 11.0% & 89.0% || Rolled: 2 & 20 || BLOCK Chance 11.0% & 89.0% || Rolled: 10 & 40 || BLOCK Chance 11.0% & 89.0% || Rolled: 0 & 72 || BLOCK Chance 11.0% & 89.0% || Rolled: 9 & 71 || BLOCK Chance 11.0% & 89.0% || Rolled: 1 & 44 || BLOCK Chance 11.0% & 89.0% || Rolled: 0 & 32 || BLOCK Chance 11.0% & 89.0% || Rolled: 9 & 1 || HIT Chance 11.0% & 89.0% || Rolled: 5 & 76 || BLOCK Chance 11.0% & 89.0% || Rolled: 2 & 74 || BLOCK[/CODE] [SIZE=4]FAQ[/SIZE] [I]Can this be applied to Non Player Characters?[/I] Yes. I've developed a method of estimating non player character stat levels, and in doing this we can treat them just like player characters for the purpose of accuracy calculation. This has obvious benefits too, which result in emulation closer to Runescape and provide additional utility to armour for both player and non player characters. Coming soon. [SIZE=4]Postface[/SIZE] Earlier this year my good friend Alex, or Light232 passed away. This brings an unfortunate end to our work together. In light of the situation I'd like to release some of my research, enjoy. I'll be posting more threads like this soon.
  15. Hey guys , I got a ::player command but it only says there are currently (how many players are online) online but i want to make the ::player command says which players are online too This is my command in player.java } else if (keyword.equals("players")) { actionSender.sendMessage("There are currently " + World.playerAmount() + " players online.");
  16. Hey guys , I want to make an autoplayer saver for my server. so I mean it saves the players of the game every 60 seconds as example. Thank you for your time
  17. What is your favorite RS Player can be popular or can be not. Mine are: [CODE]Boomer Twin skat247 - Meh Nigguh from RS2001-06 [/CODE]
  18. PLEASE READ FIRST:: I will give 5$ over paypal to anybody who can SUCCESSFULLY get my source to change rights. WARNING: this is not your average source, i have changed player rights before. My source is [SIZE=5]@@@@@(VANITY)@@@@@[/SIZE] If you can help me change the player rights I will rep+ you and give you five dollars If you help and fail I will rep+ you but you will not recieve the 5$ reward, thank you [SIZE=5]I will need help using skype and I will share my screen, Thank You[/SIZE]
  19. Can anyone help me to change my players status to owner/admin on nexon-world server, i already switched out nexon for my username in action sender.java and in commands.java i can't get it to work, i made sure to compile everything as well.
  20. [url]http://gyazo.com/d617c5b3fe5e195cc2c2764bb86dabe9[/url] Title says it all, thanks in advance! Anyone with a solution please reply, i'll try it all.
  21. I know how to code dialogues and to open them on npcs. But I wanted to add it so that it checks the player for four items and it choose which dialogue to do. This is what I tried doing: (I'm using PI) [code] case 8542: //head snow imp lower level if ((c.getItems().playerHasItem(20083, 1)) && (c.getItems().playerHasItem(11952, 1)) &&(c.getItems().playerHasItem(11954, 1)) (c.getItems().playerHasItem(11953, 1))) { //second dialouge here for teleport c.getDH().sendDialogues(888, npcType); //santa at base } else { c.getDH().sendDialogues(888, npcType); //santa at base //cock block dialouge } } break; [/code] Am I using too many parentheses or am just too much of a noob? :p Edit: 888 is coded for Santa. I have yet to code the dialogue for the npc 8542 thats why I added 888 for this npc
  22. Having some troubles with rights using dementhium source mods have more rights then admins i've been trying to fix for so long please add my skype @ [B][U]tjl.beatz[/U][/B]
  23. [CENTER][SIZE=3][COLOR="#FFA500"]Neptos PK[/COLOR][/SIZE] [COLOR="#FFA500"][B]Developers[/B][/COLOR] Fuzen Seth (Content Developer) Shony (Content Developer) [COLOR="#FFA500"]Neptos Details[/COLOR] Framework: Project Instanity (PI) Items: 634 revision NPCS: 525 Maps: 474 Characters: 667 [COLOR="#FFA500"][COLOR="#FFA500"][COLOR="#FFA500"][B]About Neptos[/B][/COLOR][/COLOR][/COLOR] Neptos will be a PKing server with killstreak and artefacts system. Players are able to purchase items such as TokHaar-Kal from the PK Points shop. Killstreak system will be written from scratch and so does artefacts system. We are also planning to make wildy 'pvp' -area with NO actual PvP loots. But players would have percent changes to get a pvp rare item. Also Neptos would include bounty hunter. This is a spawn server, but people wouldn't be able to spawn all items. [COLOR="#FFA500"][B]Updates[/B] [/COLOR] [QUOTE]6.11.2013 -Updated Combat System -Started killstreaks -Started artefacts -Firemaking fixes- - 3-4 dupe fixes. -Magic combat fixes -Itemswitching is decent and upgraded. -Bounty hunter started -Added Overloads effect fully, if you drink saradomin brews your stats stay at 125. -Added TokHaar-Kal [/QUOTE] [B] [COLOR="#FFA500"]Media[/B][/COLOR] [img]http://puu.sh/5apaW.jpg[/img] [img]http://puu.sh/5aoW3.jpg[/img] [img]http://puu.sh/5aoZz.jpg[/img] [/CENTER] More will be added to this thread. It is extremely new.
  24. My player counting isnt working. It doesnt count how many players are online it just says they're 0. Heres the code: [CODE] getPA().sendFrame126("Players Online: " + PlayerHandler.getPlayerCount(), 19161);[/CODE] PlayerHandler.java : [CODE]package com.exile.game.players; import java.net.InetSocketAddress; import com.exile.Constants; import com.exile.GameEngine; import com.exile.game.npcs.NPCHandler; import com.exile.game.players.content.minigames.impl.dueling.DuelPlayer; import com.exile.util.Misc; import com.exile.util.Stream; import java.util.ArrayList; import java.util.concurrent.ScheduledExecutorService; public class PlayerHandler { public static Player players[] = new Player[Constants.MAX_PLAYERS]; public static String messageToAll = ""; public static int playerCount = 0; public static boolean updateAnnounced; public static boolean updateRunning; public static int updateSeconds; public static long updateStartTime; public static boolean kickAllPlayers = false; static { for (int i = 0; i < Constants.MAX_PLAYERS; i++) { players[i] = null; } } public static Player[] getPlayers() { return players; } public boolean newPlayerPlayer(Player player1) { int slot = -1; for (int i = 1; i < Constants.MAX_PLAYERS; i++) { if ((players[i] == null) || players[i].disconnected) { slot = i; break; } } if (slot == -1) { return false; } player1.handler = this; player1.playerId = slot; players[slot] = player1; players[slot].isActive = true; players[slot].connectedFrom = ((InetSocketAddress) player1.getSession().getRemoteAddress()).getAddress().getHostAddress(); if (Constants.SERVER_DEBUG) { Misc.println("Player Slot " + slot + " slot 0 " + players[0] + " Player Hit " + players[slot]); } return true; } public static int[] toIntArray(ArrayList<Integer> integerList) { int[] intArray = new int[integerList.size()]; for (int i = 0; i < integerList.size(); i++) { intArray[i] = integerList.get(i); } return intArray; } public void destruct() { for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] == null) { continue; } players[i].destruct(); players[i] = null; } } public static int getPlayerCount() { return playerCount; } public static boolean isPlayerOn(final String playerName) { for (int d = 0; d < Constants.MAX_PLAYERS; d++) { if (PlayerHandler.players[d] != null) { final Player p = PlayerHandler.players[d]; if (p.playerName.toLowerCase().equals(playerName.toLowerCase())) { return true; } } } return false; } public static void process(int i, ScheduledExecutorService thread) { if (players[i] == null || !players[i].isActive) { thread.shutdownNow(); return; } if (kickAllPlayers) { players[i].disconnected = true; } Player c = (Player) PlayerHandler.players[i]; if (c != null && c.disconnected && (System.currentTimeMillis() - c.getVariables().logoutDelay > 10000 || c.getVariables().properLogout || kickAllPlayers)) { if (players[i].getVariables().inTrade) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } if (c != null && DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.duelVictory(c.opponent); } } else if (c != null && !DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } Player o = (Player) PlayerHandler.players[i]; if (PlayerSave.saveGame(o)) { System.out.println("Game saved for player " + players[i].playerName); } else { System.out.println("Could not save for " + players[i].playerName); } removePlayer(players[i]); players[i] = null; return; } players[i].preProcessing(); while (players[i].processQueuedPackets()); players[i].process(); players[i].postProcessing(); players[i].getNextPlayerMovement(); if (players[i] == null || !players[i].isActive) { players[i] = null; thread.shutdownNow(); return; } if (players[i].disconnected && (System.currentTimeMillis() - players[i].getVariables().logoutDelay > 10000 || players[i].getVariables().properLogout || kickAllPlayers)) { if (players[i].getVariables().inTrade) { Player o = (Player) PlayerHandler.players[players[i].getVariables().tradeWith]; if (o != null) { o.getTradeHandler().declineTrade(false); } } c = (Player) PlayerHandler.players[i]; if (c != null && DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.duelVictory(c.opponent); } } else if (c != null && !DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } Player o1 = (Player) PlayerHandler.players[i]; if (PlayerSave.saveGame(o1)) { System.out.println("Game saved for player " + players[i].playerName); } else { System.out.println("Could not save for " + players[i].playerName); } removePlayer(players[i]); players[i] = null; return; } else { if (!players[i].getVariables().initialized) { players[i].initialize(); players[i].getVariables().initialized = true; } else { players[i].update(); } } if (updateRunning && !updateAnnounced) { updateAnnounced = true; GameEngine.UpdateServer = true; } if (updateRunning && (System.currentTimeMillis() - updateStartTime > (updateSeconds * 1000))) { kickAllPlayers = true; } if (players[i] == null || !players[i].isActive) { players[i] = null; thread.shutdownNow(); return; } try { players[i].clearUpdateFlags(); } catch (Exception e) { e.printStackTrace(); } /*if (updateRunning && !updateAnnounced) { updateAnnounced = true; GameEngine.UpdateServer = true; } if (updateRunning && (System.currentTimeMillis() - updateStartTime > (updateSeconds * 1000))) { kickAllPlayers = true; } */ } public void process() { if (kickAllPlayers) { for (int i = 1; i < Constants.MAX_PLAYERS; i++) { if (players[i] != null) { players[i].disconnected = true; } } } for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] == null || !players[i].isActive) { continue; } Player c = (Player) PlayerHandler.players[i]; if (c != null && c.disconnected && (System.currentTimeMillis() - c.getVariables().logoutDelay > 10000 || c.getVariables().properLogout || kickAllPlayers)) { if (players[i].getVariables().inTrade) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } if (c != null && DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.duelVictory(c.opponent); } } else if (c != null && !DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } Player o = (Player) PlayerHandler.players[i]; if (PlayerSave.saveGame(o)) { System.out.println("Game saved for player " + players[i].playerName); } else { System.out.println("Could not save for " + players[i].playerName); } removePlayer(players[i]); players[i] = null; continue; } players[i].preProcessing(); while (players[i].processQueuedPackets()); players[i].process(); players[i].postProcessing(); players[i].getNextPlayerMovement(); } for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] == null || !players[i].isActive) { continue; } if (players[i].disconnected && (System.currentTimeMillis() - players[i].getVariables().logoutDelay > 10000 || players[i].getVariables().properLogout || kickAllPlayers)) { if (players[i].getVariables().inTrade) { Player o = (Player) PlayerHandler.players[players[i].getVariables().tradeWith]; if (o != null) { o.getTradeHandler().declineTrade(false); } } Player c = (Player) PlayerHandler.players[i]; if (c != null && DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.duelVictory(c.opponent); } } else if (c != null && !DuelPlayer.contains(c)) { if (c.opponent != null) { c.opponent.Dueling.declineDuel(c.opponent, true, false); } } Player o1 = (Player) PlayerHandler.players[i]; if (PlayerSave.saveGame(o1)) { System.out.println("Game saved for player " + players[i].playerName); } else { System.out.println("Could not save for " + players[i].playerName); } removePlayer(players[i]); players[i] = null; } else { if (!players[i].getVariables().initialized) { players[i].initialize(); players[i].getVariables().initialized = true; } else { players[i].update(); } } } if (updateRunning && !updateAnnounced) { updateAnnounced = true; GameEngine.UpdateServer = true; } if (updateRunning && (System.currentTimeMillis() - updateStartTime > (updateSeconds * 1000))) { kickAllPlayers = true; } for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] == null || !players[i].isActive) { continue; } try { players[i].clearUpdateFlags(); } catch (Exception e) { e.printStackTrace(); } } /*if (updateRunning && !updateAnnounced) { updateAnnounced = true; GameEngine.UpdateServer = true; } if (updateRunning && (System.currentTimeMillis() - updateStartTime > (updateSeconds * 1000))) { kickAllPlayers = true; } */ } public void updateNPC(Player plr, Stream str) { updateBlock.currentOffset = 0; str.createFrameVarSizeWord(65); str.initBitAccess(); str.writeBits(8, plr.npcListSize); int size = plr.npcListSize; plr.npcListSize = 0; for (int i = 0; i < size; i++) { if (plr.getVariables().RebuildNPCList == false && plr.withinDistance(plr.npcList[i]) == true) { plr.npcList[i].updateNPCMovement(str); plr.npcList[i].appendNPCUpdateBlock(updateBlock, (Player) plr); plr.npcList[plr.npcListSize++] = plr.npcList[i]; } else { int id = plr.npcList[i].npcId; plr.npcInListBitmap[id >> 3] &= ~(1 << (id & 7)); str.writeBits(1, 1); str.writeBits(2, 3); } } /*if (Region.REGION_UPDATING_ENABLED) { if (Region.getRegion(plr.absX, plr.absY) != null) { for (NPC n : Region.getRegion(plr.absX, plr.absY).npcs) { if (n != null) { final int id = n.npcId; if ((plr.RebuildNPCList || (plr.npcInListBitmap[id >> 3] & 1 << (id & 7)) == 0) && plr.withinDistance(n)) { plr.addNewNPC(n, str, updateBlock); } } } } } else { for (int i = 0; i < NPCHandler.maxNPCs; i++) { if (NPCHandler.npcs[i] != null) { int id = NPCHandler.npcs[i].npcId; if (plr.withinDistance(NPCHandler.npcs[i]) && (plr.RebuildNPCList == false && (plr.npcInListBitmap[id >> 3] & (1 << (id & 7))) == 0)) { plr.addNewNPC(NPCHandler.npcs[i], str, updateBlock); } } } }*/ for (int i = 0; i < NPCHandler.maxNPCs; i++) { if (NPCHandler.npcs[i] != null) { int id = NPCHandler.npcs[i].npcId; if (plr.getVariables().RebuildNPCList == false && (plr.npcInListBitmap[id >> 3] & (1 << (id & 7))) != 0) { } else if (plr.withinDistance(NPCHandler.npcs[i]) == false) { } else { plr.addNewNPC(NPCHandler.npcs[i], str, updateBlock); } } } plr.getVariables().RebuildNPCList = false; if (updateBlock.currentOffset > 0) { str.writeBits(14, 16383); str.finishBitAccess(); str.writeBytes(updateBlock.buffer, updateBlock.currentOffset, 0); } else { str.finishBitAccess(); } str.endFrameVarSizeWord(); } public Stream updateBlock = new Stream(new byte[Constants.BUFFER_SIZE]); public int hitIcon, hitIcon2, hitMask, hitMask2; public void updatePlayer(Player plr, Stream str) { updateBlock.currentOffset = 0; if (updateRunning && !updateAnnounced) { str.createFrame(114); str.writeWordBigEndian(updateSeconds * 50 / 30); } plr.updateThisPlayerMovement(str); boolean saveChatTextUpdate = plr.isChatTextUpdateRequired(); plr.setChatTextUpdateRequired(false); plr.appendPlayerUpdateBlock(updateBlock); plr.setChatTextUpdateRequired(saveChatTextUpdate); str.writeBits(8, plr.playerListSize); int size = plr.playerListSize; if (size > 255) { size = 255; } plr.playerListSize = 0; for (int i = 0; i < size; i++) { if (!plr.didTeleport && !plr.playerList[i].didTeleport && plr.withinDistance(plr.playerList[i])) { plr.playerList[i].updatePlayerMovement(str); plr.playerList[i].appendPlayerUpdateBlock(updateBlock); plr.playerList[plr.playerListSize++] = plr.playerList[i]; } else { int id = plr.playerList[i].playerId; plr.playerInListBitmap[id >> 3] &= ~(1 << (id & 7)); str.writeBits(1, 1); str.writeBits(2, 3); } } /*if (Region.REGION_UPDATING_ENABLED) { if (Region.getRegion(plr.absX, plr.absY) != null) { for (Player p : Region.getRegion(plr.absX, plr.absY).players) { if (p != null && p.isActive && p != plr) { if ((plr.playerInListBitmap[p.playerId >> 3] & 1 << (p.playerId & 7)) == 0 && plr.withinDistance(p)) { plr.addNewPlayer(p, str, updateBlock); } } } } } else { for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] == null || !players[i].isActive || players[i] == plr) { continue; } int id = players[i].playerId; if ((plr.playerInListBitmap[id >> 3] & (1 << (id & 7))) != 0) { continue; } if (!plr.withinDistance(players[i])) { continue; } plr.addNewPlayer(players[i], str, updateBlock); } }*/ /*for (int i = 0; i < Constants.MAX_PLAYERS; i++) { if (players[i] != null && players[i].isActive && players[i] != plr) { final int id = players[i].playerId; if ((plr.playerInListBitmap[id >> 3] & 1 << (id & 7)) == 0 && plr.withinDistance(players[i])) { plr.addNewPlayer(players[i], str, updateBlock); } } }*/ if (plr.didTeleport) { plr.updateVisiblePlayers(); // so if we teleport and we are in our original region we are added back to the list for all the players that can see us } int[] addPlayers = toIntArray(plr.addPlayerList); int addSize = plr.getVariables().addPlayerSize; if (size + addSize > 255) { addSize = size - 255; } for (int i = 0; i < addSize; i++) { int id = addPlayers[i]; if(players[id] == null || !players[id].isActive || players[id] == plr) continue; if(!plr.withinDistance(players[id]) || (plr.playerInListBitmap[id >> 3] & (1 << (id & 7))) != 0) { continue; } plr.addNewPlayer(players[id], str, updateBlock); plr.getVariables().addPlayerSize--; // you could just put these in player.java plr.addPlayerList.remove((Integer)id); // but for the sake of the tutorial, it's right here. } if (plr.getVariables().addPlayerSize > 0) { plr.getVariables().addPlayerSize = 0; plr.addPlayerList.clear(); } //here if (updateBlock.currentOffset > 0) { str.writeBits(11, 2047); str.finishBitAccess(); str.writeBytes(updateBlock.buffer, updateBlock.currentOffset, 0); } else { str.finishBitAccess(); } str.endFrameVarSizeWord(); } public static void removePlayer(final Player plr) { if (plr.getVariables().privateChat != 2) { for (int d = 0; d < Constants.MAX_PLAYERS; d++) { if (PlayerHandler.players[d] != null && PlayerHandler.players[d].isActive) { final Player o = PlayerHandler.players[d]; if (o != null) { o.getPA().updatePM(plr.playerId, 0); } } } } plr.destruct(); } } [/CODE] Does anyone know any possible reasons why this is not working? Would thank someone a bunch if they fix it for me. Thanks!
×