From 08a9dc807f774557fd1fb4ba2d8f9a21d6923078 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Tue, 14 Sep 2021 23:10:20 +0200 Subject: [PATCH 1/3] Added the ability to add lights to equipment automatically Added the fire cape, infernal cape and their max cape variants to the new equipment lighting --- src/main/java/rs117/hd/HdPlugin.java | 26 ++++ src/main/java/rs117/hd/HdPluginConfig.java | 22 ++- .../rs117/hd/lighting/EquipmentLight.java | 69 ++++++++++ .../java/rs117/hd/lighting/LightManager.java | 125 ++++++++++++++++++ 4 files changed, 237 insertions(+), 5 deletions(-) create mode 100644 src/main/java/rs117/hd/lighting/EquipmentLight.java diff --git a/src/main/java/rs117/hd/HdPlugin.java b/src/main/java/rs117/hd/HdPlugin.java index a2ecd86bb..6f045f02e 100644 --- a/src/main/java/rs117/hd/HdPlugin.java +++ b/src/main/java/rs117/hd/HdPlugin.java @@ -94,6 +94,9 @@ import net.runelite.api.events.GroundObjectSpawned; import net.runelite.api.events.NpcDespawned; import net.runelite.api.events.NpcSpawned; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.api.events.PlayerSpawned; +import net.runelite.api.events.PlayerChanged; import net.runelite.api.events.ProjectileMoved; import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectDespawned; @@ -395,6 +398,7 @@ enum ComputeMode public boolean configTzhaarHD = true; public boolean configProjectileLights = true; public boolean configNpcLights = true; + public boolean configEquipmentLights = true; public boolean configShadowsEnabled = false; public boolean configExpandShadowDraw = false; @@ -413,6 +417,7 @@ protected void startUp() configTzhaarHD = config.tzhaarHD(); configProjectileLights = config.projectileLights(); configNpcLights = config.npcLights(); + configEquipmentLights = config.equipmentLights(); configShadowsEnabled = config.shadowsEnabled(); configExpandShadowDraw = config.expandShadowDraw(); @@ -2129,6 +2134,9 @@ public void onConfigChanged(ConfigChanged event) case "npcLights": configNpcLights = config.npcLights(); break; + case "equipmentLights": + configEquipmentLights = config.equipmentLights(); + break; case "expandShadowDraw": configExpandShadowDraw = config.expandShadowDraw(); break; @@ -2466,6 +2474,24 @@ public void onNpcDespawned(NpcDespawned npcDespawned) lightManager.removeNpcLight(npcDespawned); } + @Subscribe + public void onPlayerSpawned(PlayerSpawned playerSpawned) + { + lightManager.addEquipmentLight(playerSpawned.getPlayer()); + } + + @Subscribe + public void onPlayerDespawned(PlayerDespawned playerDespawned) + { + lightManager.removeEquipmentLight(playerDespawned); + } + + @Subscribe + public void onPlayerChanged(PlayerChanged playerChanged) + { + lightManager.equipmentLightChanged(playerChanged); + } + @Subscribe public void onGameObjectSpawned(GameObjectSpawned gameObjectSpawned) { diff --git a/src/main/java/rs117/hd/HdPluginConfig.java b/src/main/java/rs117/hd/HdPluginConfig.java index 0667c5b96..f7cd09a3b 100644 --- a/src/main/java/rs117/hd/HdPluginConfig.java +++ b/src/main/java/rs117/hd/HdPluginConfig.java @@ -234,11 +234,23 @@ default boolean npcLights() return true; } + @ConfigItem( + keyName = "equipmentLights", + name = "Equipment Lights", + description = "Adds dynamic lights to some equipment when equipped on a player.", + position = 104, + section = lightingSettings + ) + default boolean equipmentLights() + { + return true; + } + @ConfigItem( keyName = "atmosphericLighting", name = "Atmospheric Lighting", description = "Changes the color and brightness of full-scene lighting in certain areas.", - position = 104, + position = 105, section = lightingSettings ) default boolean atmosphericLighting() @@ -250,7 +262,7 @@ default boolean atmosphericLighting() keyName = "shadowsEnabled", name = "Shadows", description = "Enables fully-dynamic shadows.", - position = 105, + position = 106, section = lightingSettings ) default boolean shadowsEnabled() @@ -262,7 +274,7 @@ default boolean shadowsEnabled() keyName = "shadowResolution", name = "Shadow Resolution", description = "The resolution of the shadow maps. Higher resolutions result in sharper, higher quality shadows at the cost of performance.", - position = 106, + position = 107, section = lightingSettings ) default ShadowResolution shadowResolution() @@ -274,7 +286,7 @@ default ShadowResolution shadowResolution() keyName = "shadowDistance", name = "Shadow Distance", description = "The maximum draw distance of shadow maps. Shorter distances result in sharper, higher quality shadows.", - position = 107, + position = 108, section = lightingSettings ) default ShadowDistance shadowDistance() @@ -286,7 +298,7 @@ default ShadowDistance shadowDistance() keyName = "expandShadowDraw", name = "Expand Shadow Draw", description = "Reduces 'flickering' of shadows disappearing at screen edge by increasing geometry drawn at a cost of performance.", - position = 108, + position = 109, section = lightingSettings ) default boolean expandShadowDraw() diff --git a/src/main/java/rs117/hd/lighting/EquipmentLight.java b/src/main/java/rs117/hd/lighting/EquipmentLight.java new file mode 100644 index 000000000..96b13f209 --- /dev/null +++ b/src/main/java/rs117/hd/lighting/EquipmentLight.java @@ -0,0 +1,69 @@ +package rs117.hd.lighting; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.ItemID; +import static net.runelite.api.ItemID.*; +import rs117.hd.lighting.LightManager.LightType; +import rs117.hd.lighting.LightManager.Alignment; + +@AllArgsConstructor +@Getter +enum EquipmentLight +{ + FIRE_CAPE(75, Alignment.BACK, 135, 8f, rgb(198, 156, 74), LightType.PULSE, 2100, 10, ItemID.FIRE_CAPE, FIRE_CAPE_10566), + FIRE_MAX_CAPE(75, Alignment.BACK, 135, 8f, rgb(198, 156, 74), LightType.PULSE, 2100, 10, ItemID.FIRE_MAX_CAPE, FIRE_MAX_CAPE_21186), + INFERNAL_CAPE(75, Alignment.BACK, 135, 8f, rgb(133, 64, 0), LightType.PULSE, 2100, 10, ItemID.INFERNAL_CAPE, INFERNAL_CAPE_21297, INFERNAL_CAPE_23622), + INFERNAL_MAX_CAPE(75, Alignment.BACK, 135, 8f, rgb(133, 64, 0), LightType.PULSE, 2100, 10, ItemID.INFERNAL_MAX_CAPE, INFERNAL_MAX_CAPE_21285), + ; + + private final int[] id; + private final int height; + private final Alignment alignment; + private final int size; + private final float strength; + private final int rgb; + private final LightType lightType; + private final float duration; + private final float range; + + EquipmentLight(int height, Alignment alignment, int size, float strength, int rgb, LightType lightType, float duration, float range, int... ids) + { + this.height = height; + this.alignment = alignment; + this.size = size; + this.strength = strength; + this.rgb = rgb; + this.lightType = lightType; + this.duration = duration; + this.range = range; + this.id = ids; + } + + private static final Map LIGHTS; + + static + { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (EquipmentLight equipmentLight : values()) + { + for (int id : equipmentLight.id) + { + builder.put(id + 512, equipmentLight); + } + } + LIGHTS = builder.build(); + } + + static EquipmentLight find(int id) + { + return LIGHTS.get(id); + } + + private static int rgb(int r, int g, int b) + { + return (r << 16) | (g << 8) | b; + } +} \ No newline at end of file diff --git a/src/main/java/rs117/hd/lighting/LightManager.java b/src/main/java/rs117/hd/lighting/LightManager.java index bce61c7f6..f9dc8cbaa 100644 --- a/src/main/java/rs117/hd/lighting/LightManager.java +++ b/src/main/java/rs117/hd/lighting/LightManager.java @@ -31,6 +31,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.Arrays; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; @@ -52,9 +53,13 @@ import net.runelite.api.Tile; import net.runelite.api.TileObject; import net.runelite.api.WallObject; +import net.runelite.api.Player; +import net.runelite.api.PlayerComposition; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.NpcDespawned; +import net.runelite.api.events.PlayerChanged; +import net.runelite.api.events.PlayerDespawned; import rs117.hd.HdPlugin; import rs117.hd.HdPluginConfig; import rs117.hd.HDUtils; @@ -164,6 +169,8 @@ public static class Light public Projectile projectile = null; public NPC npc = null; public TileObject object = null; + public Player player = null; + public int equipmentId = -1; public Light(int worldX, int worldY, int plane, int height, Alignment alignment, int size, float strength, int[] color, LightType type, float duration, float range, int fadeInDuration) { @@ -295,6 +302,56 @@ public void update() } } + if (light.player != null) + { + if (!Arrays.stream(light.player.getPlayerComposition().getEquipmentIds()).anyMatch(id -> id == light.equipmentId)) + { + lightIterator.remove(); + continue; + } + + light.x = light.player.getLocalLocation().getX(); + light.y = light.player.getLocalLocation().getY(); + + int orientation = light.player.getOrientation(); + + if (orientation != -1 && light.alignment != Alignment.CENTER) + { + orientation += light.alignment.orientation; + orientation %= 2048; + + float sine = Perspective.SINE[orientation] / 65536f; + float cosine = Perspective.COSINE[orientation] / 65536f; + //cosine /= (float)light.localSizeX / (float)localSizeY; + + int offsetX = (int)(sine * Perspective.LOCAL_HALF_TILE_SIZE); + int offsetY = (int)(cosine * Perspective.LOCAL_HALF_TILE_SIZE); + + light.x += offsetX; + light.y += offsetY; + } + + int plane = light.player.getWorldLocation().getPlane(); + light.plane = plane; + + // Interpolate between tile heights based on specific scene coordinates. + float lerpX = (light.x % Perspective.LOCAL_TILE_SIZE) / (float) Perspective.LOCAL_TILE_SIZE; + float lerpY = (light.y % Perspective.LOCAL_TILE_SIZE) / (float) Perspective.LOCAL_TILE_SIZE; + int baseTileX = (int) Math.floor(light.x / (float) Perspective.LOCAL_TILE_SIZE); + int baseTileY = (int) Math.floor(light.y / (float) Perspective.LOCAL_TILE_SIZE); + float heightNorth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY + 1], client.getTileHeights()[plane][baseTileX + 1][baseTileY + 1], lerpX); + float heightSouth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY], client.getTileHeights()[plane][baseTileX + 1][baseTileY], lerpX); + float tileHeight = HDUtils.lerp(heightSouth, heightNorth, lerpY); + light.z = (int) tileHeight - 1 - light.height; + + light.visible = light.player.getModel() != null; + + if (!hdPlugin.configEquipmentLights) + { + light.visible = false; + } + } + if (light.type == LightType.FLICKER) { double change = Math.random() * 2 - 1.0f; @@ -490,6 +547,7 @@ public void loadSceneLights() } updateSceneNpcs(); + updateSceneEquipment(); } @@ -513,6 +571,15 @@ void updateSceneNpcs() } } + void updateSceneEquipment() + { + + for (Player player : client.getPlayers()) + { + addEquipmentLight(player); + + } + } public ArrayList getVisibleLights(int maxDistance, int maxLights) { @@ -614,6 +681,64 @@ public void removeNpcLight(NpcDespawned npcDespawned) sceneLights.removeIf(light -> light.npc == npcDespawned.getNpc()); } + public void addEquipmentLight(Player player) + { + PlayerComposition composition = player.getPlayerComposition(); + + for (int id : composition.getEquipmentIds()) + { + EquipmentLight equipmentLight = EquipmentLight.find(id); + if (equipmentLight == null) + { + continue; + } + + addEquipmentLight(id, player); + } + } + + public void addEquipmentLight(int id, Player player) + { + EquipmentLight equipmentLight = EquipmentLight.find(id); + if (equipmentLight == null) + { + return; + } + + // prevent duplicate lights being spawned for the same NPC + for (Light light : sceneLights) + { + if (light.player == player && light.equipmentId == id) + { + return; + } + } + + int rgb = equipmentLight.getRgb(); + int r = rgb >>> 16; + int g = (rgb >> 8) & 0xff; + int b = rgb & 0xff; + Light light = new Light(0, 0, -1, + equipmentLight.getHeight(), equipmentLight.getAlignment(), equipmentLight.getSize(), equipmentLight.getStrength(), new int[]{r, g, b}, equipmentLight.getLightType(), equipmentLight.getDuration(), equipmentLight.getRange(), 0); + light.player = player; + light.equipmentId = id; + light.visible = false; + + sceneLights.add(light); + } + + public void removeEquipmentLight(PlayerDespawned playerDespawned) + { + sceneLights.removeIf(light -> light.player == playerDespawned.getPlayer()); + } + + public void equipmentLightChanged(PlayerChanged playerChanged) + { + Player player = playerChanged.getPlayer(); + sceneLights.removeIf(light -> light.player == player && Arrays.stream(player.getPlayerComposition().getEquipmentIds()).anyMatch(id -> id == light.equipmentId)); + addEquipmentLight(player); + } + public void addObjectLight(TileObject tileObject, int plane) { addObjectLight(tileObject, plane, 1, 1, -1); From c023cbfd5b4923499ef568e008b5b6f5b30c0f01 Mon Sep 17 00:00:00 2001 From: 117 Date: Tue, 14 Sep 2021 23:25:15 -0400 Subject: [PATCH 2/3] add null check to player composition --- src/main/java/rs117/hd/lighting/LightManager.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/rs117/hd/lighting/LightManager.java b/src/main/java/rs117/hd/lighting/LightManager.java index f9dc8cbaa..a7fe0b782 100644 --- a/src/main/java/rs117/hd/lighting/LightManager.java +++ b/src/main/java/rs117/hd/lighting/LightManager.java @@ -685,15 +685,18 @@ public void addEquipmentLight(Player player) { PlayerComposition composition = player.getPlayerComposition(); - for (int id : composition.getEquipmentIds()) + if (composition != null) { - EquipmentLight equipmentLight = EquipmentLight.find(id); - if (equipmentLight == null) + for (int id : composition.getEquipmentIds()) { - continue; - } + EquipmentLight equipmentLight = EquipmentLight.find(id); + if (equipmentLight == null) + { + continue; + } - addEquipmentLight(id, player); + addEquipmentLight(id, player); + } } } From 3e63a32c3d8fe795e3e16c24b961f737a7e0fbdb Mon Sep 17 00:00:00 2001 From: 117 Date: Wed, 15 Sep 2021 19:17:16 -0400 Subject: [PATCH 3/3] added lit bug lantern; adjusted fire/infernal cape variants; bring lights closer to player; use interpolated player orientation; use annoying complicated logic to account for bridges when calculating tile height --- .../rs117/hd/lighting/EquipmentLight.java | 9 +- .../java/rs117/hd/lighting/LightManager.java | 91 +++++++++++++++++-- 2 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/main/java/rs117/hd/lighting/EquipmentLight.java b/src/main/java/rs117/hd/lighting/EquipmentLight.java index 96b13f209..69af0091d 100644 --- a/src/main/java/rs117/hd/lighting/EquipmentLight.java +++ b/src/main/java/rs117/hd/lighting/EquipmentLight.java @@ -13,10 +13,11 @@ @Getter enum EquipmentLight { - FIRE_CAPE(75, Alignment.BACK, 135, 8f, rgb(198, 156, 74), LightType.PULSE, 2100, 10, ItemID.FIRE_CAPE, FIRE_CAPE_10566), - FIRE_MAX_CAPE(75, Alignment.BACK, 135, 8f, rgb(198, 156, 74), LightType.PULSE, 2100, 10, ItemID.FIRE_MAX_CAPE, FIRE_MAX_CAPE_21186), - INFERNAL_CAPE(75, Alignment.BACK, 135, 8f, rgb(133, 64, 0), LightType.PULSE, 2100, 10, ItemID.INFERNAL_CAPE, INFERNAL_CAPE_21297, INFERNAL_CAPE_23622), - INFERNAL_MAX_CAPE(75, Alignment.BACK, 135, 8f, rgb(133, 64, 0), LightType.PULSE, 2100, 10, ItemID.INFERNAL_MAX_CAPE, INFERNAL_MAX_CAPE_21285), + FIRE_CAPE(90, Alignment.BACK, 150, 6f, rgb(220, 156, 74), LightType.PULSE, 4000, 8, ItemID.FIRE_CAPE, FIRE_CAPE_10566), + FIRE_MAX_CAPE(90, Alignment.BACK, 150, 6f, rgb(220, 156, 74), LightType.PULSE, 4000, 8, ItemID.FIRE_MAX_CAPE, FIRE_MAX_CAPE_21186), + INFERNAL_CAPE(90, Alignment.BACK, 150, 6f, rgb(133, 64, 0), LightType.PULSE, 4000, 8, ItemID.INFERNAL_CAPE, INFERNAL_CAPE_21297, INFERNAL_CAPE_23622), + INFERNAL_MAX_CAPE(90, Alignment.BACK, 150, 6f, rgb(133, 64, 0), LightType.PULSE, 4000, 8, ItemID.INFERNAL_MAX_CAPE, INFERNAL_MAX_CAPE_21285), + LIT_BUG_LANTERN(50, Alignment.LEFT, 250, 6f, rgb(255, 233, 138), LightType.FLICKER, 0, 10, ItemID.LIT_BUG_LANTERN), ; private final int[] id; diff --git a/src/main/java/rs117/hd/lighting/LightManager.java b/src/main/java/rs117/hd/lighting/LightManager.java index a7fe0b782..d8e3a82d1 100644 --- a/src/main/java/rs117/hd/lighting/LightManager.java +++ b/src/main/java/rs117/hd/lighting/LightManager.java @@ -284,9 +284,46 @@ public void update() float lerpY = (light.y % Perspective.LOCAL_TILE_SIZE) / (float) Perspective.LOCAL_TILE_SIZE; int baseTileX = (int) Math.floor(light.x / (float) Perspective.LOCAL_TILE_SIZE); int baseTileY = (int) Math.floor(light.y / (float) Perspective.LOCAL_TILE_SIZE); - float heightNorth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY + 1], client.getTileHeights()[plane][baseTileX + 1][baseTileY + 1], lerpX); - float heightSouth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY], client.getTileHeights()[plane][baseTileX + 1][baseTileY], lerpX); + boolean bridge = client.getScene().getTiles()[plane][baseTileX][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY].getBridge() != null; + boolean nBridge = client.getScene().getTiles()[plane][baseTileX][baseTileY + 1] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean eBridge = client.getScene().getTiles()[plane][baseTileX + 1][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean sBridge = client.getScene().getTiles()[plane][baseTileX][baseTileY - 1] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean wBridge = client.getScene().getTiles()[plane][baseTileX - 1][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + int nwPlane = plane; + int nePlane = plane; + int swPlane = plane; + int sePlane = plane; + if (bridge) + { + nwPlane = nePlane = swPlane = sePlane = plane + 1; + } + else + { + if (nBridge || wBridge) + { + nwPlane++; + } + if (nBridge || eBridge) + { + nePlane++; + } + if (sBridge || wBridge) + { + swPlane++; + } + if (sBridge || eBridge) + { + sePlane++; + } + } + float nwHeight = client.getTileHeights()[nwPlane][baseTileX][baseTileY + 1]; + float neHeight = client.getTileHeights()[nePlane][baseTileX + 1][baseTileY + 1]; + float swHeight = client.getTileHeights()[swPlane][baseTileX][baseTileY]; + float seHeight = client.getTileHeights()[sePlane][baseTileX + 1][baseTileY]; + float heightNorth = HDUtils.lerp(nwHeight, neHeight, lerpX); + float heightSouth = HDUtils.lerp(swHeight, seHeight, lerpX); float tileHeight = HDUtils.lerp(heightSouth, heightNorth, lerpY); + light.z = (int) tileHeight - 1 - light.height; light.visible = light.npc.getModel() != null; @@ -313,7 +350,7 @@ public void update() light.x = light.player.getLocalLocation().getX(); light.y = light.player.getLocalLocation().getY(); - int orientation = light.player.getOrientation(); + int orientation = light.player.getCurrentOrientation(); if (orientation != -1 && light.alignment != Alignment.CENTER) { @@ -324,8 +361,9 @@ public void update() float cosine = Perspective.COSINE[orientation] / 65536f; //cosine /= (float)light.localSizeX / (float)localSizeY; - int offsetX = (int)(sine * Perspective.LOCAL_HALF_TILE_SIZE); - int offsetY = (int)(cosine * Perspective.LOCAL_HALF_TILE_SIZE); + // multiply by 0.75 to keep lights a little closer to the player model + int offsetX = (int)(sine * Perspective.LOCAL_HALF_TILE_SIZE * 0.75f); + int offsetY = (int)(cosine * Perspective.LOCAL_HALF_TILE_SIZE * 0.75f); light.x += offsetX; light.y += offsetY; @@ -339,9 +377,46 @@ public void update() float lerpY = (light.y % Perspective.LOCAL_TILE_SIZE) / (float) Perspective.LOCAL_TILE_SIZE; int baseTileX = (int) Math.floor(light.x / (float) Perspective.LOCAL_TILE_SIZE); int baseTileY = (int) Math.floor(light.y / (float) Perspective.LOCAL_TILE_SIZE); - float heightNorth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY + 1], client.getTileHeights()[plane][baseTileX + 1][baseTileY + 1], lerpX); - float heightSouth = HDUtils.lerp(client.getTileHeights()[plane][baseTileX][baseTileY], client.getTileHeights()[plane][baseTileX + 1][baseTileY], lerpX); + boolean bridge = client.getScene().getTiles()[plane][baseTileX][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY].getBridge() != null; + boolean nBridge = client.getScene().getTiles()[plane][baseTileX][baseTileY + 1] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean eBridge = client.getScene().getTiles()[plane][baseTileX + 1][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean sBridge = client.getScene().getTiles()[plane][baseTileX][baseTileY - 1] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + boolean wBridge = client.getScene().getTiles()[plane][baseTileX - 1][baseTileY] != null && client.getScene().getTiles()[plane][baseTileX][baseTileY + 1].getBridge() != null; + int nwPlane = plane; + int nePlane = plane; + int swPlane = plane; + int sePlane = plane; + if (bridge) + { + nwPlane = nePlane = swPlane = sePlane = plane + 1; + } + else + { + if (nBridge || wBridge) + { + nwPlane++; + } + if (nBridge || eBridge) + { + nePlane++; + } + if (sBridge || wBridge) + { + swPlane++; + } + if (sBridge || eBridge) + { + sePlane++; + } + } + float nwHeight = client.getTileHeights()[nwPlane][baseTileX][baseTileY + 1]; + float neHeight = client.getTileHeights()[nePlane][baseTileX + 1][baseTileY + 1]; + float swHeight = client.getTileHeights()[swPlane][baseTileX][baseTileY]; + float seHeight = client.getTileHeights()[sePlane][baseTileX + 1][baseTileY]; + float heightNorth = HDUtils.lerp(nwHeight, neHeight, lerpX); + float heightSouth = HDUtils.lerp(swHeight, seHeight, lerpX); float tileHeight = HDUtils.lerp(heightSouth, heightNorth, lerpY); + light.z = (int) tileHeight - 1 - light.height; light.visible = light.player.getModel() != null; @@ -708,7 +783,7 @@ public void addEquipmentLight(int id, Player player) return; } - // prevent duplicate lights being spawned for the same NPC + // prevent duplicate lights being spawned for the same player for (Light light : sceneLights) { if (light.player == player && light.equipmentId == id)