Thread: Some OsBrutality Fixes

Page 1 of 3 123 LastLast
Results 1 to 10 of 27
  1. #1 Some OsBrutality Fixes 
    Registered Member
    Join Date
    Nov 2015
    Posts
    77
    Thanks given
    16
    Thanks received
    22
    Rep Power
    51
    Im not sure if anyone was having any problems but here are just some basic things. Ill post more if people request for more or if i happen to find any i think would be important.

    (This post has been edited 14 fixes/additions and counting)


    Talk to an npc (Banker) from across the bank booth


    Spoiler for distance to npc:
    Code:
    if (c.goodDistance(NPCHandler.npcs[c.npcClickIndex].getX(), NPCHandler.npcs[c.npcClickIndex].getY(),
    						c.getX(), c.getY(), NPCHandler.npcs[c.npcClickIndex].getSize()))
    Find this in ClickNPC.java under FIRST_CLICK (or anywhere you want to apply this).

    Code:
    if (c.goodDistance(NPCHandler.npcs[c.npcClickIndex].getX(), NPCHandler.npcs[c.npcClickIndex].getY(),
    						c.getX(), c.getY(), NPCHandler.npcs[c.npcClickIndex].getSize() + 1))
    Replace it with that (add +1 to the size.) This allows you to click to talk to bankers or other npcs from 1 spaces away, such as across a bank booth etc.



    Use Operate (for items like Amulet of Glory)

    Spoiler for How does one not realise this in the first place?:
    Code:
    case 1688:
    			c.getPA().useOperate(removeId);
    			break;
    Find that in Bank10.java, remove it and place it in Bank5.java. That will allow you to use operate on any desired item properly.




    Fixing wrong object Id's in your packet


    Spoiler for object Packets:
    Open up ClickObject.java in packets.

    Find and SecondClick and ThirdClick with:

    Code:
    case SECOND_CLICK:
    c.objectId = packet.getLEShortA(); // getUnsignedShortA
    			c.objectY = packet.getLEShort();
    			c.objectX = packet.getUnsignedShortA();
    			c.objectDistance = 1;
    Code:
    case THIRD_CLICK:
    c.objectX = packet.getLEShort();
    			c.objectY = packet.getUnsignedShort();
    			c.objectId = packet.getLEShortA();
    			c.objectDistance = 1;
    That will make all the clicks of object 1, 2 and 3 have the same id, x and y coords. If anyone was wondering why objects had different id's!


    Fix NPC Click 4 Packet (Give assignment for Slayer etc)

    Spoiler for Fix Packet ClickNpc4:

    Open up ClickNpc.java in your packets folder. Change the c.npcClickIndex (it's right under the case) to this. There you go.
    Code:
    c.npcClickIndex = packet.getLEShort();



    Save yourself some time defining npc attack/death anims

    Spoiler for emote:

    This will just allow you to leave human npc attack and death emote's 0, and will only work properly for human models. Other npcs with 0 attack/def animation withing your .json file will not work with this and must be defined seperately. Also, this makes the npc do a basic punch. So if the human npc has a weapon you might want to define that as well. But for every other npc (there are hundreds) that only punch, you dont have to bother changing it (: same with all Human npc death emotes. 0 will = 2304 which is standard death emote.

    go into your NPCHandler.java, find getAttackEmote and replace default with this
    Code:
                            //above default
    if (NPCHandler.getNpcListName(npcs[i].npcType).toLowerCase().equals("man")
    				|| NPCHandler.getNpcListName(npcs[i].npcType).toLowerCase().equals("woman")) {
    			return 422;  //You can also define all animations simply by name, although im sure this will cause lag if you have excessive npcs. (was running fine with some 4k npcs tho)
    		          }
                            default:          
                            NpcDefinition def = npcs[i].definition();                          
    			if (def.getAttackAnimation() == 0)
    				return 422;
    			else
    				return def != null ? def.getAttackAnimation() : -1;
    do the same for getDeadEmote
    Code:
    //above default
    if (NPCHandler.getNpcListName(npcs[i].npcType).toLowerCase().equals("man")
    				|| NPCHandler.getNpcListName(npcs[i].npcType).toLowerCase().equals("woman")) {
    			return 2304;  //Same explination as getAttackEmote
    		          }
                            default:
    			NpcDefinition def = npcs[i].definition();
    			if (def.getDeathAnimation() == 0)
    				return 2304;
    			else
    				return def != null ? def.getDeathAnimation() : -1;



    More Variables for NPC's!

    Spoiler for Max Mage Def = 255, dont forget!:
    This source also has Melee, Range and Magic defense loaded into the definition file. Why not use this? If you want to do this, theres only a few things you need to change. Ill give you the code to load it but implementing it within the combat system itself instead of just using normal defence is up to you

    Code:
    public static NPC newNPC(int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit,
    			int attack, int defence) {
    		// first, search for a free slot
    		int slot = -1;
    		for (int i = 1; i < maxNPCs; i++) {
    			if (npcs[i] == null) {
    				slot = i;
    				break;
    			}
    		}
    		if (slot == -1)
    			return null; // no free slot found
    		NPC newNPC = new NPC(slot, npcType);
    		newNPC.absX = x;
    		newNPC.absY = y;
    		newNPC.makeX = x;
    		newNPC.makeY = y;
    		newNPC.heightLevel = heightLevel;
    		newNPC.walkingType = WalkingType; // try
    		npcs[slot] = newNPC;
    		return newNPC;
    	}
    Replace your NPC newNPC method with this within NPCHandler.java.

    Code:
    newNPC(Integer.parseInt(token3[0]), Integer.parseInt(token3[1]), Integer.parseInt(token3[2]),
    							Integer.parseInt(token3[3]), Integer.parseInt(token3[4]),
    							getNpcListHP(Integer.parseInt(token3[0])), getNpcMaxHit(Integer.parseInt(token3[0])),
    							getNpcAttack(Integer.parseInt(token3[0])), getNpcCombatDefence(Integer.parseInt(token3[0])),
    							getNpcRangeDefence(Integer.parseInt(token3[0])),
    							getNpcMagicDefence(Integer.parseInt(token3[0])));
    Replace newNPC in loadAutoSpawn with that.

    Code:
    public static int getNpcMaxHit(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMaxHit();
    
    	}
    
    	public static int getNpcAttack(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getAttackBonus();
    
    	}
    
    	public static int getNpcCombatDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMeleeDefence();
    
    	}
    
    	public static int getNpcRangeDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getRangedDefence();
    
    	}
    
    	public static int getNpcMagicDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMagicDefence();
    
    	}
    (Still in NPCHandler.java) Add those underneath getNpcListHP.
    Now your done in the NPCHandler. Save that and open up NPC.java.

    Code:
    public NPC(int _npcId, int _npcType) {
    		NpcDefinition definition = NpcDefinition.DEFINITIONS[_npcType];
    		index = _npcId;
    		npcType = _npcType;
    		direction = -1;
    		isDead = false;
    		applyDead = false;
    		actionTimer = 0;
    		randomWalk = true;
    		if (definition != null) {
    			size = definition.getSize();
    			if (size < 1) {
    				size = 1;
    			}
    			HP = definition.getHitpoints();
    			maximumHealth = definition.getHitpoints();
    			attack = definition.getAttackBonus();
    			defence = definition.getMeleeDefence();
    			rangeDefence = definition.getRangedDefence();
    			magicDefence = definition.getMagicDefence();
    			maxHit = definition.getMaxHit();
    		}
    	}
    Your going to replace your current public NPC with that.

    Make sure you replace these.

    Code:
    public int makeX, makeY, maxHit, defence, rangeDefence, magicDefence, attack, moveX, moveY, direction, walkingType;
    Im pretty sure thats everything. You should have .getMagicDefence() etc within your NpcDefinition.java file already.

    Example of what you put in your .json file.

    Code:
    {
        "id": 2215,
        "name": "General Graardor",
        "examine": "A huge war chief.",
        "combat": 624,
        "size": 4,
        "attackable": true,
        "aggressive": false,
        "retreats": false,
        "poisonous": false,
        "respawn": 30,
        "maxHit": 60,
        "hitpoints": 255,
        "attackSpeed": 4,
        "attackAnim": 7018,
        "defenceAnim": -1,
        "deathAnim": 7062,
        "attackBonus": 280,
        "defenceMelee": 250,
        "defenceRange": 350,
        "defenceMage": 80
      },
    Use the getAttackEmote in NPCHandler to switch attackAnimations based on attackType etc. Dont bother with the aggression boolean, use the isAggressive method for that. Although I haven't tried the poisonous one yet which could provide useful as well.

    Code:
    c.sendMessage("NPCATT: " + NPCHandler.npcs[i].attack + "   NPCMELEEDEF: " + NPCHandler.npcs[i].defence
    				+ "   NPCRANGEDEF: " + NPCHandler.npcs[i].rangeDefence + "   NPCMDEF: + NPCHandler.npcs[i].magicDefence);"
    (stick that basically anywhere in attackNPC and you can see your changes in the NPCDefinition.json file. Can be quite helpful when doing some of the math for combat.


    Now how about those silly free shop items?

    Spoiler for how does this even work..?:
    To make the shops buy and sell using coins and not free, replace your ShopAssistant.java with this.

    Code:
    package org.brutality.model.shops;
    
    import org.brutality.Config;
    import org.brutality.Server;
    import org.brutality.model.items.ItemDefinition;
    import org.brutality.model.players.Player;
    import org.brutality.model.players.PlayerHandler;
    import org.brutality.model.players.PlayerSave;
    import org.brutality.util.Misc;
    import org.brutality.world.ShopHandler;
    
    public class ShopAssistant {
    
    	private Player c;
    
    	public ShopAssistant(Player client) {
    		this.c = client;
    	}
    
    	public boolean shopSellsItem(int itemID) {
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if (itemID == (ShopHandler.ShopItems[c.myShopId][i] - 1)) {
    				return true;
    			}
    		}
    		return false;
    	}
    
    	public static final int[][] PKP_DATA = { { 1050, 100000000 } };
    
    	/**
    	 * Shops
    	 **/
    
    	public void openShop(int ShopID) {
    		if (Server.getMultiplayerSessionListener().inAnySession(c)) {
    			return;
    		}
    		c.getItems().resetItems(3823);
    		resetShop(ShopID);
    		c.isShopping = true;
    		c.myShopId = ShopID;
    		c.getPA().sendFrame248(3824, 3822);
    		if (ShopID == 68)
    			c.getPA().sendFrame126("Fishing Tourney Shop - Points: " + c.fishingTourneyPoints, 3901);
    		else if (ShopID == 72)
    			c.getPA().sendFrame126("Blast Mine Shop - Points: " + c.blastPoints, 3901);
    		else if (ShopID == 74)
    			c.getPA().sendFrame126("Sacrifice Shop - Points: " + c.hungerPoints, 3901);
    		else
    			c.getPA().sendFrame126(ShopHandler.ShopName[ShopID], 3901);
    	}
    
    	public void updatePlayerShop() {
    		for (int i = 1; i < Config.MAX_PLAYERS; i++) {
    			if (PlayerHandler.players[i] != null) {
    				if (PlayerHandler.players[i].isShopping == true && PlayerHandler.players[i].myShopId == c.myShopId
    						&& i != c.index) {
    					PlayerHandler.players[i].updateShop = true;
    				}
    			}
    		}
    	}
    
    	public void updateshop(int i) {
    		resetShop(i);
    	}
    
    	public void resetShop(int ShopID) {
    		// synchronized (c) {
    		int TotalItems = 0;
    		for (int i = 0; i < ShopHandler.MaxShopItems; i++) {
    			if (ShopHandler.ShopItems[ShopID][i] > 0) {
    				TotalItems++;
    			}
    		}
    		if (TotalItems > ShopHandler.MaxShopItems) {
    			TotalItems = ShopHandler.MaxShopItems;
    		}
    		if (ShopID == 80) {
    			c.getPA().sendFrame171(0, 28050);
    			c.getPA().sendFrame126("Bounties: " + Misc.insertCommas(Integer.toString(c.getBH().getBounties())), 28052);
    		} else {
    			c.getPA().sendFrame171(1, 28050);
    		}
    		c.getOutStream().createFrameVarSizeWord(53);
    		c.getOutStream().writeWord(3900);
    		c.getOutStream().writeWord(TotalItems);
    		int TotalCount = 0;
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if (ShopHandler.ShopItems[ShopID][i] > 0 || i <= ShopHandler.ShopItemsStandard[ShopID]) {
    				if (ShopHandler.ShopItemsN[ShopID][i] > 254) {
    					c.getOutStream().writeByte(255);
    					c.getOutStream().writeDWord_v2(ShopHandler.ShopItemsN[ShopID][i]);
    				} else {
    					c.getOutStream().writeByte(ShopHandler.ShopItemsN[ShopID][i]);
    				}
    				if (ShopHandler.ShopItems[ShopID][i] > Config.ITEM_LIMIT || ShopHandler.ShopItems[ShopID][i] < 0) {
    					ShopHandler.ShopItems[ShopID][i] = Config.ITEM_LIMIT;
    				}
    				c.getOutStream().writeWordBigEndianA(ShopHandler.ShopItems[ShopID][i]);
    				TotalCount++;
    			}
    			if (TotalCount > TotalItems) {
    				break;
    			}
    		}
    		c.getOutStream().endFrameVarSizeWord();
    		c.flushOutStream();
    		// }
    	}
    
    	public double getItemShopValue(int ItemID, int Type, int fromSlot) {
    		double ShopValue = 1;
    		double TotPrice = 0;
    		// int price = getSpecialItemValue(ItemID);
    		int price = ItemDefinition.forId(ItemID).getGeneralPrice();
    		int tokkul = ((ItemDefinition.forId(ItemID).getHighAlchValue() * 2)
    				+ (ItemDefinition.forId(ItemID).getHighAlchValue() / 2));
    		if (c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) {
    			ShopValue = price;
    		} else if ((c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) && price < 1) {
    			ShopValue = price + 1;
    		} else if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			ShopValue = tokkul;
    		} 
    		TotPrice = ShopValue;
    
    		return TotPrice;
    	}
    
    	/**
    	 * buy item from shop (Shop Price)
    	 **/
    
    	public void buyFromShopPrice(int removeId, int removeSlot) {
    		int ShopValue = (int) Math.floor(getItemShopValue(removeId, 0, removeSlot));
    		ShopValue *= 1.00;
    		String ShopAdd = "";
    		if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			c.sendMessage(c.getItems().getItemName(removeId) + ": currently costs "
    					+ ((ItemDefinition.forId(removeId).getHighAlchValue() * 2)
    							+ (ItemDefinition.forId(removeId).getHighAlchValue() / 2))
    					+ " tokkul.");
    			return;
    		} 
    		if (ShopValue >= 1000 && ShopValue < 1000000) {
    			ShopAdd = " (" + (ShopValue / 1000) + "K)";
    		} else if (ShopValue >= 1000000) {
    			ShopAdd = " (" + (ShopValue / 1000000) + " million)";
    		}
    		c.sendMessage(c.getItems().getItemName(removeId) + ": currently costs " + ShopValue + " Coins." + ShopAdd);
    	}
    
    	public int getBountyHunterItemCost(int itemId) {
    		switch (itemId) {
    		case 12783:
    			return 500_000;
    		case 12804:
    			return 25_000_000;
    		case 12851:
    			return 10_000_000;
    		case 12855:
    		case 12856:
    			return 2_500_000;
    		case 12833:
    			return 50_000_000;
    		case 12831:
    			return 35_000_000;
    		case 12829:
    			return 25_000_000;
    		case 14484:
    			return 125_000_000;
    
    		case 12800:
    		case 12802:
    			return 350_000;
    		case 12786:
    			return 100_000;
    		case 10926:
    			return 2_500;
    		case 12846:
    			return 8_000_000;
    		case 12420:
    		case 12421:
    		case 12419:
    		case 12457:
    		case 12458:
    		case 12459:
    			return 10_000_000;
    		case 12757:
    		case 12759:
    		case 12761:
    		case 12763:
    		case 12788:
    			return 500_000;
    		case 12526:
    			return 1_500_000;
    		case 12773:
    			return 15_000_000;
    		case 12849:
    		case 12798:
    			return 250_000;
    		case 12608:
    		case 12610:
    		case 12612:
    			return 350_000;
    		case 12775:
    		case 12776:
    		case 12777:
    		case 12778:
    		case 12779:
    		case 12780:
    		case 12781:
    		case 12782:
    			return 5_000;
    
    		default:
    			return Integer.MAX_VALUE;
    		}
    	}
    
    	public int getItemValueHungerGames(int id) {
    		switch (id) {
    		case 6762:
    			return 500;
    		case 20035:
    		case 20038:
    		case 20041:
    		case 20044:
    		case 20047:
    			return 2500;
    		case 13072:
    		case 13073:
    			return 7000;
    		case 11663:
    		case 11664:
    		case 11665:
    		case 8842:
    			return 5000;
    		}
    		return 0;
    	}
    
    	/**
    	 * Sell item to shop (Shop Price)
    	 **/
    	public void sellToShopPrice(int removeId, int removeSlot) {
    		
    		// if (c.myShopId == 22 || c.myShopId == 49 || c.myShopId == 116 ||
    		// c.myShopId == 9 || c.myShopId == 50 || c.myShopId == 12 || c.myShopId
    		// == 20 || c.myShopId == 2 || c.myShopId == 88 || c.myShopId == 111 ||
    		// c.myShopId == 113 || c.myShopId == 3
    		// || c.myShopId == 4 || c.myShopId == 5 || c.myShopId == 16) {
    		// //c.sendMessage("@red@You can't sell items to this shop!");
    		// return;
    		// }
    		for (int i : Config.ITEMS_KEPT_ON_DEATH) {
    			if (i == removeId) {
    				c.sendMessage("You can't sell " + c.getItems().getItemName(removeId).toLowerCase() + ".");
    				return;
    			}
    		}
    
    		boolean IsIn = false;
    		if (ShopHandler.ShopSModifier[c.myShopId] > 1) {
    			for (int j = 0; j <= ShopHandler.ShopItemsStandard[c.myShopId]; j++) {
    				if (removeId == (ShopHandler.ShopItems[c.myShopId][j] - 1)) {
    					IsIn = true;
    					break;
    				}
    			}
    		} else {
    			IsIn = true;
    		}
    		if (IsIn == false) {
    			c.sendMessage("You can't sell " + c.getItems().getItemName(removeId).toLowerCase() + " to this store.");
    		} else {
    			int ShopValue = (int) Math.floor(getItemShopValue(removeId, 1, removeSlot));
    			String ShopAdd = "";
    			if (ShopValue >= 1000 && ShopValue < 1000000) {
    				ShopAdd = " (" + (ShopValue / 1000) + "K)";
    			} else if (ShopValue >= 1000000) {
    				ShopAdd = " (" + (ShopValue / 1000000) + " million)";
    			}
    
    			if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    				c.sendMessage(c.getItems().getItemName(removeId) + ": shop will buy for "
    						+ ItemDefinition.forId(removeId).getLowAlchValue() + " tokkul" + ShopAdd);
    			} else {
    				c.sendMessage(c.getItems().getItemName(removeId) + ": shop will buy for "
    						+ (ItemDefinition.forId(removeId).getLowAlchValue() + 1) + " Coins.");
    			}
    		}
    	}
    
    	int items[] = { 661, 662 };
    
    	@SuppressWarnings("unused")
    	public boolean sellItem(int itemID, int fromSlot, int amount) {
    		if (Server.getMultiplayerSessionListener().inAnySession(c)) {
    			return false;
    		}
    		// if (c.myShopId == 22 || c.myShopId == 49 || c.myShopId == 116 ||
    		// c.myShopId == 9 || c.myShopId == 50 || c.myShopId == 12 || c.myShopId
    		// == 20 || c.myShopId == 2 || c.myShopId == 88 || c.myShopId == 111 ||
    		// c.myShopId == 113 || c.myShopId == 3
    		// || c.myShopId == 4 || c.myShopId == 5 || c.myShopId == 16) {
    		// c.sendMessage("@red@You can't sell items to this shop!");
    		// return false;
    		// }
    		for (int i : Config.ITEMS_KEPT_ON_DEATH) {
    			if (i == itemID) {
    				c.sendMessage("You can't sell " + c.getItems().getItemName(itemID).toLowerCase() + ".");
    				return false;
    			}
    		}
    		// if (c.myShopId == 115 || c.myShopId == 77 || c.myShopId == 14||
    		// c.myShopId == 116 || c.myShopId == 117 || c.myShopId == 71 ||
    		// c.myShopId == 78
    		// || c.myShopId == 80 || c.myShopId == 44 || c.myShopId == 22 ||
    		// c.myShopId == 66 || c.myShopId == 67
    		// || c.myShopId == 56 || c.myShopId == 20 || c.myShopId == 210 ||
    		// c.myShopId == 200 || c.myShopId == 68 || c.myShopId == 74 ||
    		// c.myShopId == 72
    		// || c.myShopId == 70 || c.myShopId == 69 || c.myShopId == 88) {
    		// c.sendMessage("@red@You can't sell items to this shop!");
    		// return false;
    		// }
    		if (c.getRights().isAdministrator() && !Config.ADMIN_CAN_SELL_ITEMS) {
    			c.sendMessage("Selling items as an admin has been disabled.");
    			return false;
    		}
    		if (amount > 0 && itemID == (c.playerItems[fromSlot] - 1)) {
    			if (ShopHandler.ShopSModifier[c.myShopId] > 1) {
    				boolean IsIn = false;
    				for (int i = 0; i <= ShopHandler.ShopItemsStandard[c.myShopId]; i++) {
    					if (itemID == (ShopHandler.ShopItems[c.myShopId][i] - 1)) {
    						IsIn = true;
    						break;
    					}
    				}
    				if (IsIn == false) {
    					c.sendMessage(
    							"You can't sell " + c.getItems().getItemName(itemID).toLowerCase() + " to this store.");
    					return false;
    				}
    			}
    
    			if (amount > c.playerItemsN[fromSlot] && (ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isNoted()
    					|| ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isStackable())) {
    				amount = c.playerItemsN[fromSlot];
    			} else if (amount > c.getItems().getItemAmount(itemID)
    					&& !ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isNoted()
    					&& !ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isStackable()) {
    				amount = c.getItems().getItemAmount(itemID);
    			}
    
    			int TotPrice2 = 0;
    			int TotPrice3 = 0;
    			for (int i = amount; i > 0; i--) {
    				TotPrice2 = ItemDefinition.forId(itemID).getLowAlchValue() + 1;
    				if (c.getItems().freeSlots() > 0 || c.getItems().playerHasItem(995)) {
    					if (!ItemDefinition.forId(itemID).isNoted()) {
    						c.getItems().deleteItem(itemID, c.getItems().getItemSlot(itemID), 1);
    					} else {
    						c.getItems().deleteItem(itemID, fromSlot, 1);
    					}
    					if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    						c.getItems().addItem(6529, TotPrice2 - 1);
    					} else {
    						c.getItems().addItem(995, (TotPrice2));
    					}
    				}
    			}
    
    			c.getItems().resetItems(3823);
    			resetShop(c.myShopId);
    			updatePlayerShop();
    			return true;
    		}
    		return true;
    	}
    
    	public boolean addShopItem(int itemID, int amount) {
    		boolean Added = false;
    		if (amount <= 0) {
    			return false;
    		}
    		if (ItemDefinition.forId(itemID).isNoted()) {
    			itemID = c.getItems().getUnnotedItem(itemID);
    		}
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if ((ShopHandler.ShopItems[c.myShopId][i] - 1) == itemID) {
    				ShopHandler.ShopItemsN[c.myShopId][i] += amount;
    				Added = true;
    			}
    		}
    		if (Added == false) {
    			for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    				if (ShopHandler.ShopItems[c.myShopId][i] == 0) {
    					ShopHandler.ShopItems[c.myShopId][i] = (itemID + 1);
    					ShopHandler.ShopItemsN[c.myShopId][i] = amount;
    					ShopHandler.ShopItemsDelay[c.myShopId][i] = 0;
    					break;
    				}
    			}
    		}
    		return true;
    	}
    
    	public void handleOtherShop(int itemID, int fromSlot, int amount) {
    
    		if (!shopSellsItem(itemID))
    			return;
    		if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			int itemId = c.getItems().getItemSlot(6529);
    			if (itemId != itemID) {
    				return;
    			}
    			if (c.getItems().playerHasItem(6529)
    					&& c.getItems().getItemAmount(6529) >= ItemDefinition.forId(itemID).getHighAlchValue() * 2.5) {
    				if (c.getItems().freeSlots() > 0) {
    					c.getItems().deleteItem(6529, (ItemDefinition.forId(itemID).getHighAlchValue() * 2)
    							+ (ItemDefinition.forId(itemID).getHighAlchValue() / 2));
    					c.getItems().addItem(itemID, 1);
    					ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    					ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    					if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    						ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    					}
    				}
    			} else {
    				c.sendMessage("You do not have enough tokkul to buy this item.");
    			}
    		}
    		c.getItems().resetItems(3823);
    		resetShop(c.myShopId);
    		updatePlayerShop();
    		PlayerSave.saveGame(c);
    	}
    
    	public boolean buyItem(int itemID, int fromSlot, int amount) {
    		if (c.inTrade) {
    			return false;
    		}
    		// Fixes dupe within shop via cheat engine.
    		if (!shopSellsItem(itemID) && c.myShopId != 14)
    			return false;
    
    		if (!shopSellsItem(itemID)) {
    			return false;
    		}
    		if (amount > 0) {
    			if (!shopSellsItem(itemID))
    				return false;
    			if (amount > ShopHandler.ShopItemsN[c.myShopId][fromSlot]) {
    				amount = ShopHandler.ShopItemsN[c.myShopId][fromSlot];
    			}
    			if (amount > c.getItems().freeSlots()) {
    				if (c.getItems().isStackable(itemID) && c.getItems().freeSlots() < 1)
    					return false;
    				if (!c.getItems().isStackable(itemID)) {
    					amount = c.getItems().freeSlots();
    					c.sendMessage("You do not have enough inventory space to buy that many.");
    				}
    			}
    			int TotPrice2 = 0;
    			int Slot, Slot1, Slot2 = 0;// Tokkul
    			if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    				handleOtherShop(itemID, fromSlot, amount);
    				return false;
    			}
    
    			for (int i = amount; i > 0; i--) {
    				TotPrice2 = (int) Math.floor(getItemShopValue(itemID, 0, fromSlot));
    				Slot = c.getItems().getItemSlot(995);
    				Slot1 = c.getItems().getItemSlot(6529);
    				if (Slot == -1 && c.myShopId != 65 && c.myShopId != 66 && c.myShopId != 67) {
    					c.sendMessage("You don't have enough coins.");
    					break;
    				}
    				if (Slot1 == -1 && c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    					c.sendMessage("You don't have enough tokkul.");
    					break;
    				}
    				if (TotPrice2 <= 0) {
    					TotPrice2 = (int) Math.floor(getItemShopValue(itemID, 0, fromSlot));
    					TotPrice2 *= 1.66;
    				} else {
    					if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    						if (c.playerItemsN[Slot1] >= TotPrice2) {
    							if (c.getItems().freeSlots() > 0) {
    								c.getItems().deleteItem(6529, c.getItems().getItemSlot(6529), TotPrice2);
    								c.getItems().addItem(itemID, 1);
    								ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    								ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    								if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    									ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    								}
    							} else {
    								c.sendMessage("You don't have enough space in your inventory.");
    								break;
    							}
    						} else {
    							c.sendMessage("You don't have enough tokkul.");
    							break;
    						}
    					}
    					if (c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) {
    						if (c.playerItemsN[Slot] >= TotPrice2) {
    							if (c.getItems().freeSlots() > 0) {
    								c.getItems().deleteItem(995, c.getItems().getItemSlot(995), TotPrice2);
    								c.getItems().addItem(itemID, 1);
    								ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    								ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    								if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    									ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    								}
    							} else {
    								c.sendMessage("You don't have enough space in your inventory.");
    								break;
    							}
    						} else {
    							c.sendMessage("You don't have enough coins.");
    							break;
    						}
    					}
    				}
    			}
    			c.getItems().resetItems(3823);
    			resetShop(c.myShopId);
    			updatePlayerShop();
    			PlayerSave.saveGame(c);
    			return true;
    		}
    		return false;
    	}
    
    	public void handleOtherShop(int itemID, int amount) {
    		if (!shopSellsItem(itemID)) {
    			c.sendMessage("Stop trying to cheat!");
    			return;
    		}
    		if (amount <= 0) {
    			c.sendMessage("You need to buy atleast one or more of this item.");
    			return;
    		}
    		if (!c.getItems().isStackable(itemID)) {
    			if (amount > c.getItems().freeSlots()) {
    				amount = c.getItems().freeSlots();
    			}
    		}
    		/*
    		 * if (c.myShopId == 115) { if (c.votePoints >=
    		 * getSpecialItemValue(itemID) * amount) { if (c.getItems().freeSlots()
    		 * > 0) { c.votePoints -= getSpecialItemValue(itemID) * amount;
    		 * c.getPA().loadQuests(); c.getItems().addItem(itemID, amount);
    		 * c.getItems().resetItems(3823); } } else { c.sendMessage(
    		 * "You do not have enough vote points to buy this item."); } }
    		 */
    	}
    
    	public void openSkillCape() {
    		int capes = get99Count();
    		if (capes > 1)
    			capes = 1;
    		else
    			capes = 0;
    		c.myShopId = 14;
    		setupSkillCapes(capes, get99Count());
    	}
    
    	/*
    	 * public int[][] skillCapes =
    	 * {{0,9747,4319,2679},{1,2683,4329,2685},{2,2680
    	 * ,4359,2682},{3,2701,4341,2703
    	 * },{4,2686,4351,2688},{5,2689,4347,2691},{6,2692,4343,2691},
    	 * {7,2737,4325,2733
    	 * },{8,2734,4353,2736},{9,2716,4337,2718},{10,2728,4335,2730
    	 * },{11,2695,4321,2697},{12,2713,4327,2715},{13,2725,4357,2727},
    	 * {14,2722,4345
    	 * ,2724},{15,2707,4339,2709},{16,2704,4317,2706},{17,2710,4361,
    	 * 2712},{18,2719,4355,2721},****,2737,4331,2739},{20,2698,4333,2700}};
    	 */
    	public int[] skillCapes = { 9747, 9753, 9750, 9768, 9756, 9759, 9762, 9801, 9807, 9783, 9798, 9804, 9780, 9795,
    			9792, 9774, 9771, 9777, 9786, 9810, 9765, 9789, 9948 };
    
    	public int get99Count() {
    		int count = 0;
    		for (int j = 0; j < c.playerLevel.length; j++) {
    			if (Player.getLevelForXP(c.playerXP[j]) >= 99) {
    				count++;
    			}
    		}
    		return count;
    	}
    
    	public void setupSkillCapes(int capes, int capes2) {
    		c.getPA().sendFrame171(1, 28050);
    		c.getItems().resetItems(3823);
    		c.isShopping = true;
    		c.myShopId = 14;
    		c.getPA().sendFrame248(3824, 3822);
    		c.getPA().sendFrame126("Skillcape Shop", 3901);
    
    		int TotalItems = 0;
    		TotalItems = capes2;
    		if (TotalItems > ShopHandler.MaxShopItems) {
    			TotalItems = ShopHandler.MaxShopItems;
    		}
    		c.getOutStream().createFrameVarSizeWord(53);
    		c.getOutStream().writeWord(3900);
    		c.getOutStream().writeWord(TotalItems);
    		for (int i = 0; i <= 22; i++) {
    			if (Player.getLevelForXP(c.playerXP[i]) < 99)
    				continue;
    			if (skillCapes[i] == -1)
    				continue;
    			c.getOutStream().writeByte(1);
    			c.getOutStream().writeWordBigEndianA(skillCapes[i] + 2);
    		}
    		c.getOutStream().endFrameVarSizeWord();
    		c.flushOutStream();
    		// }
    	}
    
    	public void skillBuy(int item) {
    		int nn = get99Count();
    		if (nn > 1)
    			nn = 1;
    		else
    			nn = 0;
    		for (int j = 0; j < skillCapes.length; j++) {
    			if (skillCapes[j] == item || skillCapes[j] + 1 == item) {
    				if (c.getItems().freeSlots() > 1) {
    					if (c.getItems().playerHasItem(995, 99000)) {
    						if (Player.getLevelForXP(c.playerXP[j]) >= 99) {
    							c.getItems().deleteItem(995, c.getItems().getItemSlot(995), 99000);
    							c.getItems().addItem(skillCapes[j] + nn, 1);
    							c.getItems().addItem(skillCapes[j] + 2, 1);
    						} else {
    							c.sendMessage("You must have 99 in the skill of the cape you're trying to buy.");
    						}
    					} else {
    						c.sendMessage("You need 99,000 coins to buy this item.");
    					}
    				} else {
    					c.sendMessage("You must have at least 1 inventory spaces to buy this item.");
    				}
    			}
    		}
    		c.getItems().resetItems(3823);
    	}
    
    	public void openVoid() {
    	}
    
    	public void buyVoid(int item) {
    	}
    
    }
    This wont be perfect, and it might screw up some of your existing shops that use other points. This is more so if you want to completely remove all that and start fresh from a coin base shop system and work around that. Buy price is item high alch value and sell price is low alch value. If the value is 0, it returns it as 1 so at least some of those items like buckets are 1 coin. Also shops 65, 66 and 67 I use as my tokkul shops so i just left them in there. Feel free to change or remove those, or just use them (probably easiest).


    SLAYER

    Spoiler for Slayer:
    I also released this recently if you want to replace the Slayer system as well. Delete all of the files in the slayer package and than add this.
    https://www.rune-server.ee/runescape...ayer-base.html


    Something better than movePlayer, with an animation and timer!

    Spoiler for Not movePlayer...:
    Code:
    public void forceTeleport(final Player player, final int animation, final int newX, final int newY,
    			final int newZ, int ticksBeforeAnim, int ticks) {
    		player.face(player.objectX, player.objectY);
    		if (animation != -1) {
    			if (ticksBeforeAnim < 1) {
    				player.animation(animation);				
    			} else {				
    				 CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
    			            @Override
    			            public void execute(CycleEventContainer container) {			           
    						player.animation(animation);
    						container.stop();
    					}
    			            @Override
    						public void stop() {							
    						}
    				}, 0);
    			}
    		}
    		 CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
    	            @Override
    	            public void execute(CycleEventContainer container) {
    				player.teleportToX = newX;
    				player.teleportToY = newY;
    				player.heightLevel = newZ;
    				
    				container.stop();
    			}
    	            @Override
    				public void stop() {
    					
    				}
    		}, ticks);
    	}
    Add this anywhere, AgilityHandler.Java, TeleportExecutor.java, Player.java, PlayerAssistant.java... wherever you feel it is convenient to grab it.

    Example of use under firstClickObject in ActionHandler.java :

    Code:
    case 16646:
    			if (c.absY == 3517) {  // Player, Animation, TO X, TO Y, TO Height, ticks before animation, amount of ticks event will run for.
    				c.getAgilityHandler().forceTeleport(c, 828, 3666, 3522, 1, 1, 2);
    			}
    			break;
    Use it if you like. I like it better than movePlayer.


    Ring of Suffering acts like recoil(uses recoils to charge)

    Spoiler for Ring of Suffering:
    This only apply's to NPC's, just copy it and replace it for the existing player recoil method.
    If you want to make Ring of Suffering/(i) act like a recoil, just add this. (doesnt impliment xAmount to add, pulls amount of noted and unnoted rings. Could have 2146 Noted and 11 unNoted, and it will delete and apply all of them into the correct amount of charges.)

    First off, open up ItemDef.java (Client Sided)
    Add this in there under ItemDef forId(int i)

    Code:
    case 19550: //Ring of Suffering
    			itemDef.itemActions = new String[5];
    			itemDef.itemActions[1] = "Wear";
    			itemDef.itemActions[2] = "Check";
    			break;
    		case 19710: //Ring of Suffering(i)
    			itemDef.itemActions = new String[5];
    			itemDef.itemActions[1] = "Wear";
    			itemDef.itemActions[2] = "Check";
    			itemDef.itemActions[3] = "Uncharge";
    			break;
    Add this under recoilHits; in Player.java
    Code:
    	public int sufferHits;
    Find removeRecoil in MeleeExtras.java and replace it with this. (If it's not there just add it above or below ApplyRecoilNPC)

    Code:
    public static void removeRecoil(Player c, int damage) {
    		if(c.recoilHits > 0) {
                            if (c.playerEquipment[c.playerRing] == 2550) {
                            	c.recoilHits -= damage;
                            }
    		} if(c.recoilHits <= 0) {
                if (c.playerEquipment[c.playerRing] == 2550) {
                		c.getItems().removeItem(2550, c.playerRing);
                			c.getItems().deleteItem(2550, c.getItems().getItemSlot(2550), 1);
                				c.sendMessage("Your ring of recoil shatters!");
                					c.recoilHits = 0;
                }            
    		}
    		if(c.sufferHits > 0) {
                if (c.playerEquipment[c.playerRing] == 19550 || c.playerEquipment[c.playerRing] == 19710) {
                	c.sufferHits -= damage;
                }
    		} if(c.sufferHits <= 0) {
    			if (c.playerEquipment[c.playerRing] == 19550 || c.playerEquipment[c.playerRing] == 19710) {
    					c.sendMessage("Your ring has run out of charges.");
    						c.sufferHits = 0;
    			}            
    		}
    	}
    Still in meleeExtras, replace applyRecoil with this

    Code:
    public static void applyRecoilNPC(Player c, int damage, int i) {
    		if (damage > 0 && c.playerEquipment[c.playerRing] == 2550
    				|| damage > 0 && c.playerEquipment[c.playerRing] == 19550
    				|| damage > 0 && c.playerEquipment[c.playerRing] == 19710) {
    			if (c.recoilHits > 0 || c.sufferHits > 0) {
    			int recDamage = damage / 10;
    			if (recDamage < 1) {
    				recDamage = 1;
    			}
    			if (NPCHandler.npcs[i].HP <= 0 || NPCHandler.npcs[i].isDead) {
    				return;
    			}
    			NPCHandler.npcs[i].HP -= recDamage;
    			NPCHandler.npcs[i].handleHitMask(recDamage);
    			removeRecoil(c, recDamage);
    			//c.recoilHits += damage;
    			}
    		}
    	}
    Open up your DialogueHandler.java, add this (use your own case #'s and action id's if you'd like)

    Code:
    case 6002:
    			sendItemChat3("Ring of suffering", "Would you like to remove all of the Ring's of recoil", "you currently have and apply the charges to", "your Ring of suffering?", 19550, 200);
    			c.nextChat = 6003;
    			break;
    		case 6003:
    			sendOption2("Yes, apply the charges.", "No, nevermind.");
    			c.dialogueAction = 6003;
    			break;
    		case 6004:
    			sendItemChat3("Ring of suffering(i)", "Would you like to remove all of the Ring's of recoil", "you currently have and apply the charges to", "your Ring of suffering(i)?", 19710, 200);
    			c.nextChat = 6005;
    			break;
    		case 6005:
    			sendOption2("Yes, apply the charges.", "No, nevermind.");
    			c.dialogueAction = 6005;
    			break;
    Code:
    public void sendItemChat3(String header, String one, String two,
    			String three, int item, int zoom) {
    		c.getPA().sendFrame246(4894, zoom, item);
    		c.getPA().sendFrame126(header, 4895);
    		c.getPA().sendFrame126(one, 4896);
    		c.getPA().sendFrame126(two, 4897);
    		c.getPA().sendFrame126(three, 4898);
    		c.getPA().sendFrame164(4893);
    	}
    Incase you dont have that, add that to the bottom of DialogueHandler. Save that.

    There's this one too just incase.

    Code:
    public void sendOption2(String s, String s1) {
    		c.getPA().sendString("Select an Option", 2460);
    		c.getPA().sendString(s, 2461);
    		c.getPA().sendString(s1, 2462);
    
    		c.getPA().sendFrame164(2459);
    	}
    Open up UseItem.java, add this under ItemonItem

    Code:
    if (itemUsed == 2550 && useWith == 19550 ||
    				useWith == 2550 && itemUsed == 19550 ||
    				itemUsed == 2551 && useWith == 19550 || //Charge Ring of Suffering
    				useWith == 2551 && itemUsed == 19550) {			
    			c.getDH().sendDialogues(6002, -1);
    		}
    		if (itemUsed == 2550 && useWith == 19710 ||
    				useWith == 2550 && itemUsed == 19710 ||
    				itemUsed == 2551 && useWith == 19710 || //Charge Ring of Suffering(i)
    				useWith == 2551 && itemUsed == 19710) {			
    			c.getDH().sendDialogues(6004, -1);
    		}
    Open up ClickingButtons.java and underneath case 9157: add,

    Code:
    if (player.dialogueAction == 6003) { //Charge Ring of Suffering
    				int rorN = 2551;
    				int ror = 2550;
    				int rorNAmt = player.getItems().getItemAmount(rorN);
    				int rorAmt = player.getItems().getItemAmount(ror);
    				int totalRor = player.getItems().getItemAmount(rorN) + player.getItems().getItemAmount(ror);
    				player.getItems().deleteItem2(rorN, rorNAmt);
    				player.getItems().deleteItem2(ror, rorAmt);
    				player.sufferHits += totalRor * 40;
    				player.sendMessage("You apply @blu@" + totalRor * 40 + " @bla@charges to the ring.");
    				player.sendMessage("Your Ring of suffering currently has @blu@" + player.sufferHits + " @bla@charges.");
    				player.getPA().removeAllWindows();
    				return;
    			}
    			if (player.dialogueAction == 6005) { //Charge Ring of Suffering(i)
    				int rorN = 2551;
    				int ror = 2550;
    				int rorNAmt = player.getItems().getItemAmount(rorN);
    				int rorAmt = player.getItems().getItemAmount(ror);
    				int totalRor = player.getItems().getItemAmount(rorN) + player.getItems().getItemAmount(ror);
    				player.getItems().deleteItem2(rorN, rorNAmt);
    				player.getItems().deleteItem2(ror, rorAmt);
    				player.sufferHits += totalRor * 40;
    				player.sendMessage("You apply @blu@" + totalRor * 40 + " @bla@charges to the ring.");
    				player.sendMessage("Your Ring of suffering(i) currently has @blu@" + player.sufferHits + " @bla@charges.");
    				player.getPA().removeAllWindows();
    				return;
    			}
    Open up PlayerAssistant.java and add this under applyDead (there should be some similar ones in there already)

    Code:
    if (player.getItems().playerHasItem(19550) || player.getItems().playerHasItem(19551)
    					|| player.getItems().isWearingItem(19550)) {
    				player.sufferHits = 0;
    				player.sendMessage("<col=255>You have lost your Ring of suffering charges!");
    			}
    			if (player.getItems().playerHasItem(19710) || player.getItems().playerHasItem(19711)
    					|| player.getItems().isWearingItem(19710)) {
    				player.sufferHits = 0;
    				player.sendMessage("<col=255>You have lost your Ring of suffering(i) charges!");
    			}
    Open up ItemClick2.java (in packets) and add that

    Code:
    case 19550:
    		case 19710: //Ring of Suffering/(i)
    			c.sendMessage("The ring currently has @blu@" + c.sufferHits + 
    					" @bla@charges left.");
    			break;

    Finally, these go into your PlayerSave.java

    Code:
    else if (token.equals("sufferHits")) {
    						p.sufferHits = Integer.parseInt(token3[0]);
    					}
    Code:
    characterfile.write("sufferHits = ", 0, 13);
    			characterfile.write(Integer.toString(p.sufferHits), 0, Integer.toString(p.sufferHits).length());
    			characterfile.newLine();



    NPC Aggressiveness based on player level * 2 (if cb lvl * 2 + 1 > NPC Combat lvl, NPC is no longer aggressive.)

    Spoiler for NPC Aggression:
    find in npc handler Attacking Player. Between

    Code:
    /**
    					 * Attacking player
    					 **/
    And

    Code:
    if (System.currentTimeMillis() - npcs[i].lastDamageTaken > 5000) {
    						npcs[i].underAttackBy = 0;
    						npcs[i].underAttack = false;
    					}

    Replace the current existing code with this.

    Code:
    if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && !switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    					else if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}		 
    						
    					else if (NpcDefinition.DEFINITIONS[i].isAggressive() && !npcs[i].underAttack && !npcs[i].isDead && !switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    					else if (NpcDefinition.DEFINITIONS[i].isAggressive() && !npcs[i].underAttack && !npcs[i].isDead && switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    It will look somewhat similar, you should be able to find this no problem.

    Just incase you don't have this already, add this to the NPCHandler as well.

    Code:
    public int getCloseRandomPlayer(int i) {
    		ArrayList<Integer> players = new ArrayList<>();
    		for (int j = 0; j < PlayerHandler.players.length; j++) {
    			if (PlayerHandler.players[j] != null) {
    				if (Boundary.isIn(npcs[i], Boundary.GODWARS_BOSSROOMS)) {
    					if (!Boundary.isIn(PlayerHandler.players[j], Boundary.GODWARS_BOSSROOMS)) {
    						npcs[i].killerId = 0;
    						continue;
    					}
    				}
    				if (goodDistance(PlayerHandler.players[j].absX, PlayerHandler.players[j].absY, npcs[i].absX,
    						npcs[i].absY, distanceRequired(i) + followDistance(i)) || isFightCaveNpc(i)) {
    					if ((PlayerHandler.players[j].underAttackBy <= 0 && PlayerHandler.players[j].underAttackBy2 <= 0)
    							|| PlayerHandler.players[j].inMulti())
    						if (PlayerHandler.players[j].heightLevel == npcs[i].heightLevel)
    							players.add(j);
    
    				}
    			}
    		}
    		if (players.size() > 0)
    			return players.get(Misc.random(players.size() - 1));
    		return 0;
    	}




    Not using c.absX >= # && c.absX <=# all the time...

    Spoiler for Simple:


    Open Player.java, add this anywhere.

    Example of use
    Code:
    if (c.withinArea(3200, 3202, 3200, 3202) {
    //c.getAgilityHandler().forceTeleport(c, 828, 3201, 3201, 1, 1, 2) <= using method i suggested earlier
    //c.getPA().movePlayer(3201, 3201, 1) <= move player
    }
    The other 3 should be fairly self explanatory just give them a read through.

    Code:
    public boolean withinArea(int x, int x1, int y, int y1) {
    		if (absX >= x && absX <= x1 && absY >= y && absY <= y1) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionXY(int x, int y) {
    		if (absX == x && absY == y) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionXX(int x, int x1) {
    		if (absX >= x && absX <= x1) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionYY(int y, int y1) {
    		if (absY >= y && absY <= y1) {
    			return true;
    		} else
    			return false;
    	}



    Use Item on NPC to return it as a note

    Spoiler for NOTE:


    This method also allows you to use data that is otherwise unused for the most part within the source. Again, why not use it!

    Create a new file called UseToNote.java in package content.
    Code:
    package org.brutality.model.content;
    
    import org.brutality.model.items.Item;
    import org.brutality.model.items.ItemDefinition;
    import org.brutality.model.players.Player;
    
    public class UseToNote {
    	
    	public static int[] cleanHerbs = { 249, 251, 253, 255, 257, 2998, 259, 261, 263, 3000, 265, 2481, 267, 269};
    	public static int[] grimyHerbs = { 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 2485, 3051 };
    	public static int[] otherFarmingItems = { };
    	
    	public static final int PILES = 13;
    	public static final int TOOL_LEPRECHAUN = 0;
    
    	public static boolean noteItemOnPiles(Player c, int npcId, int itemUsed) {
    		int amount = c.getItems().getItemAmount(itemUsed);
    		if (npcId == PILES) {
    			if (!ItemDefinition.forId(itemUsed).isNoted() && ItemDefinition.forId(itemUsed + 1).isNoted()
    					&& (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    					|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {			
    			if (c.getItems().playerHasItem(995, 50 * amount)) {
    				c.getItems().deleteItem2(995, 50 * amount);
    				c.getItems().deleteItem2(itemUsed, amount);
    				c.getItems().addItem(itemUsed + 1, amount);
    			}
    		}
    		}
    		return false;		
    	}
    	
    	public static boolean noteItemsOnLeprechaun(Player c, int npcId, int itemUsed) {
    		int amount = c.getItems().getItemAmount(itemUsed);
    		if (npcId == TOOL_LEPRECHAUN) {			
    			for (int h = 0; h < cleanHerbs.length; h++)					
    			if (itemUsed == cleanHerbs[h] && !ItemDefinition.forId(itemUsed).isNoted()
    					&& (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    							|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {
    				c.getItems().deleteItem2(cleanHerbs[h], amount);
    				c.getItems().addItem(cleanHerbs[h] + 1, amount);			
    		}	for (int g = 0; g < grimyHerbs.length; g++)		
    			 if (itemUsed == grimyHerbs[g] && !ItemDefinition.forId(itemUsed).isNoted()
    					 && (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    								|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {
    					c.getItems().deleteItem2(grimyHerbs[g], amount);
    					c.getItems().addItem(grimyHerbs[g] + 1, amount);			
    			}
    		}
    		return false;		
    	}
    }
    add that inside.

    You can cut this down to 1 method by making it grab the npcId you used the item on, but at least this way you can see what is going on in more than one way, and it also allows you to be specific if you only want a certain npc to note a certain item.

    Open up ItemDefinition.java.

    Code:
    public static String getItemListName(int item) {
    		if (item <= -1) {
    			return "None";
    		}
    		if (DEFINITIONS[item] == null) {
    			return "None";
    		}
    		return DEFINITIONS[item].getName();
    	}
    Add that underneath getIdForName.

    Finally open up UseItem.java

    Code:
    UseToNote.noteItemOnPiles(c, npcId, itemId);
    		UseToNote.noteItemsOnLeprechaun(c, npcId, itemId);
    Add that underneath ItemonNPC
    You can easily convert this to an object or anything you want really.



    Object Picking (Flax, w/e you wanna do with it)
    Do not use this for door handling. But this can be used for things like making
    a chest open and shut when a player uses a key on it etc.. or opening a cupboard.


    Spoiler for Why would we want to pick flax on rsps?:

    create a new file called Flax.java in package world.objects
    Code:
    package org.brutality.world.objects;
    
    import java.util.ArrayList;
    
    import org.brutality.model.players.Player;
    import org.brutality.util.Misc;
    import org.brutality.world.objects.GlobalObject;
    import org.brutality.Config;
    import org.brutality.Server;
    
     
    public class Flax {
    	
    	
    	public static void pickFlax(final Player c, final int objectId, final int x, final int y) {
    		if (c.getItems().freeSlots() != 0) {	
    			c.getItems().addItem(1779, 1);
                c.animation(827);
                if (Misc.random(5) == 0) {
                Server.getGlobalObjects()
    			.add(new GlobalObject(-1, x, y, c.heightLevel, 0, 10, 15, objectId));
                }
    			
    		} else {
    			c.sendMessage("Not enough space in your inventory.");
    			return;
    		}
    	
    	}
    }
    add that inside and save.

    Open ActionHandler.java

    under secondClickObject add

    Code:
    case 7134:
    			Flax.pickFlax(c, objectType, obX, obY);
    		break;


    Cheap Fix to update Objects for all players (ie chopping tree doesnt show a stump for all players)

    Spoiler for wat:
    Code:
    in PlayerAssistant.java, find checkObjectSpawn
    replace with the code below.
    
    public void checkObjectSpawn(int objectId, int objectX, int objectY, int face, int objectType) {
    		for (int j = 0; j < PlayerHandler.players.length; j++) { //<-- instead of it being for a single player it's updated for everyone
    			if (PlayerHandler.players[j] != null) {
    				Player p = PlayerHandler.players[j];
    		Region.addWorldObject(objectId, objectX, objectY, player.heightLevel, face); // height
    		// level
    		// should
    		// be
    		// a
    		// param
    		// :s
    		if (player.distanceToPoint(objectX, objectY) > 60)
    			return;
    		// synchronized(c) {
    		if (player.getOutStream() != null && player != null) {
    			p.getOutStream().createFrame(85);
    			p.getOutStream().writeByteC(objectY - (player.getMapRegionY() * 8));
    			p.getOutStream().writeByteC(objectX - (player.getMapRegionX() * 8));
    			p.getOutStream().createFrame(101);
    			p.getOutStream().writeByteC((objectType << 2) + (face & 3));
    			p.getOutStream().writeByte(0);
    
    			if (objectId != -1) { // removing
    				p.getOutStream().createFrame(151);
    				p.getOutStream().writeByteS(0);
    				p.getOutStream().writeWordBigEndian(objectId);
    				p.getOutStream().writeByteS((objectType << 2) + (face & 3));
    			}
    			p.flushOutStream();
    		}
    			}
    		}
    	}
    You can apply the same principle elsewhere if required.




    Hopefully this will help some of you just starting out.
    Message me, post or whatever if i missed anything. This is my first post like this.
    Enjoy! or durnt

    -Crusty Rob
    -"Where's the beef?"
    -"Fix the problem, don't become it."
    -"You're what's wrong with rsps.. - Justin"
    Reply With Quote  
     


  2. #2  
    Banned
    Join Date
    Jan 2017
    Posts
    26
    Thanks given
    19
    Thanks received
    19
    Rep Power
    0
    thanks for this,got more any bugs?
    Reply With Quote  
     

  3. #3  
    Registered Member
    Join Date
    Jan 2014
    Posts
    65
    Thanks given
    32
    Thanks received
    10
    Rep Power
    0
    Quote Originally Posted by Veng Pkz View Post
    thanks for this,got more any bugs?
    Yes, a lot of objects don't work such as Torag and Verac stairs and furnaces. Not sure how to fix.
    Reply With Quote  
     

  4. #4  
    Registered Member
    Join Date
    Nov 2015
    Posts
    77
    Thanks given
    16
    Thanks received
    22
    Rep Power
    51
    Quote Originally Posted by Ultimascape View Post
    Yes, a lot of objects don't work such as Torag and Verac stairs and furnaces. Not sure how to fix.
    This was a very simple fix, honestly i completely forget how i fixed this problem. Its checking to see if you are right infront of the tile that the object is placed, and if not, it stops. I think it's in walking or ClickObject but im not 100% sure. If i remember or stumble upon this fix i'll add it here. It is one line of code that is stopping you from doing this.
    Reply With Quote  
     

  5. #5  
    Registered Member
    Join Date
    Jan 2011
    Posts
    195
    Thanks given
    12
    Thanks received
    14
    Rep Power
    22
    Spoiler for Fixes:
    Quote Originally Posted by Crusty Rob View Post
    Im not sure if anyone was having any problems but here are just some basic things. Ill post more if people request for more or if i happen to find any i think would be important.

    (This post has been edited 12 fixes/additions and counting)


    Talk to an npc (Banker) from across the bank booth


    Spoiler for distance to npc:
    Code:
    if (c.goodDistance(NPCHandler.npcs[c.npcClickIndex].getX(), NPCHandler.npcs[c.npcClickIndex].getY(),
    						c.getX(), c.getY(), NPCHandler.npcs[c.npcClickIndex].getSize()))
    Find this in ClickNPC.java under FIRST_CLICK (or anywhere you want to apply this).

    Code:
    if (c.goodDistance(NPCHandler.npcs[c.npcClickIndex].getX(), NPCHandler.npcs[c.npcClickIndex].getY(),
    						c.getX(), c.getY(), NPCHandler.npcs[c.npcClickIndex].getSize() + 1))
    Replace it with that (add +1 to the size.) This allows you to click to talk to bankers or other npcs from 1 spaces away, such as across a bank booth etc.



    Use Operate (for items like Amulet of Glory)

    Spoiler for How does one not realise this in the first place?:
    Code:
    case 1688:
    			c.getPA().useOperate(removeId);
    			break;
    Find that in Bank10.java, remove it and place it in Bank5.java. That will allow you to use operate on any desired item properly.




    Fixing wrong object Id's in your packet


    Spoiler for object Packets:
    Open up ClickObject.java in packets.

    Find and SecondClick and ThirdClick with:

    Code:
    case SECOND_CLICK:
    c.objectId = packet.getLEShortA(); // getUnsignedShortA
    			c.objectY = packet.getLEShort();
    			c.objectX = packet.getUnsignedShortA();
    			c.objectDistance = 1;
    Code:
    case THIRD_CLICK:
    c.objectX = packet.getLEShort();
    			c.objectY = packet.getUnsignedShort();
    			c.objectId = packet.getLEShortA();
    			c.objectDistance = 1;
    That will make all the clicks of object 1, 2 and 3 have the same id, x and y coords. If anyone was wondering why objects had different id's!



    More Variables for NPC's!

    Spoiler for Max Mage Def = 255, dont forget!:
    This source also has Melee, Range and Magic defense loaded into the definition file. Why not use this? If you want to do this, theres only a few things you need to change. Ill give you the code to load it but implementing it within the combat system itself instead of just using normal defence is up to you

    Code:
    public static NPC newNPC(int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit,
    			int attack, int defence) {
    		// first, search for a free slot
    		int slot = -1;
    		for (int i = 1; i < maxNPCs; i++) {
    			if (npcs[i] == null) {
    				slot = i;
    				break;
    			}
    		}
    		if (slot == -1)
    			return null; // no free slot found
    		NPC newNPC = new NPC(slot, npcType);
    		newNPC.absX = x;
    		newNPC.absY = y;
    		newNPC.makeX = x;
    		newNPC.makeY = y;
    		newNPC.heightLevel = heightLevel;
    		newNPC.walkingType = WalkingType; // try
    		npcs[slot] = newNPC;
    		return newNPC;
    	}
    Replace your NPC newNPC method with this within NPCHandler.java.

    Code:
    newNPC(Integer.parseInt(token3[0]), Integer.parseInt(token3[1]), Integer.parseInt(token3[2]),
    							Integer.parseInt(token3[3]), Integer.parseInt(token3[4]),
    							getNpcListHP(Integer.parseInt(token3[0])), getNpcMaxHit(Integer.parseInt(token3[0])),
    							getNpcAttack(Integer.parseInt(token3[0])), getNpcCombatDefence(Integer.parseInt(token3[0])),
    							getNpcRangeDefence(Integer.parseInt(token3[0])),
    							getNpcMagicDefence(Integer.parseInt(token3[0])));
    Replace newNPC in loadAutoSpawn with that.

    Code:
    public static int getNpcMaxHit(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMaxHit();
    
    	}
    
    	public static int getNpcAttack(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getAttackBonus();
    
    	}
    
    	public static int getNpcCombatDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMeleeDefence();
    
    	}
    
    	public static int getNpcRangeDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getRangedDefence();
    
    	}
    
    	public static int getNpcMagicDefence(int npcId) {
    		if (npcId <= -1) {
    			return 0;
    		}
    		if (NpcDefinition.DEFINITIONS[npcId] == null) {
    			return 0;
    		}
    		return NpcDefinition.DEFINITIONS[npcId].getMagicDefence();
    
    	}
    (Still in NPCHandler.java) Add those underneath getNpcListHP.
    Now your done in the NPCHandler. Save that and open up NPC.java.

    Code:
    public NPC(int _npcId, int _npcType) {
    		NpcDefinition definition = NpcDefinition.DEFINITIONS[_npcType];
    		index = _npcId;
    		npcType = _npcType;
    		direction = -1;
    		isDead = false;
    		applyDead = false;
    		actionTimer = 0;
    		randomWalk = true;
    		if (definition != null) {
    			size = definition.getSize();
    			if (size < 1) {
    				size = 1;
    			}
    			HP = definition.getHitpoints();
    			maximumHealth = definition.getHitpoints();
    			attack = definition.getAttackBonus();
    			defence = definition.getMeleeDefence();
    			rangeDefence = definition.getRangedDefence();
    			magicDefence = definition.getMagicDefence();
    			maxHit = definition.getMaxHit();
    		}
    	}
    Your going to replace your current public NPC with that.

    Make sure you replace these.

    Code:
    public int makeX, makeY, maxHit, defence, rangeDefence, magicDefence, attack, moveX, moveY, direction, walkingType;
    Im pretty sure thats everything. You should have .getMagicDefence() etc within your NpcDefinition.java file already.

    Example of what you put in your .json file.

    Code:
    {
        "id": 2215,
        "name": "General Graardor",
        "examine": "A huge war chief.",
        "combat": 624,
        "size": 4,
        "attackable": true,
        "aggressive": false,
        "retreats": false,
        "poisonous": false,
        "respawn": 30,
        "maxHit": 60,
        "hitpoints": 255,
        "attackSpeed": 4,
        "attackAnim": 7018,
        "defenceAnim": -1,
        "deathAnim": 7062,
        "attackBonus": 280,
        "defenceMelee": 250,
        "defenceRange": 350,
        "defenceMage": 80
      },
    Use the getAttackEmote in NPCHandler to switch attackAnimations based on attackType etc. Dont bother with the aggression boolean, use the isAggressive method for that. Although I haven't tried the poisonous one yet which could provide useful as well.

    Code:
    c.sendMessage("NPCATT: " + NPCHandler.npcs[i].attack + "   NPCMELEEDEF: " + NPCHandler.npcs[i].defence
    				+ "   NPCRANGEDEF: " + NPCHandler.npcs[i].rangeDefence + "   NPCMDEF: + NPCHandler.npcs[i].magicDefence);"
    (stick that basically anywhere in attackNPC and you can see your changes in the NPCDefinition.json file. Can be quite helpful when doing some of the math for combat.


    Now how about those silly free shop items?

    Spoiler for how does this even work..?:
    To make the shops buy and sell using coins and not free, replace your ShopAssistant.java with this.

    Code:
    package org.brutality.model.shops;
    
    import org.brutality.Config;
    import org.brutality.Server;
    import org.brutality.model.items.ItemDefinition;
    import org.brutality.model.players.Player;
    import org.brutality.model.players.PlayerHandler;
    import org.brutality.model.players.PlayerSave;
    import org.brutality.util.Misc;
    import org.brutality.world.ShopHandler;
    
    public class ShopAssistant {
    
    	private Player c;
    
    	public ShopAssistant(Player client) {
    		this.c = client;
    	}
    
    	public boolean shopSellsItem(int itemID) {
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if (itemID == (ShopHandler.ShopItems[c.myShopId][i] - 1)) {
    				return true;
    			}
    		}
    		return false;
    	}
    
    	public static final int[][] PKP_DATA = { { 1050, 100000000 } };
    
    	/**
    	 * Shops
    	 **/
    
    	public void openShop(int ShopID) {
    		if (Server.getMultiplayerSessionListener().inAnySession(c)) {
    			return;
    		}
    		c.getItems().resetItems(3823);
    		resetShop(ShopID);
    		c.isShopping = true;
    		c.myShopId = ShopID;
    		c.getPA().sendFrame248(3824, 3822);
    		if (ShopID == 68)
    			c.getPA().sendFrame126("Fishing Tourney Shop - Points: " + c.fishingTourneyPoints, 3901);
    		else if (ShopID == 72)
    			c.getPA().sendFrame126("Blast Mine Shop - Points: " + c.blastPoints, 3901);
    		else if (ShopID == 74)
    			c.getPA().sendFrame126("Sacrifice Shop - Points: " + c.hungerPoints, 3901);
    		else
    			c.getPA().sendFrame126(ShopHandler.ShopName[ShopID], 3901);
    	}
    
    	public void updatePlayerShop() {
    		for (int i = 1; i < Config.MAX_PLAYERS; i++) {
    			if (PlayerHandler.players[i] != null) {
    				if (PlayerHandler.players[i].isShopping == true && PlayerHandler.players[i].myShopId == c.myShopId
    						&& i != c.index) {
    					PlayerHandler.players[i].updateShop = true;
    				}
    			}
    		}
    	}
    
    	public void updateshop(int i) {
    		resetShop(i);
    	}
    
    	public void resetShop(int ShopID) {
    		// synchronized (c) {
    		int TotalItems = 0;
    		for (int i = 0; i < ShopHandler.MaxShopItems; i++) {
    			if (ShopHandler.ShopItems[ShopID][i] > 0) {
    				TotalItems++;
    			}
    		}
    		if (TotalItems > ShopHandler.MaxShopItems) {
    			TotalItems = ShopHandler.MaxShopItems;
    		}
    		if (ShopID == 80) {
    			c.getPA().sendFrame171(0, 28050);
    			c.getPA().sendFrame126("Bounties: " + Misc.insertCommas(Integer.toString(c.getBH().getBounties())), 28052);
    		} else {
    			c.getPA().sendFrame171(1, 28050);
    		}
    		c.getOutStream().createFrameVarSizeWord(53);
    		c.getOutStream().writeWord(3900);
    		c.getOutStream().writeWord(TotalItems);
    		int TotalCount = 0;
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if (ShopHandler.ShopItems[ShopID][i] > 0 || i <= ShopHandler.ShopItemsStandard[ShopID]) {
    				if (ShopHandler.ShopItemsN[ShopID][i] > 254) {
    					c.getOutStream().writeByte(255);
    					c.getOutStream().writeDWord_v2(ShopHandler.ShopItemsN[ShopID][i]);
    				} else {
    					c.getOutStream().writeByte(ShopHandler.ShopItemsN[ShopID][i]);
    				}
    				if (ShopHandler.ShopItems[ShopID][i] > Config.ITEM_LIMIT || ShopHandler.ShopItems[ShopID][i] < 0) {
    					ShopHandler.ShopItems[ShopID][i] = Config.ITEM_LIMIT;
    				}
    				c.getOutStream().writeWordBigEndianA(ShopHandler.ShopItems[ShopID][i]);
    				TotalCount++;
    			}
    			if (TotalCount > TotalItems) {
    				break;
    			}
    		}
    		c.getOutStream().endFrameVarSizeWord();
    		c.flushOutStream();
    		// }
    	}
    
    	public double getItemShopValue(int ItemID, int Type, int fromSlot) {
    		double ShopValue = 1;
    		double TotPrice = 0;
    		// int price = getSpecialItemValue(ItemID);
    		int price = ItemDefinition.forId(ItemID).getGeneralPrice();
    		int tokkul = ((ItemDefinition.forId(ItemID).getHighAlchValue() * 2)
    				+ (ItemDefinition.forId(ItemID).getHighAlchValue() / 2));
    		if (c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) {
    			ShopValue = price;
    		} else if ((c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) && price < 1) {
    			ShopValue = price + 1;
    		} else if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			ShopValue = tokkul;
    		} 
    		TotPrice = ShopValue;
    
    		return TotPrice;
    	}
    
    	/**
    	 * buy item from shop (Shop Price)
    	 **/
    
    	public void buyFromShopPrice(int removeId, int removeSlot) {
    		int ShopValue = (int) Math.floor(getItemShopValue(removeId, 0, removeSlot));
    		ShopValue *= 1.00;
    		String ShopAdd = "";
    		if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			c.sendMessage(c.getItems().getItemName(removeId) + ": currently costs "
    					+ ((ItemDefinition.forId(removeId).getHighAlchValue() * 2)
    							+ (ItemDefinition.forId(removeId).getHighAlchValue() / 2))
    					+ " tokkul.");
    			return;
    		} 
    		if (ShopValue >= 1000 && ShopValue < 1000000) {
    			ShopAdd = " (" + (ShopValue / 1000) + "K)";
    		} else if (ShopValue >= 1000000) {
    			ShopAdd = " (" + (ShopValue / 1000000) + " million)";
    		}
    		c.sendMessage(c.getItems().getItemName(removeId) + ": currently costs " + ShopValue + " Coins." + ShopAdd);
    	}
    
    	public int getBountyHunterItemCost(int itemId) {
    		switch (itemId) {
    		case 12783:
    			return 500_000;
    		case 12804:
    			return 25_000_000;
    		case 12851:
    			return 10_000_000;
    		case 12855:
    		case 12856:
    			return 2_500_000;
    		case 12833:
    			return 50_000_000;
    		case 12831:
    			return 35_000_000;
    		case 12829:
    			return 25_000_000;
    		case 14484:
    			return 125_000_000;
    
    		case 12800:
    		case 12802:
    			return 350_000;
    		case 12786:
    			return 100_000;
    		case 10926:
    			return 2_500;
    		case 12846:
    			return 8_000_000;
    		case 12420:
    		case 12421:
    		case 12419:
    		case 12457:
    		case 12458:
    		case 12459:
    			return 10_000_000;
    		case 12757:
    		case 12759:
    		case 12761:
    		case 12763:
    		case 12788:
    			return 500_000;
    		case 12526:
    			return 1_500_000;
    		case 12773:
    			return 15_000_000;
    		case 12849:
    		case 12798:
    			return 250_000;
    		case 12608:
    		case 12610:
    		case 12612:
    			return 350_000;
    		case 12775:
    		case 12776:
    		case 12777:
    		case 12778:
    		case 12779:
    		case 12780:
    		case 12781:
    		case 12782:
    			return 5_000;
    
    		default:
    			return Integer.MAX_VALUE;
    		}
    	}
    
    	public int getItemValueHungerGames(int id) {
    		switch (id) {
    		case 6762:
    			return 500;
    		case 20035:
    		case 20038:
    		case 20041:
    		case 20044:
    		case 20047:
    			return 2500;
    		case 13072:
    		case 13073:
    			return 7000;
    		case 11663:
    		case 11664:
    		case 11665:
    		case 8842:
    			return 5000;
    		}
    		return 0;
    	}
    
    	/**
    	 * Sell item to shop (Shop Price)
    	 **/
    	public void sellToShopPrice(int removeId, int removeSlot) {
    		
    		// if (c.myShopId == 22 || c.myShopId == 49 || c.myShopId == 116 ||
    		// c.myShopId == 9 || c.myShopId == 50 || c.myShopId == 12 || c.myShopId
    		// == 20 || c.myShopId == 2 || c.myShopId == 88 || c.myShopId == 111 ||
    		// c.myShopId == 113 || c.myShopId == 3
    		// || c.myShopId == 4 || c.myShopId == 5 || c.myShopId == 16) {
    		// //c.sendMessage("@red@You can't sell items to this shop!");
    		// return;
    		// }
    		for (int i : Config.ITEMS_KEPT_ON_DEATH) {
    			if (i == removeId) {
    				c.sendMessage("You can't sell " + c.getItems().getItemName(removeId).toLowerCase() + ".");
    				return;
    			}
    		}
    
    		boolean IsIn = false;
    		if (ShopHandler.ShopSModifier[c.myShopId] > 1) {
    			for (int j = 0; j <= ShopHandler.ShopItemsStandard[c.myShopId]; j++) {
    				if (removeId == (ShopHandler.ShopItems[c.myShopId][j] - 1)) {
    					IsIn = true;
    					break;
    				}
    			}
    		} else {
    			IsIn = true;
    		}
    		if (IsIn == false) {
    			c.sendMessage("You can't sell " + c.getItems().getItemName(removeId).toLowerCase() + " to this store.");
    		} else {
    			int ShopValue = (int) Math.floor(getItemShopValue(removeId, 1, removeSlot));
    			String ShopAdd = "";
    			if (ShopValue >= 1000 && ShopValue < 1000000) {
    				ShopAdd = " (" + (ShopValue / 1000) + "K)";
    			} else if (ShopValue >= 1000000) {
    				ShopAdd = " (" + (ShopValue / 1000000) + " million)";
    			}
    
    			if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    				c.sendMessage(c.getItems().getItemName(removeId) + ": shop will buy for "
    						+ ItemDefinition.forId(removeId).getLowAlchValue() + " tokkul" + ShopAdd);
    			} else {
    				c.sendMessage(c.getItems().getItemName(removeId) + ": shop will buy for "
    						+ (ItemDefinition.forId(removeId).getLowAlchValue() + 1) + " Coins.");
    			}
    		}
    	}
    
    	int items[] = { 661, 662 };
    
    	@SuppressWarnings("unused")
    	public boolean sellItem(int itemID, int fromSlot, int amount) {
    		if (Server.getMultiplayerSessionListener().inAnySession(c)) {
    			return false;
    		}
    		// if (c.myShopId == 22 || c.myShopId == 49 || c.myShopId == 116 ||
    		// c.myShopId == 9 || c.myShopId == 50 || c.myShopId == 12 || c.myShopId
    		// == 20 || c.myShopId == 2 || c.myShopId == 88 || c.myShopId == 111 ||
    		// c.myShopId == 113 || c.myShopId == 3
    		// || c.myShopId == 4 || c.myShopId == 5 || c.myShopId == 16) {
    		// c.sendMessage("@red@You can't sell items to this shop!");
    		// return false;
    		// }
    		for (int i : Config.ITEMS_KEPT_ON_DEATH) {
    			if (i == itemID) {
    				c.sendMessage("You can't sell " + c.getItems().getItemName(itemID).toLowerCase() + ".");
    				return false;
    			}
    		}
    		// if (c.myShopId == 115 || c.myShopId == 77 || c.myShopId == 14||
    		// c.myShopId == 116 || c.myShopId == 117 || c.myShopId == 71 ||
    		// c.myShopId == 78
    		// || c.myShopId == 80 || c.myShopId == 44 || c.myShopId == 22 ||
    		// c.myShopId == 66 || c.myShopId == 67
    		// || c.myShopId == 56 || c.myShopId == 20 || c.myShopId == 210 ||
    		// c.myShopId == 200 || c.myShopId == 68 || c.myShopId == 74 ||
    		// c.myShopId == 72
    		// || c.myShopId == 70 || c.myShopId == 69 || c.myShopId == 88) {
    		// c.sendMessage("@red@You can't sell items to this shop!");
    		// return false;
    		// }
    		if (c.getRights().isAdministrator() && !Config.ADMIN_CAN_SELL_ITEMS) {
    			c.sendMessage("Selling items as an admin has been disabled.");
    			return false;
    		}
    		if (amount > 0 && itemID == (c.playerItems[fromSlot] - 1)) {
    			if (ShopHandler.ShopSModifier[c.myShopId] > 1) {
    				boolean IsIn = false;
    				for (int i = 0; i <= ShopHandler.ShopItemsStandard[c.myShopId]; i++) {
    					if (itemID == (ShopHandler.ShopItems[c.myShopId][i] - 1)) {
    						IsIn = true;
    						break;
    					}
    				}
    				if (IsIn == false) {
    					c.sendMessage(
    							"You can't sell " + c.getItems().getItemName(itemID).toLowerCase() + " to this store.");
    					return false;
    				}
    			}
    
    			if (amount > c.playerItemsN[fromSlot] && (ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isNoted()
    					|| ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isStackable())) {
    				amount = c.playerItemsN[fromSlot];
    			} else if (amount > c.getItems().getItemAmount(itemID)
    					&& !ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isNoted()
    					&& !ItemDefinition.forId((c.playerItems[fromSlot] - 1)).isStackable()) {
    				amount = c.getItems().getItemAmount(itemID);
    			}
    
    			int TotPrice2 = 0;
    			int TotPrice3 = 0;
    			for (int i = amount; i > 0; i--) {
    				TotPrice2 = ItemDefinition.forId(itemID).getLowAlchValue() + 1;
    				if (c.getItems().freeSlots() > 0 || c.getItems().playerHasItem(995)) {
    					if (!ItemDefinition.forId(itemID).isNoted()) {
    						c.getItems().deleteItem(itemID, c.getItems().getItemSlot(itemID), 1);
    					} else {
    						c.getItems().deleteItem(itemID, fromSlot, 1);
    					}
    					if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    						c.getItems().addItem(6529, TotPrice2 - 1);
    					} else {
    						c.getItems().addItem(995, (TotPrice2));
    					}
    				}
    			}
    
    			c.getItems().resetItems(3823);
    			resetShop(c.myShopId);
    			updatePlayerShop();
    			return true;
    		}
    		return true;
    	}
    
    	public boolean addShopItem(int itemID, int amount) {
    		boolean Added = false;
    		if (amount <= 0) {
    			return false;
    		}
    		if (ItemDefinition.forId(itemID).isNoted()) {
    			itemID = c.getItems().getUnnotedItem(itemID);
    		}
    		for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    			if ((ShopHandler.ShopItems[c.myShopId][i] - 1) == itemID) {
    				ShopHandler.ShopItemsN[c.myShopId][i] += amount;
    				Added = true;
    			}
    		}
    		if (Added == false) {
    			for (int i = 0; i < ShopHandler.ShopItems.length; i++) {
    				if (ShopHandler.ShopItems[c.myShopId][i] == 0) {
    					ShopHandler.ShopItems[c.myShopId][i] = (itemID + 1);
    					ShopHandler.ShopItemsN[c.myShopId][i] = amount;
    					ShopHandler.ShopItemsDelay[c.myShopId][i] = 0;
    					break;
    				}
    			}
    		}
    		return true;
    	}
    
    	public void handleOtherShop(int itemID, int fromSlot, int amount) {
    
    		if (!shopSellsItem(itemID))
    			return;
    		if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    			int itemId = c.getItems().getItemSlot(6529);
    			if (itemId != itemID) {
    				return;
    			}
    			if (c.getItems().playerHasItem(6529)
    					&& c.getItems().getItemAmount(6529) >= ItemDefinition.forId(itemID).getHighAlchValue() * 2.5) {
    				if (c.getItems().freeSlots() > 0) {
    					c.getItems().deleteItem(6529, (ItemDefinition.forId(itemID).getHighAlchValue() * 2)
    							+ (ItemDefinition.forId(itemID).getHighAlchValue() / 2));
    					c.getItems().addItem(itemID, 1);
    					ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    					ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    					if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    						ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    					}
    				}
    			} else {
    				c.sendMessage("You do not have enough tokkul to buy this item.");
    			}
    		}
    		c.getItems().resetItems(3823);
    		resetShop(c.myShopId);
    		updatePlayerShop();
    		PlayerSave.saveGame(c);
    	}
    
    	public boolean buyItem(int itemID, int fromSlot, int amount) {
    		if (c.inTrade) {
    			return false;
    		}
    		// Fixes dupe within shop via cheat engine.
    		if (!shopSellsItem(itemID) && c.myShopId != 14)
    			return false;
    
    		if (!shopSellsItem(itemID)) {
    			return false;
    		}
    		if (amount > 0) {
    			if (!shopSellsItem(itemID))
    				return false;
    			if (amount > ShopHandler.ShopItemsN[c.myShopId][fromSlot]) {
    				amount = ShopHandler.ShopItemsN[c.myShopId][fromSlot];
    			}
    			if (amount > c.getItems().freeSlots()) {
    				if (c.getItems().isStackable(itemID) && c.getItems().freeSlots() < 1)
    					return false;
    				if (!c.getItems().isStackable(itemID)) {
    					amount = c.getItems().freeSlots();
    					c.sendMessage("You do not have enough inventory space to buy that many.");
    				}
    			}
    			int TotPrice2 = 0;
    			int Slot, Slot1, Slot2 = 0;// Tokkul
    			if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    				handleOtherShop(itemID, fromSlot, amount);
    				return false;
    			}
    
    			for (int i = amount; i > 0; i--) {
    				TotPrice2 = (int) Math.floor(getItemShopValue(itemID, 0, fromSlot));
    				Slot = c.getItems().getItemSlot(995);
    				Slot1 = c.getItems().getItemSlot(6529);
    				if (Slot == -1 && c.myShopId != 65 && c.myShopId != 66 && c.myShopId != 67) {
    					c.sendMessage("You don't have enough coins.");
    					break;
    				}
    				if (Slot1 == -1 && c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    					c.sendMessage("You don't have enough tokkul.");
    					break;
    				}
    				if (TotPrice2 <= 0) {
    					TotPrice2 = (int) Math.floor(getItemShopValue(itemID, 0, fromSlot));
    					TotPrice2 *= 1.66;
    				} else {
    					if (c.myShopId == 65 || c.myShopId == 66 || c.myShopId == 67) {
    						if (c.playerItemsN[Slot1] >= TotPrice2) {
    							if (c.getItems().freeSlots() > 0) {
    								c.getItems().deleteItem(6529, c.getItems().getItemSlot(6529), TotPrice2);
    								c.getItems().addItem(itemID, 1);
    								ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    								ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    								if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    									ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    								}
    							} else {
    								c.sendMessage("You don't have enough space in your inventory.");
    								break;
    							}
    						} else {
    							c.sendMessage("You don't have enough tokkul.");
    							break;
    						}
    					}
    					if (c.myShopId != 65 || c.myShopId != 66 || c.myShopId != 67) {
    						if (c.playerItemsN[Slot] >= TotPrice2) {
    							if (c.getItems().freeSlots() > 0) {
    								c.getItems().deleteItem(995, c.getItems().getItemSlot(995), TotPrice2);
    								c.getItems().addItem(itemID, 1);
    								ShopHandler.ShopItemsN[c.myShopId][fromSlot] -= 1;
    								ShopHandler.ShopItemsDelay[c.myShopId][fromSlot] = 0;
    								if ((fromSlot + 1) > ShopHandler.ShopItemsStandard[c.myShopId]) {
    									ShopHandler.ShopItems[c.myShopId][fromSlot] = 0;
    								}
    							} else {
    								c.sendMessage("You don't have enough space in your inventory.");
    								break;
    							}
    						} else {
    							c.sendMessage("You don't have enough coins.");
    							break;
    						}
    					}
    				}
    			}
    			c.getItems().resetItems(3823);
    			resetShop(c.myShopId);
    			updatePlayerShop();
    			PlayerSave.saveGame(c);
    			return true;
    		}
    		return false;
    	}
    
    	public void handleOtherShop(int itemID, int amount) {
    		if (!shopSellsItem(itemID)) {
    			c.sendMessage("Stop trying to cheat!");
    			return;
    		}
    		if (amount <= 0) {
    			c.sendMessage("You need to buy atleast one or more of this item.");
    			return;
    		}
    		if (!c.getItems().isStackable(itemID)) {
    			if (amount > c.getItems().freeSlots()) {
    				amount = c.getItems().freeSlots();
    			}
    		}
    		/*
    		 * if (c.myShopId == 115) { if (c.votePoints >=
    		 * getSpecialItemValue(itemID) * amount) { if (c.getItems().freeSlots()
    		 * > 0) { c.votePoints -= getSpecialItemValue(itemID) * amount;
    		 * c.getPA().loadQuests(); c.getItems().addItem(itemID, amount);
    		 * c.getItems().resetItems(3823); } } else { c.sendMessage(
    		 * "You do not have enough vote points to buy this item."); } }
    		 */
    	}
    
    	public void openSkillCape() {
    		int capes = get99Count();
    		if (capes > 1)
    			capes = 1;
    		else
    			capes = 0;
    		c.myShopId = 14;
    		setupSkillCapes(capes, get99Count());
    	}
    
    	/*
    	 * public int[][] skillCapes =
    	 * {{0,9747,4319,2679},{1,2683,4329,2685},{2,2680
    	 * ,4359,2682},{3,2701,4341,2703
    	 * },{4,2686,4351,2688},{5,2689,4347,2691},{6,2692,4343,2691},
    	 * {7,2737,4325,2733
    	 * },{8,2734,4353,2736},{9,2716,4337,2718},{10,2728,4335,2730
    	 * },{11,2695,4321,2697},{12,2713,4327,2715},{13,2725,4357,2727},
    	 * {14,2722,4345
    	 * ,2724},{15,2707,4339,2709},{16,2704,4317,2706},{17,2710,4361,
    	 * 2712},{18,2719,4355,2721},****,2737,4331,2739},{20,2698,4333,2700}};
    	 */
    	public int[] skillCapes = { 9747, 9753, 9750, 9768, 9756, 9759, 9762, 9801, 9807, 9783, 9798, 9804, 9780, 9795,
    			9792, 9774, 9771, 9777, 9786, 9810, 9765, 9789, 9948 };
    
    	public int get99Count() {
    		int count = 0;
    		for (int j = 0; j < c.playerLevel.length; j++) {
    			if (Player.getLevelForXP(c.playerXP[j]) >= 99) {
    				count++;
    			}
    		}
    		return count;
    	}
    
    	public void setupSkillCapes(int capes, int capes2) {
    		c.getPA().sendFrame171(1, 28050);
    		c.getItems().resetItems(3823);
    		c.isShopping = true;
    		c.myShopId = 14;
    		c.getPA().sendFrame248(3824, 3822);
    		c.getPA().sendFrame126("Skillcape Shop", 3901);
    
    		int TotalItems = 0;
    		TotalItems = capes2;
    		if (TotalItems > ShopHandler.MaxShopItems) {
    			TotalItems = ShopHandler.MaxShopItems;
    		}
    		c.getOutStream().createFrameVarSizeWord(53);
    		c.getOutStream().writeWord(3900);
    		c.getOutStream().writeWord(TotalItems);
    		for (int i = 0; i <= 22; i++) {
    			if (Player.getLevelForXP(c.playerXP[i]) < 99)
    				continue;
    			if (skillCapes[i] == -1)
    				continue;
    			c.getOutStream().writeByte(1);
    			c.getOutStream().writeWordBigEndianA(skillCapes[i] + 2);
    		}
    		c.getOutStream().endFrameVarSizeWord();
    		c.flushOutStream();
    		// }
    	}
    
    	public void skillBuy(int item) {
    		int nn = get99Count();
    		if (nn > 1)
    			nn = 1;
    		else
    			nn = 0;
    		for (int j = 0; j < skillCapes.length; j++) {
    			if (skillCapes[j] == item || skillCapes[j] + 1 == item) {
    				if (c.getItems().freeSlots() > 1) {
    					if (c.getItems().playerHasItem(995, 99000)) {
    						if (Player.getLevelForXP(c.playerXP[j]) >= 99) {
    							c.getItems().deleteItem(995, c.getItems().getItemSlot(995), 99000);
    							c.getItems().addItem(skillCapes[j] + nn, 1);
    							c.getItems().addItem(skillCapes[j] + 2, 1);
    						} else {
    							c.sendMessage("You must have 99 in the skill of the cape you're trying to buy.");
    						}
    					} else {
    						c.sendMessage("You need 99,000 coins to buy this item.");
    					}
    				} else {
    					c.sendMessage("You must have at least 1 inventory spaces to buy this item.");
    				}
    			}
    		}
    		c.getItems().resetItems(3823);
    	}
    
    	public void openVoid() {
    	}
    
    	public void buyVoid(int item) {
    	}
    
    }
    This wont be perfect, and it might screw up some of your existing shops that use other points. This is more so if you want to completely remove all that and start fresh from a coin base shop system and work around that. Buy price is item high alch value and sell price is low alch value. If the value is 0, it returns it as 1 so at least some of those items like buckets are 1 coin. Also shops 65, 66 and 67 I use as my tokkul shops so i just left them in there. Feel free to change or remove those, or just use them (probably easiest).


    SLAYER

    Spoiler for Slayer:
    I also released this recently if you want to replace the Slayer system as well. Delete all of the files in the slayer package and than add this.
    https://www.rune-server.ee/runescape...ayer-base.html


    Something better than movePlayer, with an animation and timer!

    Spoiler for Not movePlayer...:
    Code:
    public void forceTeleport(final Player player, final int animation, final int newX, final int newY,
    			final int newZ, int ticksBeforeAnim, int ticks) {
    		player.face(player.objectX, player.objectY);
    		if (animation != -1) {
    			if (ticksBeforeAnim < 1) {
    				player.animation(animation);				
    			} else {				
    				 CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
    			            @Override
    			            public void execute(CycleEventContainer container) {			           
    						player.animation(animation);
    						container.stop();
    					}
    			            @Override
    						public void stop() {							
    						}
    				}, 0);
    			}
    		}
    		 CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
    	            @Override
    	            public void execute(CycleEventContainer container) {
    				player.teleportToX = newX;
    				player.teleportToY = newY;
    				player.heightLevel = newZ;
    				
    				container.stop();
    			}
    	            @Override
    				public void stop() {
    					
    				}
    		}, ticks);
    	}
    Add this anywhere, AgilityHandler.Java, TeleportExecutor.java, Player.java, PlayerAssistant.java... wherever you feel it is convenient to grab it.

    Example of use under firstClickObject in ActionHandler.java :

    Code:
    case 16646:
    			if (c.absY == 3517) {  // Player, Animation, TO X, TO Y, TO Height, ticks before animation, amount of ticks event will run for.
    				c.getAgilityHandler().forceTeleport(c, 828, 3666, 3522, 1, 1, 2);
    			}
    			break;
    Use it if you like. I like it better than movePlayer.


    Ring of Suffering acts like recoil(uses recoils to charge)

    Spoiler for Ring of Suffering:
    This only apply's to NPC's, just copy it and replace it for the existing player recoil method.
    If you want to make Ring of Suffering/(i) act like a recoil, just add this. (doesnt impliment xAmount to add, pulls amount of noted and unnoted rings. Could have 2146 Noted and 11 unNoted, and it will delete and apply all of them into the correct amount of charges.)

    First off, open up ItemDef.java (Client Sided)
    Add this in there under ItemDef forId(int i)

    Code:
    case 19550: //Ring of Suffering
    			itemDef.itemActions = new String[5];
    			itemDef.itemActions[1] = "Wear";
    			itemDef.itemActions[2] = "Check";
    			break;
    		case 19710: //Ring of Suffering(i)
    			itemDef.itemActions = new String[5];
    			itemDef.itemActions[1] = "Wear";
    			itemDef.itemActions[2] = "Check";
    			itemDef.itemActions[3] = "Uncharge";
    			break;
    Add this under recoilHits; in Player.java
    Code:
    	public int sufferHits;
    Find removeRecoil in MeleeExtras.java and replace it with this. (If it's not there just add it above or below ApplyRecoilNPC)

    Code:
    public static void removeRecoil(Player c, int damage) {
    		if(c.recoilHits > 0) {
                            if (c.playerEquipment[c.playerRing] == 2550) {
                            	c.recoilHits -= damage;
                            }
    		} if(c.recoilHits <= 0) {
                if (c.playerEquipment[c.playerRing] == 2550) {
                		c.getItems().removeItem(2550, c.playerRing);
                			c.getItems().deleteItem(2550, c.getItems().getItemSlot(2550), 1);
                				c.sendMessage("Your ring of recoil shatters!");
                					c.recoilHits = 0;
                }            
    		}
    		if(c.sufferHits > 0) {
                if (c.playerEquipment[c.playerRing] == 19550 || c.playerEquipment[c.playerRing] == 19710) {
                	c.sufferHits -= damage;
                }
    		} if(c.sufferHits <= 0) {
    			if (c.playerEquipment[c.playerRing] == 19550 || c.playerEquipment[c.playerRing] == 19710) {
    					c.sendMessage("Your ring has run out of charges.");
    						c.sufferHits = 0;
    			}            
    		}
    	}
    Still in meleeExtras, replace applyRecoil with this

    Code:
    public static void applyRecoilNPC(Player c, int damage, int i) {
    		if (damage > 0 && c.playerEquipment[c.playerRing] == 2550
    				|| damage > 0 && c.playerEquipment[c.playerRing] == 19550
    				|| damage > 0 && c.playerEquipment[c.playerRing] == 19710) {
    			if (c.recoilHits > 0 || c.sufferHits > 0) {
    			int recDamage = damage / 10;
    			if (recDamage < 1) {
    				recDamage = 1;
    			}
    			if (NPCHandler.npcs[i].HP <= 0 || NPCHandler.npcs[i].isDead) {
    				return;
    			}
    			NPCHandler.npcs[i].HP -= recDamage;
    			NPCHandler.npcs[i].handleHitMask(recDamage);
    			removeRecoil(c, recDamage);
    			//c.recoilHits += damage;
    			}
    		}
    	}
    Open up your DialogueHandler.java, add this (use your own case #'s and action id's if you'd like)

    Code:
    case 6002:
    			sendItemChat3("Ring of suffering", "Would you like to remove all of the Ring's of recoil", "you currently have and apply the charges to", "your Ring of suffering?", 19550, 200);
    			c.nextChat = 6003;
    			break;
    		case 6003:
    			sendOption2("Yes, apply the charges.", "No, nevermind.");
    			c.dialogueAction = 6003;
    			break;
    		case 6004:
    			sendItemChat3("Ring of suffering(i)", "Would you like to remove all of the Ring's of recoil", "you currently have and apply the charges to", "your Ring of suffering(i)?", 19710, 200);
    			c.nextChat = 6005;
    			break;
    		case 6005:
    			sendOption2("Yes, apply the charges.", "No, nevermind.");
    			c.dialogueAction = 6005;
    			break;
    Code:
    public void sendItemChat3(String header, String one, String two,
    			String three, int item, int zoom) {
    		c.getPA().sendFrame246(4894, zoom, item);
    		c.getPA().sendFrame126(header, 4895);
    		c.getPA().sendFrame126(one, 4896);
    		c.getPA().sendFrame126(two, 4897);
    		c.getPA().sendFrame126(three, 4898);
    		c.getPA().sendFrame164(4893);
    	}
    Incase you dont have that, add that to the bottom of DialogueHandler. Save that.

    There's this one too just incase.

    Code:
    public void sendOption2(String s, String s1) {
    		c.getPA().sendString("Select an Option", 2460);
    		c.getPA().sendString(s, 2461);
    		c.getPA().sendString(s1, 2462);
    
    		c.getPA().sendFrame164(2459);
    	}
    Open up UseItem.java, add this under ItemonItem

    Code:
    if (itemUsed == 2550 && useWith == 19550 ||
    				useWith == 2550 && itemUsed == 19550 ||
    				itemUsed == 2551 && useWith == 19550 || //Charge Ring of Suffering
    				useWith == 2551 && itemUsed == 19550) {			
    			c.getDH().sendDialogues(6002, -1);
    		}
    		if (itemUsed == 2550 && useWith == 19710 ||
    				useWith == 2550 && itemUsed == 19710 ||
    				itemUsed == 2551 && useWith == 19710 || //Charge Ring of Suffering(i)
    				useWith == 2551 && itemUsed == 19710) {			
    			c.getDH().sendDialogues(6004, -1);
    		}
    Open up ClickingButtons.java and underneath case 9157: add,

    Code:
    if (player.dialogueAction == 6003) { //Charge Ring of Suffering
    				int rorN = 2551;
    				int ror = 2550;
    				int rorNAmt = player.getItems().getItemAmount(rorN);
    				int rorAmt = player.getItems().getItemAmount(ror);
    				int totalRor = player.getItems().getItemAmount(rorN) + player.getItems().getItemAmount(ror);
    				player.getItems().deleteItem2(rorN, rorNAmt);
    				player.getItems().deleteItem2(ror, rorAmt);
    				player.sufferHits += totalRor * 40;
    				player.sendMessage("You apply @blu@" + totalRor * 40 + " @bla@charges to the ring.");
    				player.sendMessage("Your Ring of suffering currently has @blu@" + player.sufferHits + " @bla@charges.");
    				player.getPA().removeAllWindows();
    				return;
    			}
    			if (player.dialogueAction == 6005) { //Charge Ring of Suffering(i)
    				int rorN = 2551;
    				int ror = 2550;
    				int rorNAmt = player.getItems().getItemAmount(rorN);
    				int rorAmt = player.getItems().getItemAmount(ror);
    				int totalRor = player.getItems().getItemAmount(rorN) + player.getItems().getItemAmount(ror);
    				player.getItems().deleteItem2(rorN, rorNAmt);
    				player.getItems().deleteItem2(ror, rorAmt);
    				player.sufferHits += totalRor * 40;
    				player.sendMessage("You apply @blu@" + totalRor * 40 + " @bla@charges to the ring.");
    				player.sendMessage("Your Ring of suffering(i) currently has @blu@" + player.sufferHits + " @bla@charges.");
    				player.getPA().removeAllWindows();
    				return;
    			}
    Open up PlayerAssistant.java and add this under applyDead (there should be some similar ones in there already)

    Code:
    if (player.getItems().playerHasItem(19550) || player.getItems().playerHasItem(19551)
    					|| player.getItems().isWearingItem(19550)) {
    				player.sufferHits = 0;
    				player.sendMessage("<col=255>You have lost your Ring of suffering charges!");
    			}
    			if (player.getItems().playerHasItem(19710) || player.getItems().playerHasItem(19711)
    					|| player.getItems().isWearingItem(19710)) {
    				player.sufferHits = 0;
    				player.sendMessage("<col=255>You have lost your Ring of suffering(i) charges!");
    			}
    Open up ItemClick2.java (in packets) and add that

    Code:
    case 19550:
    		case 19710: //Ring of Suffering/(i)
    			c.sendMessage("The ring currently has @blu@" + c.sufferHits + 
    					" @bla@charges left.");
    			break;

    Finally, these go into your PlayerSave.java

    Code:
    else if (token.equals("sufferHits")) {
    						p.sufferHits = Integer.parseInt(token3[0]);
    					}
    Code:
    characterfile.write("sufferHits = ", 0, 13);
    			characterfile.write(Integer.toString(p.sufferHits), 0, Integer.toString(p.sufferHits).length());
    			characterfile.newLine();



    NPC Aggressiveness based on player level * 2 (if cb lvl * 2 + 1 > NPC Combat lvl, NPC is no longer aggressive.)

    Spoiler for NPC Aggression:
    find in npc handler Attacking Player. Between

    Code:
    /**
    					 * Attacking player
    					 **/
    And

    Code:
    if (System.currentTimeMillis() - npcs[i].lastDamageTaken > 5000) {
    						npcs[i].underAttackBy = 0;
    						npcs[i].underAttack = false;
    					}

    Replace the current existing code with this.

    Code:
    if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && !switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    					else if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}		 
    						
    					else if (NpcDefinition.DEFINITIONS[i].isAggressive() && !npcs[i].underAttack && !npcs[i].isDead && !switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    					else if (NpcDefinition.DEFINITIONS[i].isAggressive() && !npcs[i].underAttack && !npcs[i].isDead && switchesAttackers(i)) {
    						int randomPlayer = getCloseRandomPlayer(i);
    						Player player1 = (Player)PlayerHandler.players[getCloseRandomPlayer(i)];
    						if (player1 != null && player1.combatLevel < (npcs[i].definition().getCombatLevel() * 2) + 1) {
    						npcs[i].killerId = randomPlayer;
    					}
    					}
    It will look somewhat similar, you should be able to find this no problem.

    Just incase you don't have this already, add this to the NPCHandler as well.

    Code:
    public int getCloseRandomPlayer(int i) {
    		ArrayList<Integer> players = new ArrayList<>();
    		for (int j = 0; j < PlayerHandler.players.length; j++) {
    			if (PlayerHandler.players[j] != null) {
    				if (Boundary.isIn(npcs[i], Boundary.GODWARS_BOSSROOMS)) {
    					if (!Boundary.isIn(PlayerHandler.players[j], Boundary.GODWARS_BOSSROOMS)) {
    						npcs[i].killerId = 0;
    						continue;
    					}
    				}
    				if (goodDistance(PlayerHandler.players[j].absX, PlayerHandler.players[j].absY, npcs[i].absX,
    						npcs[i].absY, distanceRequired(i) + followDistance(i)) || isFightCaveNpc(i)) {
    					if ((PlayerHandler.players[j].underAttackBy <= 0 && PlayerHandler.players[j].underAttackBy2 <= 0)
    							|| PlayerHandler.players[j].inMulti())
    						if (PlayerHandler.players[j].heightLevel == npcs[i].heightLevel)
    							players.add(j);
    
    				}
    			}
    		}
    		if (players.size() > 0)
    			return players.get(Misc.random(players.size() - 1));
    		return 0;
    	}




    Not using c.absX >= # && c.absX <=# all the time...

    Spoiler for Simple:


    Open Player.java, add this anywhere.

    Example of use
    Code:
    if (c.withinArea(3200, 3202, 3200, 3202) {
    //c.getAgilityHandler().forceTeleport(c, 828, 3201, 3201, 1, 1, 2) <= using method i suggested earlier
    //c.getPA().movePlayer(3201, 3201, 1) <= move player
    }
    The other 3 should be fairly self explanatory just give them a read through.

    Code:
    public boolean withinArea(int x, int x1, int y, int y1) {
    		if (absX >= x && absX <= x1 && absY >= y && absY <= y1) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionXY(int x, int y) {
    		if (absX == x && absY == y) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionXX(int x, int x1) {
    		if (absX >= x && absX <= x1) {
    			return true;
    		} else
    			return false;
    	}
    	public boolean currentPositionYY(int y, int y1) {
    		if (absY >= y && absY <= y1) {
    			return true;
    		} else
    			return false;
    	}



    Use Item on NPC to return it as a note

    Spoiler for NOTE:

    Create a new file called UseToNote.java in package content.
    Code:
    package org.brutality.model.content;
    
    import org.brutality.model.items.Item;
    import org.brutality.model.items.ItemDefinition;
    import org.brutality.model.players.Player;
    
    public class UseToNote {
    	
    	public static int[] cleanHerbs = { 249, 251, 253, 255, 257, 2998, 259, 261, 263, 3000, 265, 2481, 267, 269};
    	public static int[] grimyHerbs = { 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 2485, 3051 };
    	public static int[] otherFarmingItems = { };
    	
    	public static final int PILES = 13;
    	public static final int TOOL_LEPRECHAUN = 0;
    
    	public static boolean noteItemOnPiles(Player c, int npcId, int itemUsed) {
    		int amount = c.getItems().getItemAmount(itemUsed);
    		if (npcId == PILES) {
    			if (!ItemDefinition.forId(itemUsed).isNoted() && !ItemDefinition.forId(itemUsed + 1).isNoted()
    					&& (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    					|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {			
    			if (c.getItems().playerHasItem(995, 50 * amount)) {
    				c.getItems().deleteItem2(995, 50 * amount);
    				c.getItems().deleteItem2(itemUsed, amount);
    				c.getItems().addItem(itemUsed + 1, amount);
    			}
    		}
    		}
    		return false;		
    	}
    	
    	public static boolean noteItemsOnLeprechaun(Player c, int npcId, int itemUsed) {
    		int amount = c.getItems().getItemAmount(itemUsed);
    		if (npcId == TOOL_LEPRECHAUN) {			
    			for (int h = 0; h < cleanHerbs.length; h++)					
    			if (itemUsed == cleanHerbs[h] && !ItemDefinition.forId(itemUsed).isNoted()
    					&& (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    							|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {
    				c.getItems().deleteItem2(cleanHerbs[h], amount);
    				c.getItems().addItem(cleanHerbs[h] + 1, amount);			
    		}	for (int g = 0; g < grimyHerbs.length; g++)		
    			 if (itemUsed == grimyHerbs[g] && !ItemDefinition.forId(itemUsed).isNoted()
    					 && (ItemDefinition.getItemListName(itemUsed).contains(ItemDefinition.getItemListName(itemUsed + 1))
    								|| ItemDefinition.getItemListName(itemUsed + 1).contains(ItemDefinition.getItemListName(itemUsed)))) {
    					c.getItems().deleteItem2(grimyHerbs[g], amount);
    					c.getItems().addItem(grimyHerbs[g] + 1, amount);			
    			}
    		}
    		return false;		
    	}
    }
    add that inside.

    You can cut this down to 1 method by making it grab the npcId you used the item on, but at least this way you can see what is going on in more than one way, and it also allows you to be specific if you only want a certain npc to note a certain item.

    Open up ItemDefinition.java.

    Code:
    public static String getItemListName(int item) {
    		if (item <= -1) {
    			return "None";
    		}
    		if (DEFINITIONS[item] == null) {
    			return "None";
    		}
    		return DEFINITIONS[item].getName();
    	}
    Add that underneath getIdForName.

    Finally open up UseItem.java

    Code:
    UseToNote.noteItemOnPiles(c, npcId, itemId);
    		UseToNote.noteItemsOnLeprechaun(c, npcId, itemId);
    Add that underneath ItemonNPC
    You can easily convert this to an object or anything you want really.



    Object Picking (Flax, w/e you wanna do with it)
    Do not use this for door handling. But this can be used for things like making
    a chest open and shut when a player uses a key on it etc.. or opening a cupboard.


    Spoiler for Why would we want to pick flax on rsps?:

    create a new file called Flax.java in package world.objects
    Code:
    package org.brutality.world.objects;
    
    import java.util.ArrayList;
    
    import org.brutality.model.players.Player;
    import org.brutality.util.Misc;
    import org.brutality.world.objects.GlobalObject;
    import org.brutality.Config;
    import org.brutality.Server;
    
     
    public class Flax {
    	
    	
    	public static void pickFlax(final Player c, final int objectId, final int x, final int y) {
    		if (c.getItems().freeSlots() != 0) {	
    			c.getItems().addItem(1779, 1);
                c.animation(827);
                if (Misc.random(5) == 0) {
                Server.getGlobalObjects()
    			.add(new GlobalObject(-1, x, y, c.heightLevel, 0, 10, 15, objectId));
                }
    			
    		} else {
    			c.sendMessage("Not enough space in your inventory.");
    			return;
    		}
    	
    	}
    }
    add that inside and save.

    Open ActionHandler.java

    under secondClickObject add

    Code:
    case 7134:
    			Flax.pickFlax(c, objectType, obX, obY);
    		break;




    Hopefully this will help some of you just starting out.
    Message me, post or whatever if i missed anything. This is my first post like this.
    Enjoy! or durnt

    -Crusty Rob
    -"Where's the beef?"


    Very usefull, didnt had the time to find those myself, +1
    Reply With Quote  
     

  6. #6  
    Registered Member omnee's Avatar
    Join Date
    Apr 2011
    Posts
    135
    Thanks given
    30
    Thanks received
    11
    Rep Power
    18
    Quote Originally Posted by Crusty Rob View Post
    This was a very simple fix, honestly i completely forget how i fixed this problem. Its checking to see if you are right infront of the tile that the object is placed, and if not, it stops. I think it's in walking or ClickObject but im not 100% sure. If i remember or stumble upon this fix i'll add it here. It is one line of code that is stopping you from doing this.
    ClickObject.java

    Code:
    private static final int[] ignorePathObjects
    Just add 20671 and 20672 to that array. Not the correct way to fix it, but it'll do I guess.
    Those are Verac and Torag stairs, just add whatever objects have that issue.
    Reply With Quote  
     

  7. #7  
    Banned
    Join Date
    Apr 2016
    Posts
    150
    Thanks given
    51
    Thanks received
    3
    Rep Power
    0
    May u say whats wrong with the Slayer?
    Reply With Quote  
     

  8. #8  
    Registered Member
    Join Date
    Nov 2015
    Posts
    77
    Thanks given
    16
    Thanks received
    22
    Rep Power
    51
    Quote Originally Posted by omnee View Post
    ClickObject.java

    Code:
    private static final int[] ignorePathObjects
    Just add 20671 and 20672 to that array. Not the correct way to fix it, but it'll do I guess.
    Those are Verac and Torag stairs, just add whatever objects have that issue.
    You can do this but there is one line of code in there from doing it. Try things in clickObject, Region or walking i think.. i dont think it was in the actionHandler.

    Also @Gkua, nothing i just think its silly to have 8 different files for slayer. If you read in the comments of slayer it isnt the best way to do it, but it will give you more variables to play with. (Lets you kill say abyssal sire on abby demon task, or lets you specify you can kill cerberus on a hellhound task). It works fine for what slayer needs to be. If someone wants to rewrite the task part i can edit it, but im leaving it the way it is for now
    Reply With Quote  
     

  9. #9  
    Respected Member


    George's Avatar
    Join Date
    Mar 2009
    Posts
    7,099
    Thanks given
    2,226
    Thanks received
    3,146
    Rep Power
    5000
    Seems like a really tedious server to work with.
    Attached image

    Spoiler for Spoilers!:
    Attached image
    Attached image
    Attached image
    Attached image
    Reply With Quote  
     

  10. Thankful users:


  11. #10  
    Registered Member omnee's Avatar
    Join Date
    Apr 2011
    Posts
    135
    Thanks given
    30
    Thanks received
    11
    Rep Power
    18
    Quote Originally Posted by Idiot Bird View Post
    Seems like a really tedious server to work with.
    Why do you say that?
    I'm in no way experienced in private servers, been working with this one for a bit and I'm really enjoying it
    Reply With Quote  
     

  12. Thankful users:


Page 1 of 3 123 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. [RuneEscape] Some bug fixes
    By dragonkk in forum Tutorials
    Replies: 5
    Last Post: 08-19-2011, 06:38 PM
  2. some rs2hd fixes (i hope)
    By Dylan in forum Snippets
    Replies: 4
    Last Post: 03-15-2010, 07:27 AM
  3. some 1 fix it ?:S
    By b33r in forum Help
    Replies: 0
    Last Post: 07-16-2009, 10:13 AM
  4. need some glitchs fixed...
    By silabgarza in forum Help
    Replies: 4
    Last Post: 03-23-2009, 01:35 AM
  5. Need a mod+ code. or some error fixing.
    By .:Programing God:. in forum Help
    Replies: 5
    Last Post: 01-30-2009, 03:32 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •