Thread: Multi-level entity rendering

Page 1 of 2 12 LastLast
Results 1 to 10 of 17
  1. #1 Multi-level entity rendering 
    Registered Member Tatsuya's Avatar
    Join Date
    Dec 2011
    Posts
    335
    Thanks given
    74
    Thanks received
    52
    Rep Power
    61
    As the title suggest this is how you make it so entities (players and npcs) are seen on different height levels.

    I am releasing this because I have no intention of developing RSPS any further, and this is something I want to see in the real RuneScape so I figure this would be a good way for it to gain some traction.
    If you want some pictures of how this would look, go to the link in my Signature.
    This should be a fairly easy modification, literally just copy paste.

    I am not responsible for any broken clients/servers. Use at your own risk.

    Before you begin my NPC methods are "Mob" just change that, if you cannot and ask for help then I will not help you.

    Client Side
    First add
    Code:
    public static final boolean MULTILEVEL_RENDER = true;
    Into a configuration file. Mine is Configuration.java

    Next in Client.java

    In your addNewMob method you will be adding a new area for npc's heightlevel is be recieved from the server.
    Code:
    private void addNewMob(final int i, final Stream stream) {
    	while (stream.bitPosition + 21 < i * 8) {
    		final int k = stream.readBits(14);
    		if (k == 16383) {
    			break;
    		}
    		if (mobArray[k] == null) {
    			mobArray[k] = new Mob();
    		}
    		final Mob mob = mobArray[k];
    		mobIndices[mobCount++] = k;
    		mob.anInt1537 = Client.loopCycle;
    		int l = stream.readBits(5);
    		if (l > 15) {
    			l -= 32;
    		}
    		int i1 = stream.readBits(5);
    		if (i1 > 15) {
    			i1 -= 32;
    		}
    		if (Configuration.MULTILEVEL_RENDER) {
    			mob.heightLevel = stream.readBits(5);
    		}
    		final int j1 = stream.readBits(1);
    		mob.desc = MobDef.forID(stream.readBits(12));
    		final int k1 = stream.readBits(1);
    		if (k1 == 1) {
    			anIntArray894[anInt893++] = k;
    		}
    		mob.anInt1540 = mob.desc.aByte68;
    		mob.anInt1504 = mob.desc.anInt79;
    		mob.anInt1554 = mob.desc.anInt67;
    		mob.anInt1555 = mob.desc.anInt58;
    		mob.anInt1556 = mob.desc.anInt83;
    		mob.anInt1557 = mob.desc.anInt55;
    		mob.standAnimation = mob.desc.anInt77;
    
    		mob.setEntityPos(Client.myPlayer.smallX[0] + i1, Client.myPlayer.smallY[0] + l, j1 == 1);
    	}
    	stream.finishBitAccess();
    }
    We will be doing the same for your addNewPlayer method
    Code:
    private void addNewPlayer(final Stream stream, final int i) {
    	while (stream.bitPosition + 10 < i * 8) {
    		final int j = stream.readBits(11);
    		if (j == 2047) {
    			break;
    		}
    		if (playerArray[j] == null) {
    			playerArray[j] = new Player();
    			if (aStreamArray895s[j] != null) {
    				playerArray[j].updatePlayer(aStreamArray895s[j]);
    			}
    		}
    		playerIndices[playerCount++] = j;
    		final Player player = playerArray[j];
    		player.anInt1537 = Client.loopCycle;
    		final int k = stream.readBits(1);
    		if (k == 1) {
    			anIntArray894[anInt893++] = j;
    		}
    		final int l = stream.readBits(1);
    		int i1 = stream.readBits(5);
    		if (i1 > 15) {
    			i1 -= 32;
    		}
    		int j1 = stream.readBits(5);
    		if (j1 > 15) {
    			j1 -= 32;
    		}
    		if (Configuration.MULTILEVEL_RENDER) {
    			player.heightLevel = stream.readBits(5);
    		}
    		player.setEntityPos(Client.myPlayer.smallX[0] + j1, Client.myPlayer.smallY[0] + i1, l == 1);
    	}
    	stream.finishBitAccess();
    }
    Optional
    We need to make it so you cannot click on entities at different height levels, this can be changed if you want multi level combat.

    At buildAtNPCMenu
    Code:
    private void buildAtMobMenu(MobDef entityDef, final int i, final int j, Entity entity, final int k) {
    	if (Configuration.MULTILEVEL_RENDER) {
    		if (entity.heightLevel != Client.myPlayer.heightLevel) {
    			return;
    		}
    	}
    	if (menuActionRow >= 400) {
    		return;
    	}
    	if (entityDef.childrenIDs != null) {
    		entityDef = entityDef.method161();
    	}
    	if (entityDef == null) {
    		return;
    	}
    	if (!entityDef.aBoolean84) {
    		return;
    	}
    	String s = entityDef.name;
    	if (entityDef.combatLevel != 0) {
    		s = s + Client.combatDiffColor(Client.myPlayer.combatLevel, entityDef.combatLevel) + " (level-"
    				+ entityDef.combatLevel + ")";
    	}
    	if (itemSelected == 1) {
    		menuActionName[menuActionRow] = "Use " + selectedItemName + " with @yel@" + s;
    		menuActionID[menuActionRow] = 582;
    		menuActionCmd1[menuActionRow] = i;
    		menuActionCmd2[menuActionRow] = k;
    		menuActionCmd3[menuActionRow] = j;
    		menuActionRow++;
    		return;
    	}
    	if (spellSelected == 1) {
    		if ((spellUsableOn & 2) == 2) {
    			menuActionName[menuActionRow] = spellTooltip + " @yel@" + s;
    			menuActionID[menuActionRow] = 413;
    			menuActionCmd1[menuActionRow] = i;
    			menuActionCmd2[menuActionRow] = k;
    			menuActionCmd3[menuActionRow] = j;
    			menuActionRow++;
    		}
    	} else {
    		if (entityDef.actions != null) {
    			for (int l = 4; l >= 0; l--) {
    				if (entityDef.actions[l] != null && !entityDef.actions[l].equalsIgnoreCase("attack")) {
    					menuActionName[menuActionRow] = entityDef.actions[l] + " @yel@" + s;
    					if (l == 0) {
    						menuActionID[menuActionRow] = 20;
    					}
    					if (l == 1) {
    						menuActionID[menuActionRow] = 412;
    					}
    					if (l == 2) {
    						menuActionID[menuActionRow] = 225;
    					}
    					if (l == 3) {
    						menuActionID[menuActionRow] = 965;
    					}
    					if (l == 4) {
    						menuActionID[menuActionRow] = 478;
    					}
    					menuActionCmd1[menuActionRow] = i;
    					menuActionCmd2[menuActionRow] = k;
    					menuActionCmd3[menuActionRow] = j;
    					menuActionRow++;
    				}
    			}
    
    		}
    		if (entityDef.actions != null) {
    			for (int i1 = 4; i1 >= 0; i1--) {
    				if (entityDef.actions[i1] != null && entityDef.actions[i1].equalsIgnoreCase("attack")) {
    					char c = '\0';
    					if (entityDef.combatLevel > Client.myPlayer.combatLevel) {
    						c = '\u07D0';
    					}
    					menuActionName[menuActionRow] = entityDef.actions[i1] + " @yel@" + s;
    					if (i1 == 0) {
    						menuActionID[menuActionRow] = 20 + c;
    					}
    					if (i1 == 1) {
    						menuActionID[menuActionRow] = 412 + c;
    					}
    					if (i1 == 2) {
    						menuActionID[menuActionRow] = 225 + c;
    					}
    					if (i1 == 3) {
    						menuActionID[menuActionRow] = 965 + c;
    					}
    					if (i1 == 4) {
    						menuActionID[menuActionRow] = 478 + c;
    					}
    					menuActionCmd1[menuActionRow] = i;
    					menuActionCmd2[menuActionRow] = k;
    					menuActionCmd3[menuActionRow] = j;
    					menuActionRow++;
    				}
    			}
    
    		}
    		menuActionName[menuActionRow] = "Examine @yel@" + s + (Configuration.debug ? " @gre@(@whi@" + entityDef.type + "@gre@)" : "");
    		menuActionID[menuActionRow] = 1025;
    		menuActionCmd1[menuActionRow] = i;
    		menuActionCmd2[menuActionRow] = k;
    		menuActionCmd3[menuActionRow] = j;
    		menuActionRow++;
    	}
    }
    And your buildAtPlayerMenu
    Code:
    private void buildAtPlayerMenu(final int i, final int j, final Player player, final int k) {
    	if (player == Client.myPlayer) {
    		return;
    	}
    	if (Configuration.MULTILEVEL_RENDER) {
    		if (player.heightLevel != Client.myPlayer.heightLevel) {
    			return;
    		}
    	}
    	if (menuActionRow >= 400) {
    		return;
    	}
    	String s;
    	if (player.skill == 0) {
    		s = player.name + Client.combatDiffColor(Client.myPlayer.combatLevel, player.combatLevel) + " (level-"
    				+ player.combatLevel + ")";
    	} else {
    		s = player.name + " (skill-" + player.skill + ")";
    	}
    	if (itemSelected == 1) {
    		menuActionName[menuActionRow] = "Use " + selectedItemName + " with @whi@" + s;
    		menuActionID[menuActionRow] = 491;
    		menuActionCmd1[menuActionRow] = j;
    		menuActionCmd2[menuActionRow] = i;
    		menuActionCmd3[menuActionRow] = k;
    		menuActionRow++;
    	} else if (spellSelected == 1) {
    		if ((spellUsableOn & 8) == 8) {
    			menuActionName[menuActionRow] = spellTooltip + " @whi@" + s;
    			menuActionID[menuActionRow] = 365;
    			menuActionCmd1[menuActionRow] = j;
    			menuActionCmd2[menuActionRow] = i;
    			menuActionCmd3[menuActionRow] = k;
    			menuActionRow++;
    		}
    	} else {
    		for (int l = 4; l >= 0; l--) {
    			if (atPlayerActions[l] != null) {
    				menuActionName[menuActionRow] = atPlayerActions[l] + " @whi@" + s;
    				char c = '\0';
    				if (atPlayerActions[l].equalsIgnoreCase("attack")) {
    					if (player.combatLevel > Client.myPlayer.combatLevel) {
    						c = '\u07D0';
    					}
    					if (Client.myPlayer.team != 0 && player.team != 0) {
    						if (Client.myPlayer.team == player.team) {
    							c = '\u07D0';
    						} else {
    							c = '\0';
    						}
    					}
    				} else if (atPlayerArray[l]) {
    					c = '\u07D0';
    				}
    				if (l == 0) {
    					menuActionID[menuActionRow] = 561 + c;
    				}
    				if (l == 1) {
    					menuActionID[menuActionRow] = 779 + c;
    				}
    				if (l == 2) {
    					menuActionID[menuActionRow] = 27 + c;
    				}
    				if (l == 3) {
    					menuActionID[menuActionRow] = 577 + c;
    				}
    				if (l == 4) {
    					menuActionID[menuActionRow] = 729 + c;
    				}
    				menuActionCmd1[menuActionRow] = j;
    				menuActionCmd2[menuActionRow] = i;
    				menuActionCmd3[menuActionRow] = k;
    				menuActionRow++;
    			}
    		}
    
    	}
    	for (int i1 = 0; i1 < menuActionRow; i1++) {
    		if (menuActionID[i1] == 516) {
    			menuActionName[i1] = "Walk here @whi@" + s;
    			return;
    		}
    	}
    
    }
    Next is minimap, this can be turned on or off depending on if you want it or not, I prefer to have it on so the minimap doesn't look as crowded.
    Code:
    private void drawMinimap() {
    	aRSImageProducer_1164.initDrawingArea();
    	if (anInt1021 == 2) {
    		final byte abyte0[] = mapBack.aByteArray1450;
    		final int ai[] = DrawingArea.pixels;
    		final int k2 = abyte0.length;
    		for (int i5 = 0; i5 < k2; i5++) {
    			if (abyte0[i5] == 0) {
    				ai[i5] = 0;
    			}
    		}
    
    		compass.method352(33, viewRotation, anIntArray1057, 256, anIntArray968, 25, 0, 0, 33, 25);
    		aRSImageProducer_1165.initDrawingArea();
    		return;
    	}
    	final int i = viewRotation + minimapRotation & 0x7ff;
    	final int j = 48 + Client.myPlayer.x / 32;
    	final int l2 = 464 - Client.myPlayer.y / 32;
    	aClass30_Sub2_Sub1_Sub1_1263.method352(151, i, anIntArray1229, 256 + minimapZoom, anIntArray1052, l2, 5, 25,
    			146, j);
    	compass.method352(33, viewRotation, anIntArray1057, 256, anIntArray968, 25, 0, 0, 33, 25);
    	for (int j5 = 0; j5 < anInt1071; j5++) {
    		final int k = anIntArray1072[j5] * 4 + 2 - Client.myPlayer.x / 32;
    		final int i3 = anIntArray1073[j5] * 4 + 2 - Client.myPlayer.y / 32;
    		markMinimap(aClass30_Sub2_Sub1_Sub1Array1140[j5], k, i3);
    	}
    
    	for (int k5 = 0; k5 < 104; k5++) {
    		for (int l5 = 0; l5 < 104; l5++) {
    			final NodeList class19 = groundArray[plane][k5][l5];
    			if (class19 != null) {
    				final int l = k5 * 4 + 2 - Client.myPlayer.x / 32;
    				final int j3 = l5 * 4 + 2 - Client.myPlayer.y / 32;
    				markMinimap(mapDotItem, l, j3);
    			}
    		}
    
    	}
    
    	for (int i6 = 0; i6 < mobCount; i6++) {
    		final Mob mob = mobArray[mobIndices[i6]];
    		if (Configuration.MULTILEVEL_RENDER) {
    			if (mob.heightLevel != Client.myPlayer.heightLevel) {
    				continue;
    			}
    		}
    		if (mob != null && mob.isVisible()) {
    			MobDef entityDef = mob.desc;
    			if (entityDef.childrenIDs != null) {
    				entityDef = entityDef.method161();
    			}
    			if (entityDef != null && entityDef.aBoolean87 && entityDef.aBoolean84) {
    				final int i1 = mob.x / 32 - Client.myPlayer.x / 32;
    				final int k3 = mob.y / 32 - Client.myPlayer.y / 32;
    				markMinimap(mapDotMob, i1, k3);
    			}
    		}
    	}
    
    	for (int j6 = 0; j6 < playerCount; j6++) {
    		final Player player = playerArray[playerIndices[j6]];
    		if (Configuration.MULTILEVEL_RENDER) {
    			if (player.heightLevel != Client.myPlayer.heightLevel) {
    				continue;
    			}
    		}
    		if (player != null && player.isVisible()) {
    			final int j1 = player.x / 32 - Client.myPlayer.x / 32;
    			final int l3 = player.y / 32 - Client.myPlayer.y / 32;
    			boolean flag1 = false;
    			final long l6 = TextClass.longForName(player.name);
    			for (int k6 = 0; k6 < friendsCount; k6++) {
    				if (l6 != friendsListAsLongs[k6] || friendsNodeIDs[k6] == 0) {
    					continue;
    				}
    				flag1 = true;
    				break;
    			}
    
    			boolean flag2 = false;
    			if (Client.myPlayer.team != 0 && player.team != 0 && Client.myPlayer.team == player.team) {
    				flag2 = true;
    			}
    			if (player.morph != null) {
    				markMinimap(mapDotMob, j1, l3);
    			} else if (flag1) {
    				markMinimap(mapDotFriend, j1, l3);
    			} else if (flag2) {
    				markMinimap(mapDotTeam, j1, l3);
    			} else {
    				markMinimap(mapDotPlayer, j1, l3);
    			}
    		}
    	}
    
    	if (anInt855 != 0 && Client.loopCycle % 20 < 10) {
    		if (anInt855 == 1 && anInt1222 >= 0 && anInt1222 < mobArray.length) {
    			final Mob class30_sub2_sub4_sub1_sub1_1 = mobArray[anInt1222];
    			if (class30_sub2_sub4_sub1_sub1_1 != null) {
    				final int k1 = class30_sub2_sub4_sub1_sub1_1.x / 32 - Client.myPlayer.x / 32;
    				final int i4 = class30_sub2_sub4_sub1_sub1_1.y / 32 - Client.myPlayer.y / 32;
    				method81(mapMarker, i4, k1);
    			}
    		}
    		if (anInt855 == 2) {
    			final int l1 = (anInt934 - baseX) * 4 + 2 - Client.myPlayer.x / 32;
    			final int j4 = (anInt935 - baseY) * 4 + 2 - Client.myPlayer.y / 32;
    			method81(mapMarker, j4, l1);
    		}
    		if (anInt855 == 10 && anInt933 >= 0 && anInt933 < playerArray.length) {
    			final Player class30_sub2_sub4_sub1_sub2_1 = playerArray[anInt933];
    			if (class30_sub2_sub4_sub1_sub2_1 != null) {
    				final int i2 = class30_sub2_sub4_sub1_sub2_1.x / 32 - Client.myPlayer.x / 32;
    				final int k4 = class30_sub2_sub4_sub1_sub2_1.y / 32 - Client.myPlayer.y / 32;
    				method81(mapMarker, k4, i2);
    			}
    		}
    	}
    	if (destX != 0) {
    		final int j2 = destX * 4 + 2 - Client.myPlayer.x / 32;
    		final int l4 = destY * 4 + 2 - Client.myPlayer.y / 32;
    		markMinimap(mapFlag, j2, l4);
    	}
    	DrawingArea.drawPixels(3, 78, 97, 0xffffff, 3);
    	aRSImageProducer_1165.initDrawingArea();
    }
    Now we need to draw the entities
    Code:
    private void drawMobs(final boolean flag) {
    	for (int j = 0; j < mobCount; j++) {
    		final Mob mob = mobArray[mobIndices[j]];
    		int k = 0x20000000 + (mobIndices[j] << 14);
    		if (mob == null || !mob.isVisible() || mob.desc.aBoolean93 != flag) {
    			continue;
    		}
    		final int l = mob.x >> 7;
    		final int i1 = mob.y >> 7;
    		if (l < 0 || l >= 104 || i1 < 0 || i1 >= 104) {
    			continue;
    		}
    		if (mob.anInt1540 == 1 && (mob.x & 0x7f) == 64 && (mob.y & 0x7f) == 64) {
    			if (anIntArrayArray929[l][i1] == anInt1265) {
    				if (Configuration.MULTILEVEL_RENDER && mob.heightLevel == myPlayer.heightLevel) {
    					continue;
    				}
    			}
    			anIntArrayArray929[l][i1] = anInt1265;
    		}
    		if (!mob.desc.aBoolean84) {
    			k += 0x80000000;
    		}
    		if (Configuration.MULTILEVEL_RENDER) {
    			worldController.add(mob.heightLevel, mob.yaw, method42(mob.heightLevel, mob.y, mob.x), k, mob.y, (mob.anInt1540 - 1) * 64 + 60,
    					mob.x, mob, mob.canRotate);
    		} else {
    			worldController.add(plane, mob.yaw, method42(plane, mob.y, mob.x), k, mob.y, (mob.anInt1540 - 1) * 64 + 60,
    					mob.x, mob, mob.canRotate);
    		}
    	}
    }
    Code:
    private void drawPlayers(final boolean flag) {
    	if (Client.myPlayer.x >> 7 == destX && Client.myPlayer.y >> 7 == destY) {
    		destX = 0;
    	}
    	int j = playerCount;
    	if (flag) {
    		j = 1;
    	}
    	for (int l = 0; l < j; l++) {
    		Player player;
    		int i1;
    		if (flag) {
    			player = Client.myPlayer;
    			i1 = myPlayerIndex << 14;
    		} else {
    			player = playerArray[playerIndices[l]];
    			i1 = playerIndices[l] << 14;
    		}
    		if (player == null || !player.isVisible()) {
    			continue;
    		}
    		player.ignoreSequences = (Client.lowMem && playerCount > 50 || playerCount > 200) && !flag
    				&& player.moveSequence == player.standAnimation;
    		final int j1 = player.x >> 7;
    			final int k1 = player.y >> 7;
    		if (j1 < 0 || j1 >= 104 || k1 < 0 || k1 >= 104) {
    			continue;
    		}
    		if (player.objectModel != null && Client.loopCycle >= player.objectStartCycle
    				&& Client.loopCycle < player.objectEndCycle) {
    			player.ignoreSequences = false;
    			if (Configuration.MULTILEVEL_RENDER) {
    				player.z = method42(player.heightLevel, player.y, player.x);
    				worldController.add(player.heightLevel, player.y, player, player.yaw, player.objectY1, player.x, player.z,
    						player.objectX0, player.objectY0, i1, player.objectX1);
    			} else {
    				player.z = method42(plane, player.y, player.x);
    				worldController.add(plane, player.y, player, player.yaw, player.objectY1, player.x, player.z,
    						player.objectX0, player.objectY0, i1, player.objectX1);
    			}
    			continue;
    		}
    		if ((player.x & 0x7f) == 64 && (player.y & 0x7f) == 64) {
    			if (anIntArrayArray929[j1][k1] == anInt1265) {
    				if (Configuration.MULTILEVEL_RENDER && player.heightLevel == myPlayer.heightLevel) {
    					continue;
    				}
    			}
    			anIntArrayArray929[j1][k1] = anInt1265;
    		}
    		if (Configuration.MULTILEVEL_RENDER) {
    			player.z = method42(player.heightLevel, player.y, player.x);
    			worldController.add(player.heightLevel, player.yaw, player.z, i1, player.y, 60, player.x, player, player.canRotate);
    		} else {
    			player.z = method42(plane, player.y, player.x);
    			worldController.add(plane, player.yaw, player.z, i1, player.y, 60, player.x, player, player.canRotate);
    		}
    	}
    }
    Code:
    private void entityScreenPos(final Entity entity, final int i) {
    	calcEntityScreenPos(entity.x, i, entity.y, Configuration.MULTILEVEL_RENDER ? entity.heightLevel : plane);
    }
    In your Entity.java add
    Code:
    public int heightLevel;
    And one last packet change to get player height level
    Code:
    private void method117(final Stream stream) {
    	stream.initBitAccess();
    	final int j = stream.readBits(1);
    	if (j == 0) {
    		return;
    	}
    	final int k = stream.readBits(2);
    	if (k == 0) {
    		anIntArray894[anInt893++] = myPlayerIndex;
    		return;
    	}
    	if (k == 1) {
    		final int l = stream.readBits(3);
    		Client.myPlayer.moveInDir(false, l);
    		final int k1 = stream.readBits(1);
    		if (k1 == 1) {
    			anIntArray894[anInt893++] = myPlayerIndex;
    		}
    		return;
    	}
    	if (k == 2) {
    		final int i1 = stream.readBits(3);
    		Client.myPlayer.moveInDir(true, i1);
    		final int l1 = stream.readBits(3);
    		Client.myPlayer.moveInDir(true, l1);
    		final int j2 = stream.readBits(1);
    		if (j2 == 1) {
    			anIntArray894[anInt893++] = myPlayerIndex;
    		}
    		return;
    	}
    	if (k == 3) {
    		plane = stream.readBits(2);
    		if (Configuration.MULTILEVEL_RENDER) {
    			Client.myPlayer.heightLevel = plane;
    		}
    		final int j1 = stream.readBits(1);
    		final int i2 = stream.readBits(1);
    		if (i2 == 1) {
    			anIntArray894[anInt893++] = myPlayerIndex;
    		}
    		final int k2 = stream.readBits(7);
    		final int l2 = stream.readBits(7);
    		Client.myPlayer.setEntityPos(l2, k2, j1 == 1);
    	}
    }
    In your Entity.java add


    Server Side
    Next up is the server side code this will be different dependng on the server you are using, but it should be easy to figure out where to put this stuff.
    This is for my own server use at your own risk.

    Same as before make a boolean to toggle multi-level rendering
    Code:
    public static boolean multiLevelRender = true;
    This is in my Configuration.java on the server side

    In your Entity.java
    Code:
    public boolean distanceToEntity(final Entity anEntity, final int distance) {
    	if (!Configuration.multiLevelRender) {
    		if (height != anEntity.getHeight()) {
    			return false;
    		}
    	}
    	if (anEntity.size > 1) {
    		for (int i = 0; i < (anEntity.size - 1); i++) {
    			final int top = (int) Math.sqrt(Math.pow((coordX - anEntity.getX()) + i, 2)
    					+ Math.pow((coordY - anEntity.getY()) + (anEntity.size - 1), 2));
    			final int bottom = (int) Math
    					.sqrt(Math.pow((coordX - anEntity.getX()) + i, 2) + Math.pow(coordY - anEntity.getY(), 2));
    			final int right = (int) Math
    					.sqrt(Math.pow(coordX - anEntity.getX(), 2) + Math.pow((coordY - anEntity.getY()) + i, 2));
    			final int left = (int) Math.sqrt(Math.pow((coordX - anEntity.getX()) + (anEntity.size - 1), 2)
    					+ Math.pow((coordY - anEntity.getY()) + i, 2));
    			if ((top <= distance) || (bottom <= distance) || (right <= distance) || (left <= bottom)) {
    				return true;
    			}
    		}
    	} else {
    		final int check = (int) Math
    				.sqrt(Math.pow(coordX - anEntity.getX(), 2) + Math.pow(coordY - anEntity.getY(), 2));
    		if (check <= distance) {
    			return true;
    		}
    	}
    	return false;
    }
    In your PlayerUpdate.java or whereever you have the code to update your player's client
    Code:
    public static void addNewMob(final Player player, final Mob mob, final Stream stream, final Stream updateBlock) {
    	synchronized (player) {
    		player.getMobInListBitmap()[mob.getEntityId() >> 3] |= 1 << (mob.getEntityId() & 7);
    		player.mobList[player.mobListSize++] = mob;
    		stream.writeBits(14, mob.getEntityId());
    		int z = mob.getY() - player.getY();
    		if (z < 0) {
    			z += 32;
    		}
    		stream.writeBits(5, z);
    		z = mob.getX() - player.getX();
    		if (z < 0) {
    			z += 32;
    		}
    		stream.writeBits(5, z);
    		if (Configuration.multiLevelRender) {
    			stream.writeBits(5, mob.getHeight());
    		}
    		stream.writeBits(1, 0);
    		stream.writeBits(12, mob.getMobType());
    		final boolean savedFlag = mob.getAppearanceUpdate();
    		final boolean savedUpdateRequired = mob.getUpdate();
    		mob.setAppearanceUpdate(true);
    		mob.setUpdate(true);
    		MobUpdate.appendMobUpdateBlock(mob, updateBlock);
    		mob.setAppearanceUpdate(savedFlag);
    		mob.setUpdate(savedUpdateRequired);
    		stream.writeBits(1, 1);
    	}
    }
    
    public static void addNewPlayer(final Player self, final Player player, final Stream stream,
    		final Stream updateBlock) {
    	synchronized (self) {
    		if (self.playerListSize >= 79) {
    			return;
    		}
    		final int id = player.getEntityId();
    		self.playerInListBitmap[id >> 3] |= 1 << (id & 7);
    		self.playerList[self.playerListSize++] = player;
    		stream.writeBits(11, id);
    		stream.writeBits(1, 1);
    		final boolean savedFlag = player.getAppearanceUpdate();
    		final boolean savedUpdateRequired = player.getUpdate();
    		player.setAppearanceUpdate(true);
    		player.setUpdate(true);
    		PlayerUpdate.appendPlayerUpdateBlock(player, updateBlock);
    		player.setAppearanceUpdate(savedFlag);
    		player.setUpdate(savedUpdateRequired);
    		stream.writeBits(1, 1);
    		int z = player.getY() - self.getY();
    		if (z < 0) {
    			z += 32;
    		}
    		stream.writeBits(5, z);
    		z = player.getX() - self.getX();
    		if (z < 0) {
    			z += 32;
    		}
    		stream.writeBits(5, z);
    		if (Configuration.multiLevelRender) {
    			stream.writeBits(5, player.getHeight());
    		}
    	}
    }
    Reply With Quote  
     

  2. #2  
    Community Veteran

    Dust R I P's Avatar
    Join Date
    Jan 2008
    Posts
    2,599
    Thanks given
    197
    Thanks received
    221
    Rep Power
    586
    Cool idea!
    Reply With Quote  
     

  3. Thankful user:


  4. #3  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    The code is more than just questionable, let's be honest.
    Code:
    if (self.playerListSize >= 79) {
    	return;
    }
    Any particular reason why you're only permitting 79 players to be shown at any time? This shouldn't be capped at all; if you're in a crowded area, someone that's not visible in your viewport could attack you and you'd be able to do nothing but "auto retaliate" since you cannot see them, nor interact with them on-demand.

    Code:
    stream.writeBits(5, player.getHeight());
    I guess you just copied this one, but it is unnecessary to allocate 5 bits under the height. Height can only vary from 0-3, meaning a total of just 2 bits is required to transmit the value.

    The idea itself isn't bad, it's been done plenty before too of course. RS doesn't do this themselves for which I assume would be two reasons - there's no need to, you wouldn't be able to interact with someone on another plane; and it would put potentially a lot more pressure on the process, since you could be displaying 4(all height levels could be crowded) crowded areas as opposed to just one.
    Attached image
    Reply With Quote  
     

  5. #4  
    Registered Member Tatsuya's Avatar
    Join Date
    Dec 2011
    Posts
    335
    Thanks given
    74
    Thanks received
    52
    Rep Power
    61
    Quote Originally Posted by Kris View Post
    The code is more than just questionable, let's be honest.
    Code:
    if (self.playerListSize >= 79) {
    	return;
    }
    For player limit, as you know the 317 client is fully software rendered, meaning it's only your CPU. I know that's is 2018, but let's be real the software rendering isn't the best. If it was GPU accelerated then I would increase the cap, but realistically it couldn't be unlimited unless you had unlimited resources.
    If you are so worried about the limit in pvp situations this could easily be programmed around by prioritizing the enemy entity when attacked, or just giving priority to players/npcs within a certain area around the player ie 5 squares.

    For height bits you are right, it wouldn't need 5, this was made years ago, and I don't care enough about RSPS to do anything about it.

    I would also like to point out that it is possible to interact with entities on different height levels. With the current version you can see things other players say. I also made it so the right-click menu is disabled but if you wanted to you could enable it to allow for multi level fighting via magic/ranged, or even 2-handed weapons such as haliberds, spears, hasta's, etc. But that'd be something you'd need to figure out yourself.
    Reply With Quote  
     

  6. #5  
    Banned

    Join Date
    Jul 2018
    Posts
    121
    Thanks given
    82
    Thanks received
    55
    Rep Power
    0
    thanks very much I'm gonna improve on what I did

    Quote Originally Posted by Tatsuya View Post
    For player limit, as you know the 317 client is fully software rendered, meaning it's only your CPU. I know that's is 2018, but let's be real the software rendering isn't the best. If it was GPU accelerated then I would increase the cap, but realistically it couldn't be unlimited unless you had unlimited resources.
    If you are so worried about the limit in pvp situations this could easily be programmed around by prioritizing the enemy entity when attacked, or just giving priority to players/npcs within a certain area around the player ie 5 squares.

    For height bits you are right, it wouldn't need 5, this was made years ago, and I don't care enough about RSPS to do anything about it.

    I would also like to point out that it is possible to interact with entities on different height levels. With the current version you can see things other players say. I also made it so the right-click menu is disabled but if you wanted to you could enable it to allow for multi level fighting via magic/ranged, or even 2-handed weapons such as haliberds, spears, hasta's, etc. But that'd be something you'd need to figure out yourself.
    Dunno if you are missing this out on purpose but in
    Code:
    calcEntityScreenPos

    You have
    Code:
    int i1 = getCenterHeight(plane, l, i) - j;
    are you supposed to be passing something where the plane is because I just tried it in a different client and its not working just won't show the NPC / player

    Edit: Yes they was just need to get them to show now on multi lvls as this seems to not be working for me
    Reply With Quote  
     

  7. #6  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    Quote Originally Posted by Tatsuya View Post
    For player limit, as you know the 317 client is fully software rendered, meaning it's only your CPU. I know that's is 2018, but let's be real the software rendering isn't the best. If it was GPU accelerated then I would increase the cap, but realistically it couldn't be unlimited unless you had unlimited resources.
    If you are so worried about the limit in pvp situations this could easily be programmed around by prioritizing the enemy entity when attacked, or just giving priority to players/npcs within a certain area around the player ie 5 squares.
    The 317 client was software-rendered back in 2005 too. It still didn't have a cap on RS back then. OSRS is currently software rendered too, still no cap. That's no excuse.

    Quote Originally Posted by Tatsuya View Post
    I don't care enough about RSPS to do anything about it.
    If you don't care about it, why bother posting? That's the dumbest - and actually one of the most common - excuses I've heard around these forums. Just a shit excuse for your shit code is all it is, man up and acknowledge it.
    Attached image
    Reply With Quote  
     

  8. Thankful users:


  9. #7  
    Registered Member Tatsuya's Avatar
    Join Date
    Dec 2011
    Posts
    335
    Thanks given
    74
    Thanks received
    52
    Rep Power
    61
    Quote Originally Posted by Kris View Post
    The 317 client was software-rendered back in 2005 too. It still didn't have a cap on RS back then. OSRS is currently software rendered too, still no cap. That's no excuse.


    If you don't care about it, why bother posting? That's the dumbest - and actually one of the most common - excuses I've heard around these forums. Just a shit excuse for your shit code is all it is, man up and acknowledge it.
    You're joking right? I mean you have to be. Every game has limited on what it shows. RuneScape and OSRS are no exception. If you want proof go to a populated area such as the GE on a populated world. If I'm wrong and there is no limit then please explain the players and familiars/pets disappearing. I am genuinely curious as to why they'd disappear if there is no limit, given entities are the amongst the most expensive things to render.

    Quote Originally Posted by Zac343 View Post
    thanks very much I'm gonna improve on what I did



    Dunno if you are missing this out on purpose but in
    Code:
    calcEntityScreenPos

    You have
    Code:
    int i1 = getCenterHeight(plane, l, i) - j;
    are you supposed to be passing something where the plane is because I just tried it in a different client and its not working just won't show the NPC / player

    Edit: Yes they was just need to get them to show now on multi lvls as this seems to not be working for me
    You are right. I am more than willing to admit when I'm wrong and this is no exception. You need to make a variable for heightlevel in your entity classes, then using that in place of plane for some methods. I will update this when I get the chance.
    Reply With Quote  
     

  10. #8  
    Banned

    Join Date
    Jul 2018
    Posts
    121
    Thanks given
    82
    Thanks received
    55
    Rep Power
    0
    Quote Originally Posted by Tatsuya View Post
    You're joking right? I mean you have to be. Every game has limited on what it shows. RuneScape and OSRS are no exception. If you want proof go to a populated area such as the GE on a populated world. If I'm wrong and there is no limit then please explain the players and familiars/pets disappearing. I am genuinely curious as to why they'd disappear if there is no limit, given entities are the amongst the most expensive things to render.



    You are right. I am more than willing to admit when I'm wrong and this is no exception. You need to make a variable for heightlevel in your entity classes, then using that in place of plane for some methods. I will update this when I get the chance.
    Ye what i did still was having issues hahaha

    Code:
    private void calcEntityScreenPos(int i, int j, int l,int height) {
    		if (i < 128 || l < 128 || i > 13056 || l > 13056) {
    			spriteDrawX = -1;
    			spriteDrawY = -1;
    			return;
    		}
    		int i1 = getCenterHeight(height, l, i) - j;
    		i -= xCameraPos;
    		i1 -= zCameraPos;
    		l -= yCameraPos;
    		int j1 = Model.SINE[yCameraCurve];
    		int k1 = Model.COSINE[yCameraCurve];
    		int l1 = Model.SINE[xCameraCurve];
    		int i2 = Model.COSINE[xCameraCurve];
    		int j2 = l * l1 + i * i2 >> 16;
    		l = l * i2 - i * l1 >> 16;
    		i = j2;
    		j2 = i1 * k1 - l * j1 >> 16;
    		l = i1 * j1 + l * k1 >> 16;
    		i1 = j2;
    		if (l >= 50) {
    			spriteDrawX = Rasterizer3D.originViewX + (i << SceneGraph.viewDistance) / l;
    			spriteDrawY = Rasterizer3D.originViewY + (i1 << SceneGraph.viewDistance) / l;
    		} else {
    			spriteDrawX = -1;
    			spriteDrawY = -1;
    		}
    	}
    <-- What i did

    dunno what else i'm mising or maybe you are but nothing shows diffrent for me
    Reply With Quote  
     

  11. #9  
    Community Veteran


    Arch337's Avatar
    Join Date
    Sep 2008
    Posts
    2,950
    Thanks given
    210
    Thanks received
    349
    Rep Power
    1376
    Quote Originally Posted by Tatsuya View Post
    You're joking right? I mean you have to be. Every game has limited on what it shows. RuneScape and OSRS are no exception. If you want proof go to a populated area such as the GE on a populated world. If I'm wrong and there is no limit then please explain the players and familiars/pets disappearing. I am genuinely curious as to why they'd disappear if there is no limit, given entities are the amongst the most expensive things to render.
    Osrs did this to grand exchange cause they know there will be alot of people along with grand exchange calculations in the area.
    If you look on the
    of deadman mode, you can see there is alot of people loaded in and not restricted like in the grand exchange area.


    "A fail act is something you do regular, but a dumb act is something you can learn from"
    Spoiler for Problem?:
    Reply With Quote  
     

  12. #10  
    Registered Member Tatsuya's Avatar
    Join Date
    Dec 2011
    Posts
    335
    Thanks given
    74
    Thanks received
    52
    Rep Power
    61
    Quote Originally Posted by arch337 View Post
    Osrs did this to grand exchange cause they know there will be alot of people along with grand exchange calculations in the area.
    If you look on the
    of deadman mode, you can see there is alot of people loaded in and not restricted like in the grand exchange area.
    Yes but that's in a PvP situation. As I said earlier you could prioritize this in those situations. The real problem here is the derailing of this thread due to a player's shown limit, which should not have any real discussion on this thread about adding the ability for your client and server to show entities on different levels as it is not the topic. If it is so important than you can remove it, it doens't matter to me. I'm just trying to get more attention for multi-level rendering in the hopes of it being implemented in the actual game (RuneScape, and OSRS).

    Side note in the video there does appear to be a limit as the players are in a very square shape. This is typical of the RuneScape method for limiting the amount of players shown. Also the limit is not restricted to the GE, it is in most of the game world to my knowledge, this can be seen when a very popular player walks around with people following them. Once again if I am wrong feel free to correct me, but please focus on the topic at hand, which is adding multi-level rendering.

    Quote Originally Posted by Zac343 View Post
    Ye what i did still was having issues hahaha

    Code:
    private void calcEntityScreenPos(int i, int j, int l,int height) {
    		if (i < 128 || l < 128 || i > 13056 || l > 13056) {
    			spriteDrawX = -1;
    			spriteDrawY = -1;
    			return;
    		}
    		int i1 = getCenterHeight(height, l, i) - j;
    		i -= xCameraPos;
    		i1 -= zCameraPos;
    		l -= yCameraPos;
    		int j1 = Model.SINE[yCameraCurve];
    		int k1 = Model.COSINE[yCameraCurve];
    		int l1 = Model.SINE[xCameraCurve];
    		int i2 = Model.COSINE[xCameraCurve];
    		int j2 = l * l1 + i * i2 >> 16;
    		l = l * i2 - i * l1 >> 16;
    		i = j2;
    		j2 = i1 * k1 - l * j1 >> 16;
    		l = i1 * j1 + l * k1 >> 16;
    		i1 = j2;
    		if (l >= 50) {
    			spriteDrawX = Rasterizer3D.originViewX + (i << SceneGraph.viewDistance) / l;
    			spriteDrawY = Rasterizer3D.originViewY + (i1 << SceneGraph.viewDistance) / l;
    		} else {
    			spriteDrawX = -1;
    			spriteDrawY = -1;
    		}
    	}
    <-- What i did

    dunno what else i'm mising or maybe you are but nothing shows diffrent for me
    I do not edit my calcEntityScreenPos method only the entityScreenPos method is changed as shown below.
    Code:
    private void entityScreenPos(final Entity entity, final int i) {
    	calcEntityScreenPos(entity.x, i, entity.y, Configuration.MULTILEVEL_RENDER ? entity.heightLevel : plane);
    }
    Are you sure the heightlevel of the entity is being passed to the calcEntityScreenPos method?
    Reply With Quote  
     

Page 1 of 2 12 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. Replies: 21
    Last Post: 08-03-2013, 01:55 AM
  2. Replies: 11
    Last Post: 09-27-2010, 04:09 AM
  3. Replies: 24
    Last Post: 04-26-2010, 07:39 AM
  4. Replies: 1
    Last Post: 04-03-2010, 07:51 AM
  5. Multi height levels
    By Colby in forum RS2 Client
    Replies: 26
    Last Post: 10-22-2009, 12:48 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
  •