mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-23 19:35:10 -06:00
Critical fixes that fix all the current problems: no flashing POHs, no duplicate items, no missing items when transitioning >3 chunks, no accidental goddamn game protocol changes
This commit is contained in:
parent
4eeda96ff2
commit
a22fd8185f
3 changed files with 26 additions and 21 deletions
|
|
@ -545,11 +545,6 @@ public class Player extends Entity {
|
|||
super.update();
|
||||
if (playerFlags.isUpdateSceneGraph()) {
|
||||
updateSceneGraph(false);
|
||||
// The scene graph rebuild wipes the client's build area. Reset lastViewport so MapChunkRenderer
|
||||
// re-synchronizes every visible chunk this tick (restoring scenery immediately and re-sending
|
||||
// each ground item exactly once), rather than only sending incremental updates for overlap.
|
||||
// This fixes POHs flashing their cached states (hotspots) on z transition.
|
||||
playerFlags.setLastViewport(new RegionChunk[13][13]);
|
||||
}
|
||||
PlayerRenderer.render(this);
|
||||
NPCRenderer.render(this);
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ public class RegionChunk {
|
|||
* @param item The item.
|
||||
*/
|
||||
public void add(GroundItem item) {
|
||||
items.add(item);
|
||||
getItems().add(item);
|
||||
if (item.isPrivate()) {
|
||||
if (item.getDropper() != null) {
|
||||
PacketRepository.send(ConstructGroundItem.class, new BuildItemContext(item.getDropper(), item));
|
||||
|
|
@ -404,12 +404,15 @@ public class RegionChunk {
|
|||
}
|
||||
}
|
||||
}
|
||||
ArrayList<GroundItem> totalItems = drawItems(items, player);
|
||||
for (GroundItem item : totalItems) {
|
||||
if (item != null && item.isActive() && item.getLocation() != null) {
|
||||
if (!item.isPrivate() || item.droppedBy(player)) {
|
||||
ConstructGroundItem.write(buffer, item);
|
||||
updated = true;
|
||||
// Dynamic regions (POHs etc.) deliver items once via add(GroundItem) and the client retains them across scene rebuilds;
|
||||
// re-sending here would duplicate them (the client doesn't de-dup). Static regions still need it for chunks entering view.
|
||||
if (!(getRegion() instanceof DynamicRegion)) {
|
||||
ArrayList<GroundItem> totalItems = drawItems(items, player);
|
||||
for (GroundItem item : totalItems) {
|
||||
if (item != null && item.isActive() && item.getLocation() != null) {
|
||||
if (!item.isPrivate() || item.droppedBy(player)) {
|
||||
ConstructGroundItem.write(buffer, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package core.game.world.update
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionChunk
|
||||
import core.game.world.map.build.DynamicRegion
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.ClearChunkContext
|
||||
import core.net.packet.out.ClearRegionChunk
|
||||
|
|
@ -13,21 +14,23 @@ import java.util.*
|
|||
*/
|
||||
object MapChunkRenderer {
|
||||
const val buildAreaDepth = 6
|
||||
|
||||
/**
|
||||
* Sends the map chunk rendering packet.
|
||||
* @param player The player.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun render(player: Player) {
|
||||
val last = player.playerFlags.lastViewport
|
||||
val updated: MutableList<RegionChunk> = ArrayList()
|
||||
val current: MutableList<MutableList<RegionChunk>> = ArrayList()
|
||||
|
||||
// Center the build area on the loaded scene anchor (lastSceneGraph), NOT the live player position.
|
||||
// The client's 13x13 build area is anchored at lastSceneGraph; addressing chunks relative to it keeps
|
||||
// every chunk packet inside the client's scene window even when the player has drifted up to 3 chunks
|
||||
// from the anchor (the scene graph only rebuilds at a drift of 4). Using player.location here instead
|
||||
// pushes the viewport edge to drift+6 chunks from the anchor, off-window, so edge items never render.
|
||||
val anchor = player.playerFlags.lastSceneGraph ?: player.location
|
||||
val center = Location.create(anchor.x, anchor.y, player.location.z)
|
||||
for (dcx in -buildAreaDepth..+buildAreaDepth) {
|
||||
val addX = ArrayList<RegionChunk>()
|
||||
for (dcy in -buildAreaDepth..+buildAreaDepth) {
|
||||
val newloc = player.location.transform(dcx*8, dcy*8, 0)
|
||||
val newloc = center.transform(dcx * 8, dcy * 8, 0)
|
||||
addX.add(newloc.chunk)
|
||||
}
|
||||
current.add(addX)
|
||||
|
|
@ -40,11 +43,15 @@ object MapChunkRenderer {
|
|||
val previous = last[x][y] ?: continue
|
||||
if (containsChunk(current, previous)) {
|
||||
updated.add(previous)
|
||||
} else {
|
||||
PacketRepository.send(ClearRegionChunk::class.java, ClearChunkContext(player, previous))
|
||||
continue
|
||||
}
|
||||
if (previous.region is DynamicRegion) {
|
||||
continue //dynamic regions do not need a clear packet and briefly flash their cached states (e.g. POH with only hotspots) if you do send one
|
||||
}
|
||||
PacketRepository.send(ClearRegionChunk::class.java, ClearChunkContext(player, previous))
|
||||
}
|
||||
}
|
||||
|
||||
sizeX = current.size
|
||||
for (x in 0 until sizeX) {
|
||||
val sizeY: Int = current[x].size
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue