Thread: [Ruse] Hp Overlay, and Damage Hit Mask "Fixes"

Results 1 to 2 of 2
  1. #1 [Ruse] Hp Overlay, and Damage Hit Mask "Fixes" 
    Registered Member
    Join Date
    Sep 2018
    Posts
    47
    Thanks given
    21
    Thanks received
    17
    Rep Power
    37
    Hi All,
    Sorry if this is in the wrong section. This is my first time posting a thread on the forums here.

    A few months back I was browsing this forum and came across a help thread asking for help displaying numbers over 65535 on Hp Overlays. I explained the issue, and how to fix it. However, Multiple people ended up DMing me on here asking for help fixing it. So I figured I should take the time to fix this properly. However, after starting to fix this, anther person had DMed me asking for information on how to fix Damage masks showing more damage than 65535 (6553 Non x10 Hitting). So without further ado, The "Fixes".

    *Disclaimer: There is no reason to implement this if you are not using this for a custom server with insane amounts of strength.

    The Issues:
    HP over 65535 (6553 Non x10 Hitting) would not display correctly, and cause the bar to Constantly grow and shrink on each combat tick.
    Damage over 65535 (6553 Non x10 Hitting) would not display correctly, causing confusion when an enemy dies quicker than the damage displaying.

    The Fix (This does fix both things as their both handled in the same packet):
    To Start, Were going to be making changes to the server, then the client to keep things a bit easier. The first thing were going to do is stop packet 207 from sending from the server to the client. Go into PacketSender.java, and locate the void "sendEntityInterface"
    It should look something like this:

    Code:
        public PacketSender sendEntityInterface(int flag, int maxHealth, int currentHealth, String entityName) {
            PacketBuilder out = new PacketBuilder(207);
            out.putShort(flag);
            out.putShort(maxHealth);
            out.putShort(currentHealth);
            player.getSession().queueMessage(out);
            sendEntityName(entityName);
            player.sendParallellInterfaceVisibility(41020, true);
            return this;
            
        }
    Delete the entire void.

    Now while still in PacketSender, Go to the void "sendEntityName", It should look like this.

    Code:
        public PacketSender sendEntityName(String name) {
            PacketBuilder out = new PacketBuilder(205, PacketType.BYTE);
            out.putString(name);
            player.getSession().queueMessage(out);
            return this;
        }
    Replace with:

    Code:
        public PacketSender sendEntityInterface(String name) {
            PacketBuilder out = new PacketBuilder(205, PacketType.BYTE);
            out.putString(name);
            player.getSession().queueMessage(out);
            player.sendParallellInterfaceVisibility(41020, true);
            return this;
        }
    Now there are going to be a few errors in CombatHitTask, Open CombatHitTask.java, and go to the void "handleEntityInterface".
    The current code should look something like:

    Code:
        public void handleEntityInterface(Character attacker, Character victim, int damage) {
            if (attacker.isPlayer()) {
                Player p = (Player) attacker;
                
                if (victim.isPlayer()) {//plrs
                    Player v = (Player) victim;
                    int maximumHealth = v.getSkillManager().getMaxLevel(Skill.CONSTITUTION);
                    int currentHealth = v.getSkillManager().getCurrentLevel(Skill.CONSTITUTION);
                    String entityName = v.getUsername();
                    p.getPacketSender().sendEntityInterface(victim.isPlayer() ? 1 : 0, maximumHealth, currentHealth, entityName);
                } else if (victim.isNpc()) {//npcs
                    NPC v = (NPC) victim;
                    int maximumHealth = v.getDefaultConstitution();
                    int currentHealth = v.getConstitution();
                    String entityName = v.getDefinition().getName();
                    p.getPacketSender().sendEntityInterface(victim.isPlayer() ? 1 : 0, maximumHealth, currentHealth, entityName);
                }
            }
        }
    Replace it with:

    Code:
        public void handleEntityInterface(Character attacker, Character victim, int damage) {
            if (attacker.isPlayer()) {
                Player p = (Player) attacker;
                if (victim.isPlayer()) {//plrs
                    Player v = (Player) victim;
                    String entityName = v.getUsername();
                    p.getPacketSender().sendEntityInterface(entityName);
                } else if (victim.isNpc()) {//npcs
                    NPC v = (NPC) victim;
                    String entityName = v.getDefinition().getName();
                    p.getPacketSender().sendEntityInterface(entityName);
                }
            }
        }
    So far what we have done is disabled the packet 207 from sending, and moved the code that actually displays the interface into packet 205 (Sending the Entity Name. i.e Npc Name or Player Name depending on circumstances, However the way we will be sending hp will only be for NPC's. With a bit of knowledge can be expanded to players as well.

    Now were going to start sending the currentEntityHealth, and maximumEntityHealth through an entityUpdate. Which is already done for HP Bar drawing, Not to be confused with the overlay were currently fixing.

    Open up NPCUpdating.java, Go to the void "updateSingleHit", It should look like this:

    Code:
    	private static void updateSingleHit(PacketBuilder builder, NPC npc) {
    		builder.putShort(npc.getPrimaryHit().getDamage(), ValueType.A);
    		builder.put(npc.getPrimaryHit().getHitmask().ordinal(), ValueType.C);
    		builder.put(npc.getPrimaryHit().getCombatIcon().ordinal() - 1);
    		builder.putShort(npc.getConstitution(), ValueType.A);
    		builder.putShort(npc.getDefaultConstitution(), ValueType.A);
    	}
    Now, change all the builder.putShort to builder.putInt, Then remove all the code after the first comma in the parentheses. The code should now look like this:

    Code:
    	private static void updateSingleHit(PacketBuilder builder, NPC npc) {
    		builder.putInt(npc.getPrimaryHit().getDamage());
    		builder.put(npc.getPrimaryHit().getHitmask().ordinal(), ValueType.C);
    		builder.put(npc.getPrimaryHit().getCombatIcon().ordinal() - 1);
    		builder.putInt(npc.getConstitution());
    		builder.putInt(npc.getDefaultConstitution());
    	}
    Now while still in CombatHitTask, go to the void "updateDoubleHit", and do the exact same things you had just done to "updateSingleHit", to "updateDoubleHit". "updateDoubleHit" should now look like this:

    Code:
    	private static void updateDoubleHit(PacketBuilder builder, NPC npc) {
    		builder.putInt(npc.getSecondaryHit().getDamage());
    		builder.put(npc.getSecondaryHit().getHitmask().ordinal(), ValueType.S);
    		builder.put(npc.getSecondaryHit().getCombatIcon().ordinal() - 1);
    		builder.putInt(npc.getConstitution());
    		builder.putInt(npc.getDefaultConstitution());
    	}
    We have officially finished the server portion of the code for the fix. What we have done is updated the packets to send higher values to the client, as well as made it so all the interface showing, is mostly handled when the entityname is sent.

    Now were going to start making changes to the client, to be able to read, and understand the higher values coming from the server.

    Open Client.java, and search for the void "drawHpBar" it should look something like this:

    Code:
    	private void drawHpBar() {
    		RSInterface iface = RSInterface.interfaceCache[41020];
    
    		if (!parallelWidgetList.contains(iface)) {
    			return;
    		}
    
    		float percentage = ((float) currentEntityHealth / (float) maximumEntityHealth) * (float) 100;
    		DrawingArea.drawPixels(16, iface.y + 30, iface.x, 0x00b300, (int) percentage * 7/6);
    		// drawPixels(int height_, int yPos, int xPos, int color, int width_)
    
    		TextDrawingArea.drawAlphaFilledPixels(iface.x, iface.y + 30, 117, 16, 0xff000d, 50);
    		// int xPos, int yPos,
    		// int pixelWidth, int pixelHeight, int color, int alpha) {// method586
    		RSInterface text = RSInterface.interfaceCache[41023];
    		newSmallFont.drawCenteredString(iface.message, 63, 52, 0xffffff, 1);
    	}
    What were going to do is add the ability for the currentEntityHealth, and maximumEntityHealth to be drawn at the same time the green portions of the hp overlay is drawn based on percent of hp left.

    Replace the current drawHpBar code with this code below:

    Code:
    	private void drawHpBar() {
    		RSInterface iface = RSInterface.interfaceCache[41020];
    
    		if (!parallelWidgetList.contains(iface)) {
    			return;
    		}
    		int current = currentEntityHealth;
    		int max  = maximumEntityHealth;
    		if (!getOption("constitution")) {
    			current = current / 10;
    			max = max / 10;
    		}
    		float percentage = ((float) currentEntityHealth / (float) maximumEntityHealth) * (float) 100;
    		DrawingArea.drawPixels(16, iface.y + 30, iface.x, 0x00b300, (int) percentage * 7/6);
    		// drawPixels(int height_, int yPos, int xPos, int color, int width_)
    		iface.message = current + " / " + max;
    		TextDrawingArea.drawAlphaFilledPixels(iface.x, iface.y + 30, 117, 16, 0xff000d, 50);
    		// int xPos, int yPos,
    		// int pixelWidth, int pixelHeight, int color, int alpha) {// method586
    		RSInterface text = RSInterface.interfaceCache[41023];
    		newSmallFont.drawCenteredString(iface.message, 63, 52, 0xffffff, 1);
    	}
    Now we need to tell the client how much currentEntityHealth, and maximumEntityHealth the entity has.

    While still in Client.java, Were going to update the hitmask to get be able to read the data from the server being sent (see NPCUpdating Section) search for "((l & 8) != 0)". the code should look something like this.

    Code:
    			if ((l & 8) != 0) {
    				int j1 = inStream.readByteA();
    				int j2 = stream.nglb();
    				int icon = stream.readUnsignedByte();
    				npc.updateHitData(j2, j1, loopCycle, icon, 0);
    				npc.loopCycleStatus = loopCycle + 300;
    				npc.currentHealth = inStream.readByteA();
    				npc.maxHealth = inStream.readByteA();
    			}
    Replace with

    Code:
    			if ((l & 8) != 0) {
    				int j1 = inStream.readInt();
    				int j2 = stream.nglb();
    				int icon = stream.readUnsignedByte();
    				npc.updateHitData(j2, j1, loopCycle, icon, 0);
    				npc.loopCycleStatus = loopCycle + 300;
    				npc.currentHealth = inStream.readInt();
    				npc.maxHealth = inStream.readInt();
    				currentEntityHealth = npc.currentHealth;
    				maximumEntityHealth = npc.maxHealth;
    			}
    Now search for "(l & 0x40) != 0" the code should look identical to the first mask we editted:

    Code:
    			if ((l & 0x40) != 0) {
    				int l1 = inStream.readByteA();
    				int k2 = stream.readByteS();
    				int icon = stream.readUnsignedByte();
    				npc.updateHitData(k2, l1, loopCycle, icon, 0);
    				npc.loopCycleStatus = loopCycle + 300;
    				npc.currentHealth = inStream.readByteA();
    				npc.maxHealth = inStream.readByteA();
    			}
    Replace with

    Code:
    			if ((l & 0x40) != 0) {
    				int l1 = inStream.readInt();
    				int k2 = stream.readByteS();
    				int icon = stream.readUnsignedByte();
    				npc.updateHitData(k2, l1, loopCycle, icon, 0);
    				npc.loopCycleStatus = loopCycle + 300;
    				npc.currentHealth = inStream.readInt();
    				npc.maxHealth = inStream.readInt();
    				currentEntityHealth = npc.currentHealth;
    				maximumEntityHealth = npc.maxHealth;
    			}
    Now save and compile everything, and run your server and client. You should now be able to see the HPOverlay with correct constitution values, as well as hit masks with damage over 65535.
    If you have any issues implementing this, or something doesn't work, Feel free to scream at me in DMs.

    Teaser of End Product:
    Attached image
    Last edited by Seraphim; 09-14-2019 at 11:37 PM. Reason: Fixed an issue I forgot to fix earlier, updated code
    Reply With Quote  
     

  2. Thankful users:


  3. #2  
    Registered Member
    Join Date
    Aug 2012
    Posts
    139
    Thanks given
    23
    Thanks received
    20
    Rep Power
    25
    Nice tutorial, a lot of custom private servers will find this extremely helpful as they don't display the correct HP and damages.
    Reply With Quote  
     


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. Replies: 6
    Last Post: 04-02-2012, 11:43 PM
  2. What are hit mask 3 and 4?
    By JalYt Marcel in forum Help
    Replies: 2
    Last Post: 11-07-2010, 05:13 PM
  3. Replies: 5
    Last Post: 09-16-2010, 02:00 AM
  4. 484 hp bar 'fix' for hit masks
    By cube in forum Snippets
    Replies: 3
    Last Post: 03-28-2010, 08:44 PM
  5. Replies: 0
    Last Post: 09-22-2009, 06:00 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •