mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2026-08-01 14:39:16 -06:00
Final commit
This commit is contained in:
parent
a7c7dea3c7
commit
d29dd6f1b7
10 changed files with 1070 additions and 100 deletions
|
|
@ -20,6 +20,10 @@ import static rt4.Player.plane;
|
||||||
* @author ceikry
|
* @author ceikry
|
||||||
*/
|
*/
|
||||||
public class API {
|
public class API {
|
||||||
|
public static final int TILE_FLAG_UNDER_ROOF = 0x4;
|
||||||
|
private static final int DEFAULT_ROOF_VISIBILITY_GROUP_LIMIT = 2;
|
||||||
|
private static RoofVisibilityHandler roofVisibilityHandler = null;
|
||||||
|
|
||||||
public static Runnable[] miniMenuCustomActions = new Runnable[10];
|
public static Runnable[] miniMenuCustomActions = new Runnable[10];
|
||||||
public static int customMiniMenuIndex = 0;
|
public static int customMiniMenuIndex = 0;
|
||||||
public static ArrayList<KeyAdapter> registeredKeyListeners = new ArrayList<>();
|
public static ArrayList<KeyAdapter> registeredKeyListeners = new ArrayList<>();
|
||||||
|
|
@ -246,6 +250,104 @@ public class API {
|
||||||
return client.gameState == 30;
|
return client.gameState == 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int[] GetMapFlagTile() {
|
||||||
|
if (LoginManager.mapFlagX == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new int[]{LoginManager.mapFlagX, LoginManager.mapFlagZ};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetRoofVisibilityHandler(RoofVisibilityHandler handler) {
|
||||||
|
roofVisibilityHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearRoofVisibilityHandler(RoofVisibilityHandler handler) {
|
||||||
|
if (roofVisibilityHandler == handler) {
|
||||||
|
roofVisibilityHandler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetRoofVisibilityGroupLimit() {
|
||||||
|
if (roofVisibilityHandler == null) {
|
||||||
|
return DEFAULT_ROOF_VISIBILITY_GROUP_LIMIT;
|
||||||
|
}
|
||||||
|
return Math.max(DEFAULT_ROOF_VISIBILITY_GROUP_LIMIT, roofVisibilityHandler.getGroupLimit());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean IsRoofVisibilityActive() {
|
||||||
|
return roofVisibilityHandler != null && roofVisibilityHandler.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableRoofVisibilityIfExpired() {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.disableIfExpired();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnsureRoofVisibilityBuffers() {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.ensureBuffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyRoofVisibilityRequests() {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.applyRequests();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean IsRoofVisibilityPicking() {
|
||||||
|
return roofVisibilityHandler != null && roofVisibilityHandler.isPicking();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetRoofVisibilityPickScreenX() {
|
||||||
|
return roofVisibilityHandler == null ? 0 : roofVisibilityHandler.getPickScreenX();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetRoofVisibilityPickScreenY() {
|
||||||
|
return roofVisibilityHandler == null ? 0 : roofVisibilityHandler.getPickScreenY();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ReportRoofVisibilityTile(int sceneX, int sceneZ, int plane) {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.reportTile(sceneX, sceneZ, plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean IsRoofVisibilityLocPickable(long key) {
|
||||||
|
return roofVisibilityHandler != null && roofVisibilityHandler.isLocPickable(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ReportRoofVisibilityLoc(long key, int plane) {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.reportLoc(key, plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BeginRoofVisibilityGroup(int group) {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.beginGroup(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddRoofVisibilityGroupTile(int group, int plane, int sceneX, int sceneZ) {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.addGroupTile(group, plane, sceneX, sceneZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetDestinationRoofTarget(int sceneX, int sceneZ) {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.setDestinationTarget(sceneX, sceneZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearDestinationRoofTarget() {
|
||||||
|
if (roofVisibilityHandler != null) {
|
||||||
|
roofVisibilityHandler.clearDestinationTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void StoreData(String key, Object value) {
|
public static void StoreData(String key, Object value) {
|
||||||
PluginRepository.pluginStorage.put(key, value);
|
PluginRepository.pluginStorage.put(key, value);
|
||||||
PluginRepository.pluginStorage.put("_keystoreDirty", true);
|
PluginRepository.pluginStorage.put("_keystoreDirty", true);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import org.openrs2.deob.annotation.OriginalArg;
|
||||||
import org.openrs2.deob.annotation.OriginalClass;
|
import org.openrs2.deob.annotation.OriginalClass;
|
||||||
import org.openrs2.deob.annotation.OriginalMember;
|
import org.openrs2.deob.annotation.OriginalMember;
|
||||||
import org.openrs2.deob.annotation.Pc;
|
import org.openrs2.deob.annotation.Pc;
|
||||||
|
import plugin.api.API;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
|
@ -972,7 +973,9 @@ public final class GlModel extends Model {
|
||||||
local161 = MathUtils.sin[arg0];
|
local161 = MathUtils.sin[arg0];
|
||||||
local163 = MathUtils.cos[arg0];
|
local163 = MathUtils.cos[arg0];
|
||||||
}
|
}
|
||||||
if (arg8 > 0L && RawModel.allowInput && local70 > 0) {
|
@Pc(165) boolean roofVisibilityLocPick = API.IsRoofVisibilityLocPickable(arg8);
|
||||||
|
@Pc(168) boolean miniMenuPick = arg8 > 0L;
|
||||||
|
if ((miniMenuPick || roofVisibilityLocPick) && RawModel.allowInput && local70 > 0) {
|
||||||
@Pc(187) int local187;
|
@Pc(187) int local187;
|
||||||
@Pc(191) int local191;
|
@Pc(191) int local191;
|
||||||
if (local84 > 0) {
|
if (local84 > 0) {
|
||||||
|
|
@ -1046,63 +1049,79 @@ public final class GlModel extends Model {
|
||||||
}
|
}
|
||||||
if (anInt3582 >= local187 && anInt3582 <= local191 && RawModel.anInt1053 >= local206 && RawModel.anInt1053 <= local210) {
|
if (anInt3582 >= local187 && anInt3582 <= local191 && RawModel.anInt1053 >= local206 && RawModel.anInt1053 <= local210) {
|
||||||
if (this.pickable) {
|
if (this.pickable) {
|
||||||
Model.aLongArray11[MiniMenu.anInt7++] = arg8;
|
if (miniMenuPick) {
|
||||||
} else {
|
Model.aLongArray11[MiniMenu.anInt7++] = arg8;
|
||||||
if (anIntArray468.length < this.anInt5296) {
|
|
||||||
anIntArray468 = new int[this.anInt5296];
|
|
||||||
anIntArray467 = new int[this.anInt5296];
|
|
||||||
}
|
}
|
||||||
local362 = 0;
|
if (roofVisibilityLocPick) {
|
||||||
label118:
|
API.ReportRoofVisibilityLoc(arg8, arg9);
|
||||||
while (true) {
|
}
|
||||||
if (local362 >= this.vertexCount) {
|
} else {
|
||||||
local362 = 0;
|
if (this.vertexX == null || this.vertexY == null || this.vertexZ == null || this.anIntArray462 == null || this.aShortArray81 == null) {
|
||||||
while (true) {
|
if (roofVisibilityLocPick) {
|
||||||
if (local362 >= this.triangleCount) {
|
API.ReportRoofVisibilityLoc(arg8, arg9);
|
||||||
break label118;
|
}
|
||||||
|
} else {
|
||||||
|
if (anIntArray468.length < this.anInt5296) {
|
||||||
|
anIntArray468 = new int[this.anInt5296];
|
||||||
|
anIntArray467 = new int[this.anInt5296];
|
||||||
|
}
|
||||||
|
local362 = 0;
|
||||||
|
label118:
|
||||||
|
while (true) {
|
||||||
|
if (local362 >= this.vertexCount) {
|
||||||
|
local362 = 0;
|
||||||
|
while (true) {
|
||||||
|
if (local362 >= this.triangleCount) {
|
||||||
|
break label118;
|
||||||
|
}
|
||||||
|
@Pc(698) short local698 = this.aShortArray77[local362];
|
||||||
|
@Pc(703) short local703 = this.aShortArray82[local362];
|
||||||
|
@Pc(708) short local708 = this.aShortArray83[local362];
|
||||||
|
if (this.method4118(anInt3582, RawModel.anInt1053, anIntArray467[local698], anIntArray467[local703], anIntArray467[local708], anIntArray468[local698], anIntArray468[local703], anIntArray468[local708])) {
|
||||||
|
if (miniMenuPick) {
|
||||||
|
Model.aLongArray11[MiniMenu.anInt7++] = arg8;
|
||||||
|
}
|
||||||
|
if (roofVisibilityLocPick) {
|
||||||
|
API.ReportRoofVisibilityLoc(arg8, arg9);
|
||||||
|
}
|
||||||
|
break label118;
|
||||||
|
}
|
||||||
|
local362++;
|
||||||
}
|
}
|
||||||
@Pc(698) short local698 = this.aShortArray77[local362];
|
|
||||||
@Pc(703) short local703 = this.aShortArray82[local362];
|
|
||||||
@Pc(708) short local708 = this.aShortArray83[local362];
|
|
||||||
if (this.method4118(anInt3582, RawModel.anInt1053, anIntArray467[local698], anIntArray467[local703], anIntArray467[local708], anIntArray468[local698], anIntArray468[local703], anIntArray468[local708])) {
|
|
||||||
Model.aLongArray11[MiniMenu.anInt7++] = arg8;
|
|
||||||
break label118;
|
|
||||||
}
|
|
||||||
local362++;
|
|
||||||
}
|
}
|
||||||
}
|
local369 = this.vertexX[local362];
|
||||||
local369 = this.vertexX[local362];
|
local373 = this.vertexY[local362];
|
||||||
local373 = this.vertexY[local362];
|
local377 = this.vertexZ[local362];
|
||||||
local377 = this.vertexZ[local362];
|
if (arg0 != 0) {
|
||||||
if (arg0 != 0) {
|
local389 = local377 * local161 + local369 * local163 >> 16;
|
||||||
local389 = local377 * local161 + local369 * local163 >> 16;
|
local377 = local377 * local163 - local369 * local161 >> 16;
|
||||||
local377 = local377 * local163 - local369 * local161 >> 16;
|
local369 = local389;
|
||||||
|
}
|
||||||
|
local369 += arg5;
|
||||||
|
local373 += arg6;
|
||||||
|
local377 += arg7;
|
||||||
|
local389 = local377 * arg3 + local369 * arg4 >> 16;
|
||||||
|
local377 = local377 * arg4 - local369 * arg3 >> 16;
|
||||||
local369 = local389;
|
local369 = local389;
|
||||||
}
|
local389 = local373 * arg2 - local377 * arg1 >> 16;
|
||||||
local369 += arg5;
|
local377 = local373 * arg1 + local377 * arg2 >> 16;
|
||||||
local373 += arg6;
|
if (local377 < 50) {
|
||||||
local377 += arg7;
|
|
||||||
local389 = local377 * arg3 + local369 * arg4 >> 16;
|
|
||||||
local377 = local377 * arg4 - local369 * arg3 >> 16;
|
|
||||||
local369 = local389;
|
|
||||||
local389 = local373 * arg2 - local377 * arg1 >> 16;
|
|
||||||
local377 = local373 * arg1 + local377 * arg2 >> 16;
|
|
||||||
if (local377 < 50) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
local465 = (local369 << 9) / local377;
|
|
||||||
local471 = (local389 << 9) / local377;
|
|
||||||
@Pc(652) int local652 = this.anIntArray462[local362];
|
|
||||||
@Pc(659) int local659 = this.anIntArray462[local362 + 1];
|
|
||||||
for (@Pc(661) int local661 = local652; local661 < local659; local661++) {
|
|
||||||
@Pc(671) int local671 = this.aShortArray81[local661] - 1;
|
|
||||||
if (local671 == -1) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
anIntArray468[local671] = local465;
|
local465 = (local369 << 9) / local377;
|
||||||
anIntArray467[local671] = local471;
|
local471 = (local389 << 9) / local377;
|
||||||
|
@Pc(652) int local652 = this.anIntArray462[local362];
|
||||||
|
@Pc(659) int local659 = this.anIntArray462[local362 + 1];
|
||||||
|
for (@Pc(661) int local661 = local652; local661 < local659; local661++) {
|
||||||
|
@Pc(671) int local671 = this.aShortArray81[local661] - 1;
|
||||||
|
if (local671 == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
anIntArray468[local671] = local465;
|
||||||
|
anIntArray467[local671] = local471;
|
||||||
|
}
|
||||||
|
local362++;
|
||||||
}
|
}
|
||||||
local362++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -606,11 +606,17 @@ public class MiniMenu {
|
||||||
}
|
}
|
||||||
if (actionCode == WALK_HERE) {
|
if (actionCode == WALK_HERE) {
|
||||||
if (local36 == 0) {
|
if (local36 == 0) {
|
||||||
|
if (API.IsRoofVisibilityActive()) {
|
||||||
|
API.ClearDestinationRoofTarget();
|
||||||
|
}
|
||||||
method3556(Player.plane, local15, local19);
|
method3556(Player.plane, local15, local19);
|
||||||
} else if (local36 == 1) {
|
} else if (local36 == 1) {
|
||||||
if (LoginManager.staffModLevel > 0 && Keyboard.pressedKeys[Keyboard.KEY_CTRL] && Keyboard.pressedKeys[Keyboard.KEY_SHIFT]) {
|
if (LoginManager.staffModLevel > 0 && Keyboard.pressedKeys[Keyboard.KEY_CTRL] && Keyboard.pressedKeys[Keyboard.KEY_SHIFT]) {
|
||||||
Cheat.teleport(Camera.originX + local15, Camera.originZ + local19, Player.plane);
|
Cheat.teleport(Camera.originX + local15, Camera.originZ + local19, Player.plane);
|
||||||
} else if (PathFinder.findPath(PlayerList.self.movementQueueZ[0], 0, 0, true, 0, local15, 0, 0, 1, local19, PlayerList.self.movementQueueX[0])) {
|
} else if (PathFinder.findPath(PlayerList.self.movementQueueZ[0], 0, 0, true, 0, local15, 0, 0, 1, local19, PlayerList.self.movementQueueX[0])) {
|
||||||
|
if (API.IsRoofVisibilityActive()) {
|
||||||
|
API.SetDestinationRoofTarget(local15, local19);
|
||||||
|
}
|
||||||
Protocol.outboundBuffer.p1(InterfaceList.anInt5);
|
Protocol.outboundBuffer.p1(InterfaceList.anInt5);
|
||||||
Protocol.outboundBuffer.p1(anInt2878);
|
Protocol.outboundBuffer.p1(anInt2878);
|
||||||
Protocol.outboundBuffer.p2((int) Camera.yawTarget);
|
Protocol.outboundBuffer.p2((int) Camera.yawTarget);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.jogamp.opengl.GL2;
|
||||||
import org.openrs2.deob.annotation.OriginalArg;
|
import org.openrs2.deob.annotation.OriginalArg;
|
||||||
import org.openrs2.deob.annotation.OriginalMember;
|
import org.openrs2.deob.annotation.OriginalMember;
|
||||||
import org.openrs2.deob.annotation.Pc;
|
import org.openrs2.deob.annotation.Pc;
|
||||||
|
import plugin.api.API;
|
||||||
|
|
||||||
public class SceneGraph {
|
public class SceneGraph {
|
||||||
|
|
||||||
|
|
@ -1744,7 +1745,7 @@ public class SceneGraph {
|
||||||
}
|
}
|
||||||
if (local153.plainTile == null) {
|
if (local153.plainTile == null) {
|
||||||
if (local153.shapedTile != null) {
|
if (local153.shapedTile != null) {
|
||||||
method2762(local153.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, method187(0, local18, local21));
|
method2762(local153.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, 0, method187(0, local18, local21));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
method2610(local153.plainTile, 0, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, method187(0, local18, local21));
|
method2610(local153.plainTile, 0, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, method187(0, local18, local21));
|
||||||
|
|
@ -1776,10 +1777,10 @@ public class SceneGraph {
|
||||||
if (local8.plainTile == null) {
|
if (local8.plainTile == null) {
|
||||||
if (local8.shapedTile != null) {
|
if (local8.shapedTile != null) {
|
||||||
if (method187(local27, local18, local21)) {
|
if (method187(local27, local18, local21)) {
|
||||||
method2762(local8.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, true);
|
method2762(local8.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, local27, true);
|
||||||
} else {
|
} else {
|
||||||
var24 = true;
|
var24 = true;
|
||||||
method2762(local8.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, false);
|
method2762(local8.shapedTile, anInt2886, anInt3038, anInt5205, anInt2222, local18, local21, local27, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (method187(local27, local18, local21)) {
|
} else if (method187(local27, local18, local21)) {
|
||||||
|
|
@ -3915,6 +3916,9 @@ public class SceneGraph {
|
||||||
MiniMenu.anInt1742 = arg6;
|
MiniMenu.anInt1742 = arg6;
|
||||||
MiniMenu.anInt2954 = arg7;
|
MiniMenu.anInt2954 = arg7;
|
||||||
}
|
}
|
||||||
|
if (API.IsRoofVisibilityPicking() && method583(API.GetRoofVisibilityPickScreenX() + Rasteriser.centerX, API.GetRoofVisibilityPickScreenY() + Rasteriser.centerY, local315, local331, local299, local307, local323, local291)) {
|
||||||
|
API.ReportRoofVisibilityTile(arg6, arg7, arg1);
|
||||||
|
}
|
||||||
if (!GlRenderer.enabled && !arg8) {
|
if (!GlRenderer.enabled && !arg8) {
|
||||||
Rasteriser.testX = local307 < 0 || local323 < 0 || local291 < 0 || local307 > Rasteriser.width || local323 > Rasteriser.width || local291 > Rasteriser.width;
|
Rasteriser.testX = local307 < 0 || local323 < 0 || local291 < 0 || local307 > Rasteriser.width || local323 > Rasteriser.width || local291 > Rasteriser.width;
|
||||||
if (arg0.anInt4869 == -1) {
|
if (arg0.anInt4869 == -1) {
|
||||||
|
|
@ -3938,6 +3942,9 @@ public class SceneGraph {
|
||||||
MiniMenu.anInt1742 = arg6;
|
MiniMenu.anInt1742 = arg6;
|
||||||
MiniMenu.anInt2954 = arg7;
|
MiniMenu.anInt2954 = arg7;
|
||||||
}
|
}
|
||||||
|
if (API.IsRoofVisibilityPicking() && method583(API.GetRoofVisibilityPickScreenX() + Rasteriser.centerX, API.GetRoofVisibilityPickScreenY() + Rasteriser.centerY, local283, local299, local331, local275, local291, local323)) {
|
||||||
|
API.ReportRoofVisibilityTile(arg6, arg7, arg1);
|
||||||
|
}
|
||||||
if (GlRenderer.enabled || arg8) {
|
if (GlRenderer.enabled || arg8) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4225,7 +4232,7 @@ public class SceneGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OriginalMember(owner = "client!lh", name = "a", descriptor = "(Lclient!fg;IIIIIIZ)V")
|
@OriginalMember(owner = "client!lh", name = "a", descriptor = "(Lclient!fg;IIIIIIZ)V")
|
||||||
public static void method2762(@OriginalArg(0) ShapedTile arg0, @OriginalArg(1) int arg1, @OriginalArg(2) int arg2, @OriginalArg(3) int arg3, @OriginalArg(4) int arg4, @OriginalArg(5) int arg5, @OriginalArg(6) int arg6, @OriginalArg(7) boolean arg7) {
|
public static void method2762(@OriginalArg(0) ShapedTile arg0, @OriginalArg(1) int arg1, @OriginalArg(2) int arg2, @OriginalArg(3) int arg3, @OriginalArg(4) int arg4, @OriginalArg(5) int arg5, @OriginalArg(6) int arg6, int arg7, @OriginalArg(7) boolean arg8) {
|
||||||
@Pc(3) int local3 = arg0.anIntArray168.length;
|
@Pc(3) int local3 = arg0.anIntArray168.length;
|
||||||
@Pc(5) int local5;
|
@Pc(5) int local5;
|
||||||
@Pc(15) int local15;
|
@Pc(15) int local15;
|
||||||
|
|
@ -4268,7 +4275,10 @@ public class SceneGraph {
|
||||||
MiniMenu.anInt1742 = arg5;
|
MiniMenu.anInt1742 = arg5;
|
||||||
MiniMenu.anInt2954 = arg6;
|
MiniMenu.anInt2954 = arg6;
|
||||||
}
|
}
|
||||||
if (!GlRenderer.enabled && !arg7) {
|
if (API.IsRoofVisibilityPicking() && method583(API.GetRoofVisibilityPickScreenX() + Rasteriser.centerX, API.GetRoofVisibilityPickScreenY() + Rasteriser.centerY, local156, local160, local164, local39, local148, local152)) {
|
||||||
|
API.ReportRoofVisibilityTile(arg5, arg6, arg7);
|
||||||
|
}
|
||||||
|
if (!GlRenderer.enabled && !arg8) {
|
||||||
Rasteriser.testX = local39 < 0 || local148 < 0 || local152 < 0 || local39 > Rasteriser.width || local148 > Rasteriser.width || local152 > Rasteriser.width;
|
Rasteriser.testX = local39 < 0 || local148 < 0 || local152 < 0 || local39 > Rasteriser.width || local148 > Rasteriser.width || local152 > Rasteriser.width;
|
||||||
if (arg0.anIntArray161 == null || arg0.anIntArray161[local5] == -1) {
|
if (arg0.anIntArray161 == null || arg0.anIntArray161[local5] == -1) {
|
||||||
if (arg0.anIntArray167[local5] != 12345678) {
|
if (arg0.anIntArray167[local5] != 12345678) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import org.openrs2.deob.annotation.OriginalArg;
|
||||||
import org.openrs2.deob.annotation.OriginalMember;
|
import org.openrs2.deob.annotation.OriginalMember;
|
||||||
import org.openrs2.deob.annotation.Pc;
|
import org.openrs2.deob.annotation.Pc;
|
||||||
import plugin.PluginRepository;
|
import plugin.PluginRepository;
|
||||||
|
import plugin.api.API;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
@ -116,15 +117,15 @@ public final class ScriptRunner {
|
||||||
@OriginalMember(owner = "client!vg", name = "c", descriptor = "Z")
|
@OriginalMember(owner = "client!vg", name = "c", descriptor = "Z")
|
||||||
public static boolean aBoolean299 = false;
|
public static boolean aBoolean299 = false;
|
||||||
@OriginalMember(owner = "client!lj", name = "z", descriptor = "[I")
|
@OriginalMember(owner = "client!lj", name = "z", descriptor = "[I")
|
||||||
public static int[] anIntArray338 = new int[2];
|
public static int[] anIntArray338 = new int[8];
|
||||||
@OriginalMember(owner = "client!vl", name = "i", descriptor = "[I")
|
@OriginalMember(owner = "client!vl", name = "i", descriptor = "[I")
|
||||||
public static int[] anIntArray518 = new int[2];
|
public static int[] anIntArray518 = new int[8];
|
||||||
@OriginalMember(owner = "client!tk", name = "K", descriptor = "[I")
|
@OriginalMember(owner = "client!tk", name = "K", descriptor = "[I")
|
||||||
public static int[] anIntArray476 = new int[2];
|
public static int[] anIntArray476 = new int[8];
|
||||||
@OriginalMember(owner = "client!e", name = "xc", descriptor = "[I")
|
@OriginalMember(owner = "client!e", name = "xc", descriptor = "[I")
|
||||||
public static int[] anIntArray134 = new int[2];
|
public static int[] anIntArray134 = new int[8];
|
||||||
@OriginalMember(owner = "client!ge", name = "k", descriptor = "[I")
|
@OriginalMember(owner = "client!ge", name = "k", descriptor = "[I")
|
||||||
public static int[] anIntArray205 = new int[2];
|
public static int[] anIntArray205 = new int[8];
|
||||||
@OriginalMember(owner = "client!nm", name = "W", descriptor = "Lclient!na;")
|
@OriginalMember(owner = "client!nm", name = "W", descriptor = "Lclient!na;")
|
||||||
public static JagString url;
|
public static JagString url;
|
||||||
@OriginalMember(owner = "client!bf", name = "B", descriptor = "I")
|
@OriginalMember(owner = "client!bf", name = "B", descriptor = "I")
|
||||||
|
|
@ -976,12 +977,16 @@ public final class ScriptRunner {
|
||||||
method2608();
|
method2608();
|
||||||
} else {
|
} else {
|
||||||
method960((byte) (anInt3325 - 4 & 0xFF));
|
method960((byte) (anInt3325 - 4 & 0xFF));
|
||||||
method3993(2);
|
method3993(API.GetRoofVisibilityGroupLimit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OriginalMember(owner = "client!tc", name = "a", descriptor = "(B)I")
|
@OriginalMember(owner = "client!tc", name = "a", descriptor = "(B)I")
|
||||||
public static int method4047() {
|
public static int method4047() {
|
||||||
|
return getBaseRoofMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getBaseRoofMode() {
|
||||||
if (neverRemoveRoofs) {
|
if (neverRemoveRoofs) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (SceneGraph.allLevelsAreVisible()) {
|
} else if (SceneGraph.allLevelsAreVisible()) {
|
||||||
|
|
@ -991,6 +996,11 @@ public final class ScriptRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean canUseSelectiveRoofHiding() {
|
||||||
|
return getBaseRoofMode() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@OriginalMember(owner = "client!ok", name = "a", descriptor = "(IIB)Lclient!ce;")
|
@OriginalMember(owner = "client!ok", name = "a", descriptor = "(IIB)Lclient!ce;")
|
||||||
public static SecondaryLinkedList method3333(@OriginalArg(0) int arg0, @OriginalArg(1) int arg1) {
|
public static SecondaryLinkedList method3333(@OriginalArg(0) int arg0, @OriginalArg(1) int arg1) {
|
||||||
@Pc(9) SecondaryLinkedList local9 = new SecondaryLinkedList();
|
@Pc(9) SecondaryLinkedList local9 = new SecondaryLinkedList();
|
||||||
|
|
@ -1042,18 +1052,31 @@ public final class ScriptRunner {
|
||||||
|
|
||||||
@OriginalMember(owner = "client!uj", name = "a", descriptor = "(BZII[[[Lclient!bj;I)Z")
|
@OriginalMember(owner = "client!uj", name = "a", descriptor = "(BZII[[[Lclient!bj;I)Z")
|
||||||
public static boolean method4348(@OriginalArg(1) boolean arg0, @OriginalArg(2) int arg1, @OriginalArg(3) int arg2, @OriginalArg(4) Tile[][][] arg3, @OriginalArg(5) int arg4) {
|
public static boolean method4348(@OriginalArg(1) boolean arg0, @OriginalArg(2) int arg1, @OriginalArg(3) int arg2, @OriginalArg(4) Tile[][][] arg3, @OriginalArg(5) int arg4) {
|
||||||
@Pc(14) byte local14 = arg0 ? 1 : (byte) (anInt3325 & 0xFF);
|
return method4348(arg0, arg1, arg2, arg3, arg4, Player.plane);
|
||||||
if (local14 == aByteArrayArrayArray15[Player.plane][arg1][arg2]) {
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean hideRoofAt(int sceneX, int sceneZ, int group, int plane) {
|
||||||
|
return method4348(false, sceneX, sceneZ, SceneGraph.tiles, group, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean method4348(boolean arg0, int arg1, int arg2, Tile[][][] arg3, int arg4, int plane) {
|
||||||
|
if (plane < 0 || plane >= 3) {
|
||||||
return false;
|
return false;
|
||||||
} else if ((SceneGraph.renderFlags[Player.plane][arg1][arg2] & 0x4) == 0) {
|
}
|
||||||
|
@Pc(14) byte local14 = arg0 ? 1 : (byte) (anInt3325 & 0xFF);
|
||||||
|
if (local14 == aByteArrayArrayArray15[plane][arg1][arg2]) {
|
||||||
|
return false;
|
||||||
|
} else if ((SceneGraph.renderFlags[plane][arg1][arg2] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
API.BeginRoofVisibilityGroup(arg4);
|
||||||
@Pc(47) int local47 = 0;
|
@Pc(47) int local47 = 0;
|
||||||
@Pc(49) byte local49 = 0;
|
@Pc(49) byte local49 = 0;
|
||||||
PathFinder.queueX[0] = arg1;
|
PathFinder.queueX[0] = arg1;
|
||||||
@Pc(69) int local69 = local49 + 1;
|
@Pc(69) int local69 = local49 + 1;
|
||||||
PathFinder.queueZ[0] = arg2;
|
PathFinder.queueZ[0] = arg2;
|
||||||
aByteArrayArrayArray15[Player.plane][arg1][arg2] = local14;
|
aByteArrayArrayArray15[plane][arg1][arg2] = local14;
|
||||||
while (local47 != local69) {
|
while (local47 != local69) {
|
||||||
@Pc(94) int local94 = PathFinder.queueX[local47] >> 16 & 0xFF;
|
@Pc(94) int local94 = PathFinder.queueX[local47] >> 16 & 0xFF;
|
||||||
@Pc(102) int local102 = PathFinder.queueX[local47] >> 24 & 0xFF;
|
@Pc(102) int local102 = PathFinder.queueX[local47] >> 24 & 0xFF;
|
||||||
|
|
@ -1063,13 +1086,13 @@ public final class ScriptRunner {
|
||||||
local47 = local47 + 1 & 0xFFF;
|
local47 = local47 + 1 & 0xFFF;
|
||||||
@Pc(130) boolean local130 = false;
|
@Pc(130) boolean local130 = false;
|
||||||
@Pc(132) boolean local132 = false;
|
@Pc(132) boolean local132 = false;
|
||||||
if ((SceneGraph.renderFlags[Player.plane][local108][local122] & 0x4) == 0) {
|
if ((SceneGraph.renderFlags[plane][local108][local122] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
local130 = true;
|
local130 = true;
|
||||||
}
|
}
|
||||||
@Pc(150) int local150;
|
@Pc(150) int local150;
|
||||||
@Pc(191) int local191;
|
@Pc(191) int local191;
|
||||||
label238:
|
label238:
|
||||||
for (local150 = Player.plane + 1; local150 <= 3; local150++) {
|
for (local150 = plane + 1; local150 <= 3; local150++) {
|
||||||
if ((SceneGraph.renderFlags[local150][local108][local122] & 0x8) == 0) {
|
if ((SceneGraph.renderFlags[local150][local108][local122] & 0x8) == 0) {
|
||||||
@Pc(227) int local227;
|
@Pc(227) int local227;
|
||||||
@Pc(358) int local358;
|
@Pc(358) int local358;
|
||||||
|
|
@ -1124,8 +1147,8 @@ public final class ScriptRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (local132) {
|
if (local132) {
|
||||||
if (SceneGraph.tileHeights[Player.plane + 1][local108][local122] > anIntArray205[arg4]) {
|
if (SceneGraph.tileHeights[plane + 1][local108][local122] > anIntArray205[arg4]) {
|
||||||
anIntArray205[arg4] = SceneGraph.tileHeights[Player.plane + 1][local108][local122];
|
anIntArray205[arg4] = SceneGraph.tileHeights[plane + 1][local108][local122];
|
||||||
}
|
}
|
||||||
local150 = local108 << 7;
|
local150 = local108 << 7;
|
||||||
if (local150 < anIntArray338[arg4]) {
|
if (local150 < anIntArray338[arg4]) {
|
||||||
|
|
@ -1139,60 +1162,61 @@ public final class ScriptRunner {
|
||||||
} else if (anIntArray134[arg4] < local191) {
|
} else if (anIntArray134[arg4] < local191) {
|
||||||
anIntArray134[arg4] = local191;
|
anIntArray134[arg4] = local191;
|
||||||
}
|
}
|
||||||
|
API.AddRoofVisibilityGroupTile(arg4, plane, local108, local122);
|
||||||
}
|
}
|
||||||
if (!local130) {
|
if (!local130) {
|
||||||
if (local108 >= 1 && aByteArrayArrayArray15[Player.plane][local108 - 1][local122] != local14) {
|
if (local108 >= 1 && aByteArrayArrayArray15[plane][local108 - 1][local122] != local14) {
|
||||||
PathFinder.queueX[local69] = local108 - 1 | 0x120000 | 0xD3000000;
|
PathFinder.queueX[local69] = local108 - 1 | 0x120000 | 0xD3000000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x130000;
|
PathFinder.queueZ[local69] = local122 | 0x130000;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 - 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 - 1][local122] = local14;
|
||||||
}
|
}
|
||||||
local122++;
|
local122++;
|
||||||
if (local122 < 104) {
|
if (local122 < 104) {
|
||||||
if (local108 - 1 >= 0 && local14 != aByteArrayArrayArray15[Player.plane][local108 - 1][local122] && (SceneGraph.renderFlags[Player.plane][local108][local122] & 0x4) == 0 && (SceneGraph.renderFlags[Player.plane][local108 - 1][local122 - 1] & 0x4) == 0) {
|
if (local108 - 1 >= 0 && local14 != aByteArrayArrayArray15[plane][local108 - 1][local122] && (SceneGraph.renderFlags[plane][local108][local122] & API.TILE_FLAG_UNDER_ROOF) == 0 && (SceneGraph.renderFlags[plane][local108 - 1][local122 - 1] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
PathFinder.queueX[local69] = 0x52000000 | 0x120000 | local108 - 1;
|
PathFinder.queueX[local69] = 0x52000000 | 0x120000 | local108 - 1;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x130000;
|
PathFinder.queueZ[local69] = local122 | 0x130000;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 - 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 - 1][local122] = local14;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
}
|
}
|
||||||
if (local14 != aByteArrayArrayArray15[Player.plane][local108][local122]) {
|
if (local14 != aByteArrayArrayArray15[plane][local108][local122]) {
|
||||||
PathFinder.queueX[local69] = local108 | 0x13000000 | 0x520000;
|
PathFinder.queueX[local69] = local108 | 0x13000000 | 0x520000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x530000;
|
PathFinder.queueZ[local69] = local122 | 0x530000;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
aByteArrayArrayArray15[Player.plane][local108][local122] = local14;
|
aByteArrayArrayArray15[plane][local108][local122] = local14;
|
||||||
}
|
}
|
||||||
if (local108 + 1 < 104 && aByteArrayArrayArray15[Player.plane][local108 + 1][local122] != local14 && (SceneGraph.renderFlags[Player.plane][local108][local122] & 0x4) == 0 && (SceneGraph.renderFlags[Player.plane][local108 + 1][local122 - 1] & 0x4) == 0) {
|
if (local108 + 1 < 104 && aByteArrayArrayArray15[plane][local108 + 1][local122] != local14 && (SceneGraph.renderFlags[plane][local108][local122] & API.TILE_FLAG_UNDER_ROOF) == 0 && (SceneGraph.renderFlags[plane][local108 + 1][local122 - 1] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
PathFinder.queueX[local69] = 0x92000000 | 0x520000 | local108 + 1;
|
PathFinder.queueX[local69] = 0x92000000 | 0x520000 | local108 + 1;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x530000;
|
PathFinder.queueZ[local69] = local122 | 0x530000;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 + 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 + 1][local122] = local14;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local122--;
|
local122--;
|
||||||
if (local108 + 1 < 104 && local14 != aByteArrayArrayArray15[Player.plane][local108 + 1][local122]) {
|
if (local108 + 1 < 104 && local14 != aByteArrayArrayArray15[plane][local108 + 1][local122]) {
|
||||||
PathFinder.queueX[local69] = local108 + 1 | 0x920000 | 0x53000000;
|
PathFinder.queueX[local69] = local108 + 1 | 0x920000 | 0x53000000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x930000;
|
PathFinder.queueZ[local69] = local122 | 0x930000;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 + 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 + 1][local122] = local14;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
}
|
}
|
||||||
local122--;
|
local122--;
|
||||||
if (local122 >= 0) {
|
if (local122 >= 0) {
|
||||||
if (local108 - 1 >= 0 && aByteArrayArrayArray15[Player.plane][local108 - 1][local122] != local14 && (SceneGraph.renderFlags[Player.plane][local108][local122] & 0x4) == 0 && (SceneGraph.renderFlags[Player.plane][local108 - 1][local122 + 1] & 0x4) == 0) {
|
if (local108 - 1 >= 0 && aByteArrayArrayArray15[plane][local108 - 1][local122] != local14 && (SceneGraph.renderFlags[plane][local108][local122] & API.TILE_FLAG_UNDER_ROOF) == 0 && (SceneGraph.renderFlags[plane][local108 - 1][local122 + 1] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
PathFinder.queueX[local69] = local108 - 1 | 0xD20000 | 0x12000000;
|
PathFinder.queueX[local69] = local108 - 1 | 0xD20000 | 0x12000000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0xD30000;
|
PathFinder.queueZ[local69] = local122 | 0xD30000;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 - 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 - 1][local122] = local14;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
}
|
}
|
||||||
if (local14 != aByteArrayArrayArray15[Player.plane][local108][local122]) {
|
if (local14 != aByteArrayArrayArray15[plane][local108][local122]) {
|
||||||
PathFinder.queueX[local69] = local108 | 0xD20000 | 0x93000000;
|
PathFinder.queueX[local69] = local108 | 0xD20000 | 0x93000000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0xD30000;
|
PathFinder.queueZ[local69] = local122 | 0xD30000;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
aByteArrayArrayArray15[Player.plane][local108][local122] = local14;
|
aByteArrayArrayArray15[plane][local108][local122] = local14;
|
||||||
}
|
}
|
||||||
if (local108 + 1 < 104 && aByteArrayArrayArray15[Player.plane][local108 + 1][local122] != local14 && (SceneGraph.renderFlags[Player.plane][local108][local122] & 0x4) == 0 && (SceneGraph.renderFlags[Player.plane][local108 + 1][local122 + 1] & 0x4) == 0) {
|
if (local108 + 1 < 104 && aByteArrayArrayArray15[plane][local108 + 1][local122] != local14 && (SceneGraph.renderFlags[plane][local108][local122] & API.TILE_FLAG_UNDER_ROOF) == 0 && (SceneGraph.renderFlags[plane][local108 + 1][local122 + 1] & API.TILE_FLAG_UNDER_ROOF) == 0) {
|
||||||
PathFinder.queueX[local69] = local108 + 1 | 0xD2000000 | 0x920000;
|
PathFinder.queueX[local69] = local108 + 1 | 0xD2000000 | 0x920000;
|
||||||
PathFinder.queueZ[local69] = local122 | 0x930000;
|
PathFinder.queueZ[local69] = local122 | 0x930000;
|
||||||
aByteArrayArrayArray15[Player.plane][local108 + 1][local122] = local14;
|
aByteArrayArrayArray15[plane][local108 + 1][local122] = local14;
|
||||||
local69 = local69 + 1 & 0xFFF;
|
local69 = local69 + 1 & 0xFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1316,9 +1340,12 @@ public final class ScriptRunner {
|
||||||
|
|
||||||
@OriginalMember(owner = "client!uh", name = "f", descriptor = "(I)V")
|
@OriginalMember(owner = "client!uh", name = "f", descriptor = "(I)V")
|
||||||
public static void method4302() {
|
public static void method4302() {
|
||||||
|
API.DisableRoofVisibilityIfExpired();
|
||||||
if (method4047() != 2) {
|
if (method4047() != 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
API.EnsureRoofVisibilityBuffers();
|
||||||
|
boolean roofVisibilityActive = API.IsRoofVisibilityActive();
|
||||||
@Pc(27) byte local27 = (byte) (anInt3325 - 4 & 0xFF);
|
@Pc(27) byte local27 = (byte) (anInt3325 - 4 & 0xFF);
|
||||||
@Pc(31) int local31 = anInt3325 % 104;
|
@Pc(31) int local31 = anInt3325 % 104;
|
||||||
@Pc(33) int local33;
|
@Pc(33) int local33;
|
||||||
|
|
@ -1331,7 +1358,7 @@ public final class ScriptRunner {
|
||||||
if (Player.plane == 3) {
|
if (Player.plane == 3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (local33 = 0; local33 < 2; local33++) {
|
for (local33 = 0; local33 < anIntArray205.length; local33++) {
|
||||||
anIntArray205[local33] = -1000000;
|
anIntArray205[local33] = -1000000;
|
||||||
anIntArray338[local33] = 1000000;
|
anIntArray338[local33] = 1000000;
|
||||||
anIntArray518[local33] = 0;
|
anIntArray518[local33] = 0;
|
||||||
|
|
@ -1340,14 +1367,17 @@ public final class ScriptRunner {
|
||||||
}
|
}
|
||||||
if (Camera.cameraType != 1) {
|
if (Camera.cameraType != 1) {
|
||||||
local33 = SceneGraph.getTileHeight(Player.plane, Camera.renderX, Camera.renderZ);
|
local33 = SceneGraph.getTileHeight(Player.plane, Camera.renderX, Camera.renderZ);
|
||||||
if (local33 - Camera.anInt40 < 800 && (SceneGraph.renderFlags[Player.plane][Camera.renderX >> 7][Camera.renderZ >> 7] & 0x4) != 0) {
|
if (local33 - Camera.anInt40 < 800 && (SceneGraph.renderFlags[Player.plane][Camera.renderX >> 7][Camera.renderZ >> 7] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, Camera.renderX >> 7, Camera.renderZ >> 7, SceneGraph.tiles, 1);
|
method4348(false, Camera.renderX >> 7, Camera.renderZ >> 7, SceneGraph.tiles, 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((SceneGraph.renderFlags[Player.plane][PlayerList.self.xFine >> 7][PlayerList.self.zFine >> 7] & 0x4) != 0) {
|
if ((SceneGraph.renderFlags[Player.plane][PlayerList.self.xFine >> 7][PlayerList.self.zFine >> 7] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, PlayerList.self.xFine >> 7, PlayerList.self.zFine >> 7, SceneGraph.tiles, 0);
|
method4348(false, PlayerList.self.xFine >> 7, PlayerList.self.zFine >> 7, SceneGraph.tiles, 0);
|
||||||
}
|
}
|
||||||
|
if (roofVisibilityActive) {
|
||||||
|
API.ApplyRoofVisibilityRequests();
|
||||||
|
}
|
||||||
if (Camera.cameraPitch >= 310) {
|
if (Camera.cameraPitch >= 310) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1378,7 +1408,7 @@ public final class ScriptRunner {
|
||||||
} else if (local40 > local135) {
|
} else if (local40 > local135) {
|
||||||
local40--;
|
local40--;
|
||||||
}
|
}
|
||||||
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & 0x4) != 0) {
|
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1390,7 +1420,7 @@ public final class ScriptRunner {
|
||||||
local33--;
|
local33--;
|
||||||
}
|
}
|
||||||
local186 -= 65536;
|
local186 -= 65536;
|
||||||
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & 0x4) != 0) {
|
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1406,7 +1436,7 @@ public final class ScriptRunner {
|
||||||
} else if (local33 > local162) {
|
} else if (local33 > local162) {
|
||||||
local33--;
|
local33--;
|
||||||
}
|
}
|
||||||
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & 0x4) != 0) {
|
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1418,7 +1448,7 @@ public final class ScriptRunner {
|
||||||
local40--;
|
local40--;
|
||||||
}
|
}
|
||||||
local186 -= 65536;
|
local186 -= 65536;
|
||||||
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & 0x4) != 0) {
|
if ((SceneGraph.renderFlags[Player.plane][local33][local40] & API.TILE_FLAG_UNDER_ROOF) != 0) {
|
||||||
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
method4348(false, local33, local40, SceneGraph.tiles, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import org.openrs2.deob.annotation.OriginalArg;
|
||||||
import org.openrs2.deob.annotation.OriginalClass;
|
import org.openrs2.deob.annotation.OriginalClass;
|
||||||
import org.openrs2.deob.annotation.OriginalMember;
|
import org.openrs2.deob.annotation.OriginalMember;
|
||||||
import org.openrs2.deob.annotation.Pc;
|
import org.openrs2.deob.annotation.Pc;
|
||||||
|
import plugin.api.API;
|
||||||
|
|
||||||
@OriginalClass("client!w")
|
@OriginalClass("client!w")
|
||||||
public final class SoftwareModel extends Model {
|
public final class SoftwareModel extends Model {
|
||||||
|
|
@ -833,7 +834,9 @@ public final class SoftwareModel extends Model {
|
||||||
@Pc(223) int x;
|
@Pc(223) int x;
|
||||||
@Pc(208) int y;
|
@Pc(208) int y;
|
||||||
@Pc(227) int z;
|
@Pc(227) int z;
|
||||||
if (key > 0L && RawModel.allowInput && d > 0) {
|
@Pc(229) boolean roofVisibilityLocPick = API.IsRoofVisibilityLocPickable(key);
|
||||||
|
@Pc(232) boolean miniMenuPick = key > 0L;
|
||||||
|
if ((miniMenuPick || roofVisibilityLocPick) && RawModel.allowInput && d > 0) {
|
||||||
if (e > 0) {
|
if (e > 0) {
|
||||||
v = maxScreenX / c;
|
v = maxScreenX / c;
|
||||||
y = minScreenX / d;
|
y = minScreenX / d;
|
||||||
|
|
@ -893,7 +896,12 @@ public final class SoftwareModel extends Model {
|
||||||
}
|
}
|
||||||
if (GlModel.anInt3582 >= v && GlModel.anInt3582 <= y && RawModel.anInt1053 >= x && RawModel.anInt1053 <= z) {
|
if (GlModel.anInt3582 >= v && GlModel.anInt3582 <= y && RawModel.anInt1053 >= x && RawModel.anInt1053 <= z) {
|
||||||
if (this.pickable) {
|
if (this.pickable) {
|
||||||
Model.aLongArray11[MiniMenu.anInt7++] = key;
|
if (miniMenuPick) {
|
||||||
|
Model.aLongArray11[MiniMenu.anInt7++] = key;
|
||||||
|
}
|
||||||
|
if (roofVisibilityLocPick) {
|
||||||
|
API.ReportRoofVisibilityLoc(key, arg9);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
local190 = true;
|
local190 = true;
|
||||||
}
|
}
|
||||||
|
|
@ -933,7 +941,7 @@ public final class SoftwareModel extends Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.draw(project1, local190, key, b - d, c - d + 2, arg10);
|
this.draw(project1, local190, key, b - d, c - d + 2, arg9, arg10);
|
||||||
} catch (@Pc(713) Exception ex) {
|
} catch (@Pc(713) Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
@ -1148,7 +1156,7 @@ public final class SoftwareModel extends Model {
|
||||||
projectSceneZ[local52] = local71;
|
projectSceneZ[local52] = local71;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.draw(false, arg6 >= 0L, arg6, this.aShort35, this.aShort35 << 1, null);
|
this.draw(false, arg6 >= 0L || API.IsRoofVisibilityLocPickable(arg6), arg6, this.aShort35, this.aShort35 << 1, Player.plane, null);
|
||||||
} catch (@Pc(240) RuntimeException local240) {
|
} catch (@Pc(240) RuntimeException local240) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1583,7 +1591,7 @@ public final class SoftwareModel extends Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OriginalMember(owner = "client!w", name = "a", descriptor = "(ZZJIILclient!ga;)V")
|
@OriginalMember(owner = "client!w", name = "a", descriptor = "(ZZJIILclient!ga;)V")
|
||||||
private void draw(@OriginalArg(0) boolean arg0, @OriginalArg(1) boolean arg1, @OriginalArg(2) long arg2, @OriginalArg(3) int arg3, @OriginalArg(4) int arg4, @OriginalArg(5) ParticleSystem arg5) {
|
private void draw(@OriginalArg(0) boolean arg0, @OriginalArg(1) boolean arg1, @OriginalArg(2) long arg2, @OriginalArg(3) int arg3, @OriginalArg(4) int arg4, int roofHidePlane, @OriginalArg(5) ParticleSystem arg5) {
|
||||||
if (arg4 >= 1600) {
|
if (arg4 >= 1600) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1659,7 +1667,12 @@ public final class SoftwareModel extends Model {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (arg1 && this.pointWithinTriangle(GlModel.anInt3582 + Rasteriser.centerX, RawModel.anInt1053 + Rasteriser.centerY, vertexScreenY[local51], vertexScreenY[local56], vertexScreenY[pri], local65, local69, local73)) {
|
if (arg1 && this.pointWithinTriangle(GlModel.anInt3582 + Rasteriser.centerX, RawModel.anInt1053 + Rasteriser.centerY, vertexScreenY[local51], vertexScreenY[local56], vertexScreenY[pri], local65, local69, local73)) {
|
||||||
Model.aLongArray11[MiniMenu.anInt7++] = arg2;
|
if (arg2 >= 0L) {
|
||||||
|
Model.aLongArray11[MiniMenu.anInt7++] = arg2;
|
||||||
|
}
|
||||||
|
if (API.IsRoofVisibilityLocPickable(arg2)) {
|
||||||
|
API.ReportRoofVisibilityLoc(arg2, roofHidePlane);
|
||||||
|
}
|
||||||
arg1 = false;
|
arg1 = false;
|
||||||
}
|
}
|
||||||
if ((local65 - local69) * (vertexScreenY[pri] - vertexScreenY[local56]) - (vertexScreenY[local51] - vertexScreenY[local56]) * (local73 - local69) > 0) {
|
if ((local65 - local69) * (vertexScreenY[pri] - vertexScreenY[local56]) - (vertexScreenY[local51] - vertexScreenY[local56]) * (local73 - local69) > 0) {
|
||||||
|
|
@ -1946,7 +1959,7 @@ public final class SoftwareModel extends Model {
|
||||||
projectSceneZ[local52] = local71;
|
projectSceneZ[local52] = local71;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.draw(false, false, 0L, this.aShort35, this.aShort35 << 1, null);
|
this.draw(false, false, 0L, this.aShort35, this.aShort35 << 1, Player.plane, null);
|
||||||
} catch (@Pc(234) RuntimeException local234) {
|
} catch (@Pc(234) RuntimeException local234) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
client/src/main/kotlin/plugin/api/RoofVisibilityHandler.kt
Normal file
33
client/src/main/kotlin/plugin/api/RoofVisibilityHandler.kt
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package plugin.api
|
||||||
|
|
||||||
|
interface RoofVisibilityHandler {
|
||||||
|
fun getGroupLimit(): Int
|
||||||
|
|
||||||
|
fun isActive(): Boolean
|
||||||
|
|
||||||
|
fun disableIfExpired()
|
||||||
|
|
||||||
|
fun ensureBuffers()
|
||||||
|
|
||||||
|
fun applyRequests()
|
||||||
|
|
||||||
|
fun isPicking(): Boolean
|
||||||
|
|
||||||
|
fun getPickScreenX(): Int
|
||||||
|
|
||||||
|
fun getPickScreenY(): Int
|
||||||
|
|
||||||
|
fun reportTile(sceneX: Int, sceneZ: Int, plane: Int)
|
||||||
|
|
||||||
|
fun isLocPickable(key: Long): Boolean
|
||||||
|
|
||||||
|
fun reportLoc(key: Long, plane: Int)
|
||||||
|
|
||||||
|
fun beginGroup(group: Int)
|
||||||
|
|
||||||
|
fun addGroupTile(group: Int, plane: Int, sceneX: Int, sceneZ: Int)
|
||||||
|
|
||||||
|
fun setDestinationTarget(sceneX: Int, sceneZ: Int)
|
||||||
|
|
||||||
|
fun clearDestinationTarget()
|
||||||
|
}
|
||||||
703
plugin-playground/src/main/kotlin/SmartRoofs/RoofHider.kt
Normal file
703
plugin-playground/src/main/kotlin/SmartRoofs/RoofHider.kt
Normal file
|
|
@ -0,0 +1,703 @@
|
||||||
|
package SmartRoofs
|
||||||
|
|
||||||
|
import plugin.api.API
|
||||||
|
import plugin.api.MiniMenuAction
|
||||||
|
import plugin.api.MiniMenuEntry
|
||||||
|
import plugin.api.RoofVisibilityHandler
|
||||||
|
import rt4.Camera
|
||||||
|
import rt4.Cs1ScriptRunner
|
||||||
|
import rt4.LocType
|
||||||
|
import rt4.MathUtils
|
||||||
|
import rt4.Player
|
||||||
|
import rt4.PlayerList
|
||||||
|
import rt4.SceneGraph
|
||||||
|
import rt4.ScriptRunner
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
object RoofHider {
|
||||||
|
private const val TILE_FLAG_UNDER_ROOF = API.TILE_FLAG_UNDER_ROOF
|
||||||
|
private const val SMART_ROOFS_ACTIVE_GRACE_MS = 750L
|
||||||
|
|
||||||
|
private const val MAP_FLAG_ROOF_GROUP = 2
|
||||||
|
|
||||||
|
private const val HOVER_GROUP_START = 3
|
||||||
|
private const val HOVER_TARGET_LIMIT = 8
|
||||||
|
private const val HOVER_HOLD_MS = 125L
|
||||||
|
private const val HOVER_PRIMARY_HIT_DISTANCE = 64
|
||||||
|
private const val HOVER_BUILDING_FOOTPRINT_PRIMARY_HIT_DISTANCE = 12
|
||||||
|
private const val HOVER_UPPER_PLANE_TILE_SEARCH_RADIUS = 2
|
||||||
|
private const val HOVER_BUILDING_FOOTPRINT_X_PADDING = 2
|
||||||
|
private const val HOVER_BUILDING_FOOTPRINT_TOP_PADDING = 64
|
||||||
|
private const val HOVER_BUILDING_FOOTPRINT_BOTTOM_PADDING = 4
|
||||||
|
private const val HOVER_OUTSIDE_GROUND_HIT_MS = 50L
|
||||||
|
|
||||||
|
private const val DESTINATION_TARGET_GROUP = HOVER_GROUP_START + HOVER_TARGET_LIMIT
|
||||||
|
const val SELECTIVE_ROOF_GROUP_COUNT = DESTINATION_TARGET_GROUP + 1
|
||||||
|
private const val DESTINATION_HOLD_MS = 20000L
|
||||||
|
private const val DESTINATION_REACHED_DISTANCE = 1
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val HANDLER: RoofVisibilityHandler = object : RoofVisibilityHandler {
|
||||||
|
override fun getGroupLimit(): Int = SELECTIVE_ROOF_GROUP_COUNT
|
||||||
|
|
||||||
|
override fun isActive(): Boolean = isSmartRoofsActive()
|
||||||
|
|
||||||
|
override fun disableIfExpired() = disableSmartRoofsIfExpired()
|
||||||
|
|
||||||
|
override fun ensureBuffers() = ensureSelectiveRoofBuffers()
|
||||||
|
|
||||||
|
override fun applyRequests() {
|
||||||
|
hideMapFlagRoof()
|
||||||
|
hideHoverTargets()
|
||||||
|
hideDestinationTarget()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isPicking(): Boolean = isHoverPicking()
|
||||||
|
|
||||||
|
override fun getPickScreenX(): Int = getHoverPickScreenX()
|
||||||
|
|
||||||
|
override fun getPickScreenY(): Int = getHoverPickScreenY()
|
||||||
|
|
||||||
|
override fun reportTile(sceneX: Int, sceneZ: Int, plane: Int) {
|
||||||
|
setHoverTile(sceneX, sceneZ, plane)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isLocPickable(key: Long): Boolean = isHoverLocPickable(key)
|
||||||
|
|
||||||
|
override fun reportLoc(key: Long, plane: Int) {
|
||||||
|
setHoverLoc(key, plane)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beginGroup(group: Int) = beginBuildingFootprint(group)
|
||||||
|
|
||||||
|
override fun addGroupTile(group: Int, plane: Int, sceneX: Int, sceneZ: Int) {
|
||||||
|
addBuildingFootprintTile(group, plane, sceneX, sceneZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setDestinationTarget(sceneX: Int, sceneZ: Int) {
|
||||||
|
this@RoofHider.setDestinationTarget(sceneX, sceneZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearDestinationTarget() = this@RoofHider.clearDestinationTarget()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private var smartRoofsEnabled = false
|
||||||
|
private var smartRoofsActiveUntil = 0L
|
||||||
|
private var smartRoofsWasActive = false
|
||||||
|
|
||||||
|
private var mapFlagRoofX = -1
|
||||||
|
private var mapFlagRoofZ = -1
|
||||||
|
private var mapFlagRoofRadius = 0
|
||||||
|
|
||||||
|
private var hoverPickActive = false
|
||||||
|
private var hoverPickScreenX = 0
|
||||||
|
private var hoverPickScreenY = 0
|
||||||
|
private val hoverTargetX = IntArray(HOVER_TARGET_LIMIT) { -1 }
|
||||||
|
private val hoverTargetZ = IntArray(HOVER_TARGET_LIMIT) { -1 }
|
||||||
|
private val hoverTargetPlane = IntArray(HOVER_TARGET_LIMIT) { -1 }
|
||||||
|
private val hoverPrimaryHitX = IntArray(HOVER_TARGET_LIMIT) { Int.MIN_VALUE }
|
||||||
|
private val hoverPrimaryHitY = IntArray(HOVER_TARGET_LIMIT) { Int.MIN_VALUE }
|
||||||
|
private val hoverTargetUntil = LongArray(HOVER_TARGET_LIMIT)
|
||||||
|
private val buildingFootprintMinX = IntArray(HOVER_TARGET_LIMIT) { Int.MAX_VALUE }
|
||||||
|
private val buildingFootprintMaxX = IntArray(HOVER_TARGET_LIMIT) { Int.MIN_VALUE }
|
||||||
|
private val buildingFootprintMinY = IntArray(HOVER_TARGET_LIMIT) { Int.MAX_VALUE }
|
||||||
|
private val buildingFootprintMaxY = IntArray(HOVER_TARGET_LIMIT) { Int.MIN_VALUE }
|
||||||
|
private val buildingFootprintTiles = Array(HOVER_TARGET_LIMIT) { Array(104) { BooleanArray(104) } }
|
||||||
|
private var lastHoverTileX = -1
|
||||||
|
private var lastHoverTileZ = -1
|
||||||
|
private var lastHoverTilePlane = -1
|
||||||
|
private var lastHoverTileValid = false
|
||||||
|
private var lastHoverTileAt = 0L
|
||||||
|
private var lastHoverHitAt = 0L
|
||||||
|
|
||||||
|
private var destinationTargetX = -1
|
||||||
|
private var destinationTargetZ = -1
|
||||||
|
private var destinationTargetUntil = 0L
|
||||||
|
|
||||||
|
fun isSmartRoofsActive(): Boolean {
|
||||||
|
return smartRoofsEnabled && isSmartRoofsActive(System.currentTimeMillis()) && ScriptRunner.canUseSelectiveRoofHiding()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isSmartRoofsActive(now: Long): Boolean {
|
||||||
|
return now <= smartRoofsActiveUntil
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateSmartRoofsPulse(now: Long) {
|
||||||
|
smartRoofsActiveUntil = now + SMART_ROOFS_ACTIVE_GRACE_MS
|
||||||
|
smartRoofsWasActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disableSmartRoofsIfExpired() {
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (!smartRoofsWasActive || isSmartRoofsActive(now)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearSmartRoofsState()
|
||||||
|
smartRoofsWasActive = false
|
||||||
|
ScriptRunner.method2218()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearSmartRoofsState() {
|
||||||
|
clearMapFlagRoof()
|
||||||
|
clearHoverRequest()
|
||||||
|
clearDestinationTarget()
|
||||||
|
smartRoofsEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSmartRoofsEnabled(enabled: Boolean) {
|
||||||
|
if (!enabled) {
|
||||||
|
clearSmartRoofsState()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
smartRoofsEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateSmartRoofs() {
|
||||||
|
if (!smartRoofsEnabled) {
|
||||||
|
clearSmartRoofsState()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
val wasActive = isSmartRoofsActive(now)
|
||||||
|
updateSmartRoofsPulse(now)
|
||||||
|
if (!ScriptRunner.canUseSelectiveRoofHiding()) {
|
||||||
|
clearSmartRoofsState()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val rebuild = !wasActive ||
|
||||||
|
ScriptRunner.method4047() != 2 ||
|
||||||
|
ScriptRunner.aByteArrayArrayArray15 == null ||
|
||||||
|
ScriptRunner.anIntArray205.size < SELECTIVE_ROOF_GROUP_COUNT
|
||||||
|
if (rebuild) {
|
||||||
|
ScriptRunner.method2218()
|
||||||
|
} else {
|
||||||
|
ensureSelectiveRoofBuffers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureSelectiveRoofBuffers() {
|
||||||
|
if (ScriptRunner.aByteArrayArrayArray15 == null) {
|
||||||
|
ScriptRunner.method960(((ScriptRunner.anInt3325 - 4) and 0xFF).toByte())
|
||||||
|
}
|
||||||
|
if (ScriptRunner.anIntArray205.size < SELECTIVE_ROOF_GROUP_COUNT) {
|
||||||
|
ScriptRunner.method3993(SELECTIVE_ROOF_GROUP_COUNT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMapFlagRoof(sceneX: Int, sceneZ: Int, radius: Int) {
|
||||||
|
if (!isSmartRoofsActive()) {
|
||||||
|
clearMapFlagRoof()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!isInSceneBounds(sceneX, sceneZ)) {
|
||||||
|
clearMapFlagRoof()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapFlagRoofX = sceneX
|
||||||
|
mapFlagRoofZ = sceneZ
|
||||||
|
mapFlagRoofRadius = radius.coerceIn(0, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearMapFlagRoof() {
|
||||||
|
mapFlagRoofX = -1
|
||||||
|
mapFlagRoofZ = -1
|
||||||
|
mapFlagRoofRadius = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideMapFlagRoof() {
|
||||||
|
hideRoofFromSeedTile(mapFlagRoofX, mapFlagRoofZ, mapFlagRoofRadius, MAP_FLAG_ROOF_GROUP, Player.plane)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideRoofFromSeedTile(sceneX: Int, sceneZ: Int, radius: Int, group: Int, plane: Int): Boolean {
|
||||||
|
if (sceneX == -1 || !isRoofHidePlane(plane) || ScriptRunner.anIntArray205.size <= group) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (currentRadius in 0..radius) {
|
||||||
|
for (dx in -currentRadius..currentRadius) {
|
||||||
|
for (dz in -currentRadius..currentRadius) {
|
||||||
|
if (abs(dx) != currentRadius && abs(dz) != currentRadius) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (tryHideRoofFromTile(sceneX + dx, sceneZ + dz, group, plane)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryHideRoofFromTile(sceneX: Int, sceneZ: Int, group: Int, plane: Int): Boolean {
|
||||||
|
if (!isHideableRoofTile(sceneX, sceneZ, plane)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val masks = ScriptRunner.aByteArrayArrayArray15 ?: return false
|
||||||
|
val currentRoofMask = (ScriptRunner.anInt3325 and 0xFF).toByte()
|
||||||
|
if (masks[plane][sceneX][sceneZ] == currentRoofMask) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return ScriptRunner.hideRoofAt(sceneX, sceneZ, group, plane)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateHoverPick(entries: Array<out MiniMenuEntry>?) {
|
||||||
|
if (!isSmartRoofsActive()) {
|
||||||
|
clearHoverRequest()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hoverPickActive = false
|
||||||
|
if (entries == null) {
|
||||||
|
clearExpiredHoverTargets(System.currentTimeMillis())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (entry in entries) {
|
||||||
|
if (entry.action == MiniMenuAction.WALK_HERE && entry.subjectIndex == 0L) {
|
||||||
|
hoverPickActive = true
|
||||||
|
hoverPickScreenX = entry.intArg1
|
||||||
|
hoverPickScreenY = entry.intArg2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearExpiredHoverTargets(System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isHoverPicking(): Boolean {
|
||||||
|
return isSmartRoofsActive() && hoverPickActive
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHoverPickScreenX(): Int = hoverPickScreenX
|
||||||
|
|
||||||
|
private fun getHoverPickScreenY(): Int = hoverPickScreenY
|
||||||
|
|
||||||
|
private fun setHoverTile(sceneX: Int, sceneZ: Int, plane: Int) {
|
||||||
|
if (!isSmartRoofsActive() || !hoverPickActive || !isInSceneBounds(sceneX, sceneZ)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val valid = updateHoverTarget(sceneX, sceneZ, Player.plane, plane)
|
||||||
|
rememberHoverTileHit(sceneX, sceneZ, plane, valid)
|
||||||
|
if (valid) {
|
||||||
|
markHoverHit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearExpiredHoverTargets(System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isHoverLocPickable(key: Long): Boolean {
|
||||||
|
if (!isSmartRoofsActive() || !hoverPickActive || key == 0L) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val entityType = (key.toInt() shr 29) and 0x3
|
||||||
|
val locShape = ((key shr 14) and 0x3F).toInt()
|
||||||
|
return entityType == 2 && isBuildingLocShape(locShape)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setHoverLoc(key: Long, plane: Int) {
|
||||||
|
if (!isHoverLocPickable(key)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val sceneX = (key and 0x7F).toInt()
|
||||||
|
val sceneZ = ((key shr 7) and 0x7F).toInt()
|
||||||
|
if (!isInSceneBounds(sceneX, sceneZ)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (updateHoverTarget(sceneX, sceneZ, Player.plane, plane)) {
|
||||||
|
markHoverHit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateHoverTarget(sceneX: Int, sceneZ: Int, plane: Int, hitPlane: Int): Boolean {
|
||||||
|
var targetX = sceneX
|
||||||
|
var targetZ = sceneZ
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (!isHideableRoofTile(targetX, targetZ, plane)) {
|
||||||
|
val packed = findNearbyHideableRoofTile(sceneX, sceneZ, plane, hitPlane)
|
||||||
|
if (packed == -1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
targetX = packed shr 7
|
||||||
|
targetZ = packed and 0x7F
|
||||||
|
}
|
||||||
|
if (!isHideableRoofTile(targetX, targetZ, plane)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val duplicateSlot = findHoverTargetByBuildingFootprint(targetX, targetZ, plane)
|
||||||
|
if (duplicateSlot != -1) {
|
||||||
|
updateHoverPrimaryHit(duplicateSlot)
|
||||||
|
extendHoverTarget(duplicateSlot, now)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldestSlot = 0
|
||||||
|
var oldestUntil = Long.MAX_VALUE
|
||||||
|
for (i in 0 until HOVER_TARGET_LIMIT) {
|
||||||
|
if (hoverTargetX[i] == targetX && hoverTargetZ[i] == targetZ && hoverTargetPlane[i] == plane) {
|
||||||
|
updateHoverPrimaryHit(i)
|
||||||
|
extendHoverTarget(i, now)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (hoverTargetX[i] == -1 || now > hoverTargetUntil[i]) {
|
||||||
|
hoverTargetX[i] = targetX
|
||||||
|
hoverTargetZ[i] = targetZ
|
||||||
|
hoverTargetPlane[i] = plane
|
||||||
|
clearBuildingFootprint(i)
|
||||||
|
updateHoverPrimaryHit(i)
|
||||||
|
extendHoverTarget(i, now)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (hoverTargetUntil[i] < oldestUntil) {
|
||||||
|
oldestUntil = hoverTargetUntil[i]
|
||||||
|
oldestSlot = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hoverTargetX[oldestSlot] = targetX
|
||||||
|
hoverTargetZ[oldestSlot] = targetZ
|
||||||
|
hoverTargetPlane[oldestSlot] = plane
|
||||||
|
clearBuildingFootprint(oldestSlot)
|
||||||
|
updateHoverPrimaryHit(oldestSlot)
|
||||||
|
extendHoverTarget(oldestSlot, now)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findNearbyHideableRoofTile(sceneX: Int, sceneZ: Int, plane: Int, hitPlane: Int): Int {
|
||||||
|
if (hitPlane <= plane) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
for (radius in 1..HOVER_UPPER_PLANE_TILE_SEARCH_RADIUS) {
|
||||||
|
for (dx in -radius..radius) {
|
||||||
|
for (dz in -radius..radius) {
|
||||||
|
if (abs(dx) != radius && abs(dz) != radius) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val targetX = sceneX + dx
|
||||||
|
val targetZ = sceneZ + dz
|
||||||
|
if (isHideableRoofTile(targetX, targetZ, plane)) {
|
||||||
|
return (targetX shl 7) or targetZ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun rememberHoverTileHit(sceneX: Int, sceneZ: Int, plane: Int, valid: Boolean) {
|
||||||
|
lastHoverTileX = sceneX
|
||||||
|
lastHoverTileZ = sceneZ
|
||||||
|
lastHoverTilePlane = plane
|
||||||
|
lastHoverTileValid = valid
|
||||||
|
lastHoverTileAt = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun markHoverHit() {
|
||||||
|
lastHoverHitAt = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearHoverRequest() {
|
||||||
|
hoverPickActive = false
|
||||||
|
clearHoverTargets()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findHoverTargetByBuildingFootprint(sceneX: Int, sceneZ: Int, plane: Int): Int {
|
||||||
|
for (i in 0 until HOVER_TARGET_LIMIT) {
|
||||||
|
if (hoverTargetX[i] == -1 || hoverTargetPlane[i] != plane) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (isBuildingFootprintTile(i, sceneX, sceneZ)) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extendHoverTarget(index: Int, now: Long) {
|
||||||
|
hoverTargetUntil[index] = now + HOVER_HOLD_MS
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHoverGroup(index: Int): Int = HOVER_GROUP_START + index
|
||||||
|
|
||||||
|
private fun getHoverIndex(group: Int): Int {
|
||||||
|
val index = group - HOVER_GROUP_START
|
||||||
|
return if (index >= 0 && index < HOVER_TARGET_LIMIT) index else -1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearExpiredHoverTargets(now: Long) {
|
||||||
|
for (i in 0 until HOVER_TARGET_LIMIT) {
|
||||||
|
if (hoverTargetX[i] != -1 && now > hoverTargetUntil[i]) {
|
||||||
|
if (isPickInsideBuildingFootprint(i)) {
|
||||||
|
extendHoverTarget(i, now)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
clearHoverTarget(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearHoverTargets() {
|
||||||
|
for (i in 0 until HOVER_TARGET_LIMIT) {
|
||||||
|
clearHoverTarget(i)
|
||||||
|
}
|
||||||
|
lastHoverTileX = -1
|
||||||
|
lastHoverTileZ = -1
|
||||||
|
lastHoverTilePlane = -1
|
||||||
|
lastHoverTileValid = false
|
||||||
|
lastHoverTileAt = 0L
|
||||||
|
lastHoverHitAt = 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearHoverTarget(index: Int) {
|
||||||
|
hoverTargetX[index] = -1
|
||||||
|
hoverTargetZ[index] = -1
|
||||||
|
hoverTargetPlane[index] = -1
|
||||||
|
hoverPrimaryHitX[index] = Int.MIN_VALUE
|
||||||
|
hoverPrimaryHitY[index] = Int.MIN_VALUE
|
||||||
|
hoverTargetUntil[index] = 0L
|
||||||
|
clearBuildingFootprint(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideHoverTargets() {
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
val keepAlive = Cs1ScriptRunner.aBoolean108
|
||||||
|
for (i in 0 until HOVER_TARGET_LIMIT) {
|
||||||
|
if (hoverTargetX[i] == -1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val hasBuildingArea = hasBuildingFootprint(i)
|
||||||
|
val buildingFootprintKeepAlive = isPickInsideBuildingFootprint(i)
|
||||||
|
val primaryHitKeepAlive = isPickNearPrimaryHit(i, if (hasBuildingArea) HOVER_BUILDING_FOOTPRINT_PRIMARY_HIT_DISTANCE else HOVER_PRIMARY_HIT_DISTANCE)
|
||||||
|
if (hasRecentOutsideGroundHit(i, now, buildingFootprintKeepAlive || hasBuildingArea && primaryHitKeepAlive)) {
|
||||||
|
clearHoverTarget(i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (keepAlive || primaryHitKeepAlive || buildingFootprintKeepAlive) {
|
||||||
|
extendHoverTarget(i, now)
|
||||||
|
} else if (now > hoverTargetUntil[i]) {
|
||||||
|
clearHoverTarget(i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val group = getHoverGroup(i)
|
||||||
|
hideRoofFromSeedTile(hoverTargetX[i], hoverTargetZ[i], 0, group, hoverTargetPlane[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateHoverPrimaryHit(index: Int) {
|
||||||
|
hoverPrimaryHitX[index] = hoverPickScreenX
|
||||||
|
hoverPrimaryHitY[index] = hoverPickScreenY
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPickNearPrimaryHit(index: Int, distance: Int): Boolean {
|
||||||
|
if (!hoverPickActive || hoverPrimaryHitX[index] == Int.MIN_VALUE) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val dx = hoverPickScreenX - hoverPrimaryHitX[index]
|
||||||
|
val dy = hoverPickScreenY - hoverPrimaryHitY[index]
|
||||||
|
return dx * dx + dy * dy <= distance * distance
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPickInsideBuildingFootprint(index: Int): Boolean {
|
||||||
|
if (!hoverPickActive || !hasBuildingFootprint(index)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (x in 0 until 104) {
|
||||||
|
for (z in 0 until 104) {
|
||||||
|
if (buildingFootprintTiles[index][x][z] && isPickInsideBuildingFootprintTile(index, x, z)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasBuildingFootprint(index: Int): Boolean {
|
||||||
|
return buildingFootprintMinX[index] != Int.MAX_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearBuildingFootprint(index: Int) {
|
||||||
|
buildingFootprintMinX[index] = Int.MAX_VALUE
|
||||||
|
buildingFootprintMaxX[index] = Int.MIN_VALUE
|
||||||
|
buildingFootprintMinY[index] = Int.MAX_VALUE
|
||||||
|
buildingFootprintMaxY[index] = Int.MIN_VALUE
|
||||||
|
for (x in 0 until 104) {
|
||||||
|
buildingFootprintTiles[index][x].fill(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun beginBuildingFootprint(group: Int) {
|
||||||
|
val index = getHoverIndex(group)
|
||||||
|
if (index != -1) {
|
||||||
|
clearBuildingFootprint(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addBuildingFootprintTile(group: Int, plane: Int, sceneX: Int, sceneZ: Int) {
|
||||||
|
val index = getHoverIndex(group)
|
||||||
|
if (index == -1 || plane + 1 >= SceneGraph.tileHeights.size) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buildingFootprintTiles[index][sceneX][sceneZ] = true
|
||||||
|
addBuildingFootprintTileBounds(index, plane, sceneX, sceneZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addBuildingFootprintTileBounds(index: Int, plane: Int, sceneX: Int, sceneZ: Int) {
|
||||||
|
addBuildingFootprintBoundPoint(index, projectBuildingFootprintPoint(sceneX shl 7, sceneZ shl 7, SceneGraph.tileHeights[plane + 1][sceneX][sceneZ]))
|
||||||
|
addBuildingFootprintBoundPoint(index, projectBuildingFootprintPoint((sceneX + 1) shl 7, sceneZ shl 7, SceneGraph.tileHeights[plane + 1][sceneX + 1][sceneZ]))
|
||||||
|
addBuildingFootprintBoundPoint(index, projectBuildingFootprintPoint((sceneX + 1) shl 7, (sceneZ + 1) shl 7, SceneGraph.tileHeights[plane + 1][sceneX + 1][sceneZ + 1]))
|
||||||
|
addBuildingFootprintBoundPoint(index, projectBuildingFootprintPoint(sceneX shl 7, (sceneZ + 1) shl 7, SceneGraph.tileHeights[plane + 1][sceneX][sceneZ + 1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPickInsideBuildingFootprintTile(index: Int, sceneX: Int, sceneZ: Int): Boolean {
|
||||||
|
val plane = hoverTargetPlane[index]
|
||||||
|
if (!isRoofHidePlane(plane) || plane + 1 >= SceneGraph.tileHeights.size) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val point0 = projectBuildingFootprintPoint(sceneX shl 7, sceneZ shl 7, SceneGraph.tileHeights[plane + 1][sceneX][sceneZ])
|
||||||
|
val point1 = projectBuildingFootprintPoint((sceneX + 1) shl 7, sceneZ shl 7, SceneGraph.tileHeights[plane + 1][sceneX + 1][sceneZ])
|
||||||
|
val point2 = projectBuildingFootprintPoint((sceneX + 1) shl 7, (sceneZ + 1) shl 7, SceneGraph.tileHeights[plane + 1][sceneX + 1][sceneZ + 1])
|
||||||
|
val point3 = projectBuildingFootprintPoint(sceneX shl 7, (sceneZ + 1) shl 7, SceneGraph.tileHeights[plane + 1][sceneX][sceneZ + 1])
|
||||||
|
if (point0 == Long.MIN_VALUE || point1 == Long.MIN_VALUE || point2 == Long.MIN_VALUE || point3 == Long.MIN_VALUE) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val minX = min(min((point0 shr 32).toInt(), (point1 shr 32).toInt()), min((point2 shr 32).toInt(), (point3 shr 32).toInt()))
|
||||||
|
val maxX = max(max((point0 shr 32).toInt(), (point1 shr 32).toInt()), max((point2 shr 32).toInt(), (point3 shr 32).toInt()))
|
||||||
|
val minY = min(min(point0.toInt(), point1.toInt()), min(point2.toInt(), point3.toInt()))
|
||||||
|
val maxY = max(max(point0.toInt(), point1.toInt()), max(point2.toInt(), point3.toInt()))
|
||||||
|
return hoverPickScreenX >= minX - HOVER_BUILDING_FOOTPRINT_X_PADDING &&
|
||||||
|
hoverPickScreenX <= maxX + HOVER_BUILDING_FOOTPRINT_X_PADDING &&
|
||||||
|
hoverPickScreenY >= minY - HOVER_BUILDING_FOOTPRINT_TOP_PADDING &&
|
||||||
|
hoverPickScreenY <= maxY + HOVER_BUILDING_FOOTPRINT_BOTTOM_PADDING
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasRecentOutsideGroundHit(index: Int, now: Long, pickInsideBuildingFootprint: Boolean): Boolean {
|
||||||
|
if (pickInsideBuildingFootprint || lastHoverTileAt == 0L || now - lastHoverTileAt > HOVER_OUTSIDE_GROUND_HIT_MS) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (lastHoverTileValid || lastHoverTileAt <= lastHoverHitAt || now - lastHoverHitAt <= HOVER_OUTSIDE_GROUND_HIT_MS) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (lastHoverTilePlane != hoverTargetPlane[index]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !isBuildingFootprintTile(index, lastHoverTileX, lastHoverTileZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isBuildingFootprintTile(index: Int, sceneX: Int, sceneZ: Int): Boolean {
|
||||||
|
return isInSceneBounds(sceneX, sceneZ) && buildingFootprintTiles[index][sceneX][sceneZ]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addBuildingFootprintBoundPoint(index: Int, packedPoint: Long) {
|
||||||
|
if (packedPoint == Long.MIN_VALUE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val screenX = (packedPoint shr 32).toInt()
|
||||||
|
val screenY = packedPoint.toInt()
|
||||||
|
if (screenX < buildingFootprintMinX[index]) {
|
||||||
|
buildingFootprintMinX[index] = screenX
|
||||||
|
}
|
||||||
|
if (screenX > buildingFootprintMaxX[index]) {
|
||||||
|
buildingFootprintMaxX[index] = screenX
|
||||||
|
}
|
||||||
|
if (screenY < buildingFootprintMinY[index]) {
|
||||||
|
buildingFootprintMinY[index] = screenY
|
||||||
|
}
|
||||||
|
if (screenY > buildingFootprintMaxY[index]) {
|
||||||
|
buildingFootprintMaxY[index] = screenY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun projectBuildingFootprintPoint(xFine: Int, zFine: Int, yFine: Int): Long {
|
||||||
|
val localX = xFine - Camera.renderX
|
||||||
|
val localY = yFine - Camera.anInt40
|
||||||
|
val localZ = zFine - Camera.renderZ
|
||||||
|
val sinPitch = MathUtils.sin[Camera.cameraPitch]
|
||||||
|
val cosPitch = MathUtils.cos[Camera.cameraPitch]
|
||||||
|
val sinYaw = MathUtils.sin[Camera.cameraYaw]
|
||||||
|
val cosYaw = MathUtils.cos[Camera.cameraYaw]
|
||||||
|
val rotatedX = localX * cosYaw + localZ * sinYaw shr 16
|
||||||
|
val rotatedZ = localZ * cosYaw - localX * sinYaw shr 16
|
||||||
|
val screenYDepth = rotatedZ * cosPitch + localY * sinPitch shr 16
|
||||||
|
if (screenYDepth < 50) {
|
||||||
|
return Long.MIN_VALUE
|
||||||
|
}
|
||||||
|
val rotatedY = localY * cosPitch - rotatedZ * sinPitch shr 16
|
||||||
|
val screenX = (rotatedX shl 9) / screenYDepth
|
||||||
|
val screenY = (rotatedY shl 9) / screenYDepth
|
||||||
|
return (screenX.toLong() shl 32) or (screenY.toLong() and 0xFFFFFFFFL)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setDestinationTarget(sceneX: Int, sceneZ: Int) {
|
||||||
|
if (!isSmartRoofsActive()) {
|
||||||
|
clearDestinationTarget()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!isInSceneBounds(sceneX, sceneZ)) {
|
||||||
|
clearDestinationTarget()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
destinationTargetX = sceneX
|
||||||
|
destinationTargetZ = sceneZ
|
||||||
|
destinationTargetUntil = System.currentTimeMillis() + DESTINATION_HOLD_MS
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearDestinationTarget() {
|
||||||
|
destinationTargetX = -1
|
||||||
|
destinationTargetZ = -1
|
||||||
|
destinationTargetUntil = 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasDestinationTarget(): Boolean {
|
||||||
|
if (destinationTargetX == -1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (System.currentTimeMillis() > destinationTargetUntil) {
|
||||||
|
clearDestinationTarget()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val self = PlayerList.self
|
||||||
|
if (self != null &&
|
||||||
|
abs(self.movementQueueX[0] - destinationTargetX) <= DESTINATION_REACHED_DISTANCE &&
|
||||||
|
abs(self.movementQueueZ[0] - destinationTargetZ) <= DESTINATION_REACHED_DISTANCE
|
||||||
|
) {
|
||||||
|
clearDestinationTarget()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideDestinationTarget() {
|
||||||
|
if (hasDestinationTarget()) {
|
||||||
|
hideRoofFromSeedTile(destinationTargetX, destinationTargetZ, 0, DESTINATION_TARGET_GROUP, Player.plane)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isInSceneBounds(sceneX: Int, sceneZ: Int): Boolean {
|
||||||
|
return sceneX in 0 until 104 && sceneZ in 0 until 104
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isHideableRoofTile(sceneX: Int, sceneZ: Int, plane: Int): Boolean {
|
||||||
|
if (ScriptRunner.aByteArrayArrayArray15 == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isRoofHidePlane(plane) &&
|
||||||
|
isInSceneBounds(sceneX, sceneZ) &&
|
||||||
|
(SceneGraph.renderFlags[plane][sceneX][sceneZ].toInt() and TILE_FLAG_UNDER_ROOF) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isRoofHidePlane(plane: Int): Boolean {
|
||||||
|
return plane in 0 until 3
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isBuildingLocShape(shape: Int): Boolean {
|
||||||
|
return shape == LocType.WALL_STRAIGHT ||
|
||||||
|
shape == LocType.WALL_DIAGONALCORNER ||
|
||||||
|
shape == LocType.WALL_L ||
|
||||||
|
shape == LocType.WALL_SQUARECORNER ||
|
||||||
|
shape == LocType.WALL_DIAGONAL ||
|
||||||
|
shape == LocType.WALLDECOR_STRAIGHT_XOFFSET ||
|
||||||
|
shape == LocType.WALLDECOR_STRAIGHT_ZOFFSET ||
|
||||||
|
shape == LocType.WALLDECOR_DIAGONAL_XOFFSET ||
|
||||||
|
shape == LocType.WALLDECOR_DIAGONAL_ZOFFSET ||
|
||||||
|
shape == LocType.WALLDECOR_DIAGONAL_BOTH
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
plugin-playground/src/main/kotlin/SmartRoofs/plugin.kt
Normal file
51
plugin-playground/src/main/kotlin/SmartRoofs/plugin.kt
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package SmartRoofs
|
||||||
|
|
||||||
|
import plugin.Plugin
|
||||||
|
import plugin.api.API
|
||||||
|
import plugin.api.MiniMenuEntry
|
||||||
|
|
||||||
|
class plugin : Plugin() {
|
||||||
|
override fun Init() {
|
||||||
|
API.SetRoofVisibilityHandler(RoofHider.HANDLER)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Draw(timeDelta: Long) {
|
||||||
|
if (!API.IsLoggedIn()) {
|
||||||
|
clearTargets()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
API.SetRoofVisibilityHandler(RoofHider.HANDLER)
|
||||||
|
RoofHider.setSmartRoofsEnabled(true)
|
||||||
|
RoofHider.updateSmartRoofs()
|
||||||
|
|
||||||
|
val mapFlag = API.GetMapFlagTile()
|
||||||
|
if (mapFlag == null) {
|
||||||
|
RoofHider.clearMapFlagRoof()
|
||||||
|
} else {
|
||||||
|
RoofHider.setMapFlagRoof(mapFlag[0], mapFlag[1], MAP_FLAG_RADIUS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnMiniMenuCreate(currentEntries: Array<out MiniMenuEntry>?) {
|
||||||
|
RoofHider.updateHoverPick(currentEntries)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnLogout() {
|
||||||
|
clearTargets()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnPluginsReloaded(): Boolean {
|
||||||
|
clearTargets()
|
||||||
|
API.ClearRoofVisibilityHandler(RoofHider.HANDLER)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearTargets() {
|
||||||
|
RoofHider.clearMapFlagRoof()
|
||||||
|
RoofHider.setSmartRoofsEnabled(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MAP_FLAG_RADIUS = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
AUTHOR='Edith'
|
||||||
|
DESCRIPTION='Hides roofs on cursor hover and destination travel.'
|
||||||
|
VERSION=1.0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue