dredless 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/browser/dredless.global.js +459 -1192
- package/dist/browser/dredless.global.js.map +4 -4
- package/docs/API_REFERENCE.md +90 -1
- package/docs/NODE_API.md +20 -1
- package/package.json +1 -1
- package/src/browser.d.ts +3 -0
- package/src/client/core.js +3 -0
- package/src/client/domains/index.js +12 -0
- package/src/client/domains/tips.js +153 -0
- package/src/client/index.d.ts +1 -1
- package/src/index.d.ts +36 -1
- package/src/network/invites.js +1 -1
- package/src/state/model/decoder.js +31 -46
- package/src/state/model/loader-config.js +0 -997
- package/src/state/model/state.js +6 -73
|
@@ -588,6 +588,367 @@
|
|
|
588
588
|
}
|
|
589
589
|
};
|
|
590
590
|
|
|
591
|
+
// src/protocol/outbound/ship-management.js
|
|
592
|
+
var SHIP_MANAGEMENT_TYPE = 4;
|
|
593
|
+
var SET_PRIVACY_ACTION = "set_privacy";
|
|
594
|
+
var STARTER_RECOVERY_ACTION = "starter_recovery";
|
|
595
|
+
var PLAYER_LIST_ACTION = "player_list";
|
|
596
|
+
var INVITE_RESET_ACTION = "invite_reset";
|
|
597
|
+
var SET_RANK_ACTION = "set_rank";
|
|
598
|
+
var KICK_ACTION = "kick";
|
|
599
|
+
var BAN_ACTION = "ban";
|
|
600
|
+
var DEMOTE_SELF_ACTION = "demote_self";
|
|
601
|
+
function requireNonNegativeInteger(value, name) {
|
|
602
|
+
const number = Number(value);
|
|
603
|
+
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer`);
|
|
604
|
+
return number;
|
|
605
|
+
}
|
|
606
|
+
function normalizePrivacy(value) {
|
|
607
|
+
if (value === true || value === 1 || value === "private") return 1;
|
|
608
|
+
if (value === false || value === 0 || value === "public") return 0;
|
|
609
|
+
throw new RangeError(`privacy must be 0, 1, true, false, "public", or "private"`);
|
|
610
|
+
}
|
|
611
|
+
function normalizePlayerRef(value) {
|
|
612
|
+
return requireNonNegativeInteger(value, "refId");
|
|
613
|
+
}
|
|
614
|
+
function normalizePlayerRank(value) {
|
|
615
|
+
if (value === 0 || value === "guest") return 0;
|
|
616
|
+
if (value === 1 || value === "crew") return 1;
|
|
617
|
+
if (value === 3 || value === "captain") return 3;
|
|
618
|
+
throw new RangeError(`rank must be 0, 1, 3, "guest", "crew", or "captain"`);
|
|
619
|
+
}
|
|
620
|
+
function buildShipManagementMessage(act, arg = null, extra = null) {
|
|
621
|
+
if (typeof act !== "string" || !act) throw new TypeError(`act must be a non-empty string`);
|
|
622
|
+
const message = { type: SHIP_MANAGEMENT_TYPE, act, arg };
|
|
623
|
+
if (extra && typeof extra === "object") Object.assign(message, extra);
|
|
624
|
+
return message;
|
|
625
|
+
}
|
|
626
|
+
function buildShipPrivacyMessage(privacy) {
|
|
627
|
+
return buildShipManagementMessage(SET_PRIVACY_ACTION, normalizePrivacy(privacy));
|
|
628
|
+
}
|
|
629
|
+
function buildStarterRecoveryMessage(itemId) {
|
|
630
|
+
return buildShipManagementMessage(STARTER_RECOVERY_ACTION, requireNonNegativeInteger(itemId, "itemId"));
|
|
631
|
+
}
|
|
632
|
+
function buildPlayerListMessage() {
|
|
633
|
+
return buildShipManagementMessage(PLAYER_LIST_ACTION);
|
|
634
|
+
}
|
|
635
|
+
function buildInviteResetMessage() {
|
|
636
|
+
return buildShipManagementMessage(INVITE_RESET_ACTION);
|
|
637
|
+
}
|
|
638
|
+
function buildSetPlayerRankMessage(refId, rank) {
|
|
639
|
+
return buildShipManagementMessage(SET_RANK_ACTION, normalizePlayerRef(refId), { rank: normalizePlayerRank(rank) });
|
|
640
|
+
}
|
|
641
|
+
function buildKickPlayerMessage(refId) {
|
|
642
|
+
return buildShipManagementMessage(KICK_ACTION, normalizePlayerRef(refId));
|
|
643
|
+
}
|
|
644
|
+
function buildBanPlayerMessage(refId) {
|
|
645
|
+
return buildShipManagementMessage(BAN_ACTION, normalizePlayerRef(refId));
|
|
646
|
+
}
|
|
647
|
+
function buildDemoteSelfMessage() {
|
|
648
|
+
return buildShipManagementMessage(DEMOTE_SELF_ACTION);
|
|
649
|
+
}
|
|
650
|
+
function normalizeShipConfig(event = {}) {
|
|
651
|
+
const source = event && typeof event === "object" ? event : {};
|
|
652
|
+
const config = source.config && typeof source.config === "object" ? source.config : {};
|
|
653
|
+
return {
|
|
654
|
+
privacy: config.privacy ?? null,
|
|
655
|
+
privacyName: config.privacy === 0 ? "public" : config.privacy === 1 ? "private" : null,
|
|
656
|
+
inviteKey: config.invite_key ?? null,
|
|
657
|
+
teamId: source.team_id ?? null,
|
|
658
|
+
patronPerks: Array.isArray(source.patron_perks) ? source.patron_perks.slice() : []
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
function normalizeCaptainSubrank(event = {}) {
|
|
662
|
+
const source = event && typeof event === "object" ? event : {};
|
|
663
|
+
return {
|
|
664
|
+
subrank: source.subrank ?? null,
|
|
665
|
+
enableCheats: Boolean(source.enable_cheats)
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function normalizeShipPlayerList(event = {}, previous = null, currentCaptainSubrank = null) {
|
|
669
|
+
const source = event && typeof event === "object" ? event : {};
|
|
670
|
+
const changes = Array.isArray(source.player_list) ? source.player_list.map(normalizePlayerListChange) : [];
|
|
671
|
+
const removedPlayers = changes.filter((change) => change.remove && Number.isFinite(Number(change.refId))).map((change) => Number(change.refId));
|
|
672
|
+
const changedPlayers = changes.filter((change) => !change.remove).map(({ remove: _remove, ...change }) => change);
|
|
673
|
+
const players = mergePlayerListChanges(previous?.players, changes);
|
|
674
|
+
const ownerCaptainRank = ownerRankForPlayers(players);
|
|
675
|
+
applyPlayerControlState(players, currentCaptainSubrank);
|
|
676
|
+
applyPlayerControlState(changedPlayers, currentCaptainSubrank);
|
|
677
|
+
return {
|
|
678
|
+
ownerCaptainRank,
|
|
679
|
+
shipOwners: players.filter((player) => player.isShipOwner),
|
|
680
|
+
players,
|
|
681
|
+
changes: changedPlayers,
|
|
682
|
+
removedPlayers
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
function mergePlayerListChanges(previousPlayers, changes) {
|
|
686
|
+
if (!Array.isArray(previousPlayers) || !previousPlayers.length) return changes.filter((change) => !change.remove).map(({
|
|
687
|
+
remove: _remove,
|
|
688
|
+
...player
|
|
689
|
+
}) => ({ ...player }));
|
|
690
|
+
const existing = /* @__PURE__ */ new Map();
|
|
691
|
+
for (const player of previousPlayers) {
|
|
692
|
+
if (player?.refId == null) continue;
|
|
693
|
+
existing.set(player.refId, { ...player, isShipOwner: false });
|
|
694
|
+
}
|
|
695
|
+
const changedRefs = /* @__PURE__ */ new Set();
|
|
696
|
+
const merged = [];
|
|
697
|
+
for (const change of changes) {
|
|
698
|
+
if (change.refId == null) {
|
|
699
|
+
if (!change.remove) {
|
|
700
|
+
const { remove: _remove2, ...player2 } = change;
|
|
701
|
+
merged.push({ ...player2, isShipOwner: false });
|
|
702
|
+
}
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
changedRefs.add(change.refId);
|
|
706
|
+
if (change.remove) {
|
|
707
|
+
existing.delete(change.refId);
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
const { remove: _remove, ...changePlayer } = change;
|
|
711
|
+
const player = { ...existing.get(change.refId) || {}, ...changePlayer, isShipOwner: false };
|
|
712
|
+
existing.set(change.refId, player);
|
|
713
|
+
merged.push(player);
|
|
714
|
+
}
|
|
715
|
+
for (const player of previousPlayers) {
|
|
716
|
+
if (player?.refId == null || changedRefs.has(player.refId)) continue;
|
|
717
|
+
const retained = existing.get(player.refId);
|
|
718
|
+
if (retained) merged.push(retained);
|
|
719
|
+
}
|
|
720
|
+
return merged;
|
|
721
|
+
}
|
|
722
|
+
function normalizePlayerListChange(entry = {}) {
|
|
723
|
+
const source = entry && typeof entry === "object" ? entry : {};
|
|
724
|
+
if (source._removed) return { refId: source.ref_id ?? null, remove: true };
|
|
725
|
+
return {
|
|
726
|
+
refId: source.ref_id ?? null,
|
|
727
|
+
remove: false,
|
|
728
|
+
discrim: source.discrim ?? null,
|
|
729
|
+
discrimColor: source.discrim_color ?? null,
|
|
730
|
+
teamRank: source.team_rank ?? null,
|
|
731
|
+
captainRank: source.captain_rank ?? null,
|
|
732
|
+
isCaptain: Number(source.captain_rank) > 0,
|
|
733
|
+
isShipOwner: false,
|
|
734
|
+
canBeManaged: false,
|
|
735
|
+
time: source.time ?? null,
|
|
736
|
+
items: Array.isArray(source.items) ? source.items.slice() : [],
|
|
737
|
+
aliasDiscrims: Array.isArray(source.alias_discrims) ? source.alias_discrims.slice() : [],
|
|
738
|
+
extraAliasCount: normalizeNonNegativeNumber(source.extra_aliases),
|
|
739
|
+
onlineCount: source.online_count ?? null
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
function normalizeNonNegativeNumber(value) {
|
|
743
|
+
const number = Number(value);
|
|
744
|
+
return Number.isFinite(number) && number > 0 ? number : 0;
|
|
745
|
+
}
|
|
746
|
+
function ownerRankForPlayers(players) {
|
|
747
|
+
const ranks = players.filter((player) => Number(player.captainRank) > 0).map((player) => Number(player.captainRank)).filter(Number.isFinite);
|
|
748
|
+
if (!ranks.length) return null;
|
|
749
|
+
const ownerRank = Math.min(...ranks);
|
|
750
|
+
for (const player of players) player.isShipOwner = Number(player.captainRank) === ownerRank;
|
|
751
|
+
return ownerRank;
|
|
752
|
+
}
|
|
753
|
+
function applyPlayerControlState(players, currentCaptainSubrank) {
|
|
754
|
+
const currentRank = currentCaptainRank(currentCaptainSubrank);
|
|
755
|
+
for (const player of players) player.canBeManaged = playerCanBeManagedBy(player, currentRank);
|
|
756
|
+
}
|
|
757
|
+
function currentCaptainRank(currentCaptainSubrank) {
|
|
758
|
+
const rank = Number(currentCaptainSubrank?.subrank);
|
|
759
|
+
return Number.isFinite(rank) && rank > 0 ? rank : null;
|
|
760
|
+
}
|
|
761
|
+
function playerCanBeManagedBy(player, currentRank) {
|
|
762
|
+
if (!Number.isFinite(currentRank) || !player) return false;
|
|
763
|
+
const targetCaptainRank = Number(player.captainRank);
|
|
764
|
+
if (Number.isFinite(targetCaptainRank) && targetCaptainRank > 0) return currentRank < targetCaptainRank;
|
|
765
|
+
const targetTeamRank = Number(player.teamRank);
|
|
766
|
+
return targetTeamRank === 0 || targetTeamRank === 1;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// src/client/domains/tips.js
|
|
770
|
+
function timeoutValue(options) {
|
|
771
|
+
const timeout = options.timeout ?? 5e3;
|
|
772
|
+
if (!Number.isFinite(timeout) || timeout <= 0) throw new RangeError("timeout must be positive milliseconds");
|
|
773
|
+
return timeout;
|
|
774
|
+
}
|
|
775
|
+
function waitFor(client, eventType, read, timeout, label, send = null) {
|
|
776
|
+
return new Promise((resolve, reject) => {
|
|
777
|
+
const cleanup = () => {
|
|
778
|
+
clearTimeout(timer);
|
|
779
|
+
client.off(eventType, check);
|
|
780
|
+
client.off("close", closed);
|
|
781
|
+
};
|
|
782
|
+
const check = (...args) => {
|
|
783
|
+
const value = read(...args);
|
|
784
|
+
if (value) {
|
|
785
|
+
cleanup();
|
|
786
|
+
resolve(value);
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
const closed = () => {
|
|
790
|
+
cleanup();
|
|
791
|
+
reject(new Error(`Disconnected while waiting for ${label}`));
|
|
792
|
+
};
|
|
793
|
+
const timer = setTimeout(() => {
|
|
794
|
+
cleanup();
|
|
795
|
+
reject(new Error(`Timed out waiting for ${label}`));
|
|
796
|
+
}, timeout);
|
|
797
|
+
client.on(eventType, check);
|
|
798
|
+
client.on("close", closed);
|
|
799
|
+
if (send) {
|
|
800
|
+
try {
|
|
801
|
+
send();
|
|
802
|
+
} catch (error) {
|
|
803
|
+
cleanup();
|
|
804
|
+
reject(error);
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
check();
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
var TipDomain = class {
|
|
812
|
+
#busy = false;
|
|
813
|
+
#target = null;
|
|
814
|
+
#current = null;
|
|
815
|
+
constructor(client) {
|
|
816
|
+
this.client = client;
|
|
817
|
+
client.on("close", () => {
|
|
818
|
+
this.#current = null;
|
|
819
|
+
this.#target = null;
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
get current() {
|
|
823
|
+
return this.#current;
|
|
824
|
+
}
|
|
825
|
+
receive(event, world) {
|
|
826
|
+
const options = Array.isArray(event.options) ? event.options.map(String) : [];
|
|
827
|
+
const entity = this.#target?.world === world?.id ? this.#target.entity : null;
|
|
828
|
+
const menu = Object.freeze({
|
|
829
|
+
entity,
|
|
830
|
+
world: world?.id ?? null,
|
|
831
|
+
filter: event.filter ?? null,
|
|
832
|
+
x: event.x ?? 0,
|
|
833
|
+
y: event.y ?? 0,
|
|
834
|
+
options: Object.freeze(options)
|
|
835
|
+
});
|
|
836
|
+
this.#current = options.length ? menu : null;
|
|
837
|
+
this.client.emit("tip-list", menu, world);
|
|
838
|
+
}
|
|
839
|
+
async #exclusive(action) {
|
|
840
|
+
if (this.#busy) throw new Error("A tip menu operation is already in progress");
|
|
841
|
+
this.#busy = true;
|
|
842
|
+
try {
|
|
843
|
+
return await action();
|
|
844
|
+
} catch (error) {
|
|
845
|
+
this.#current = null;
|
|
846
|
+
this.#target = null;
|
|
847
|
+
throw error;
|
|
848
|
+
} finally {
|
|
849
|
+
this.#busy = false;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
async #open(entity, options) {
|
|
853
|
+
if (!this.client.ready || !this.client.connected) throw new Error("Client must be connected and ready to open tips");
|
|
854
|
+
const timeout = timeoutValue(options);
|
|
855
|
+
const handle = typeof entity === "number" ? this.client.currentShip()?.entities.get(entity) : entity;
|
|
856
|
+
if (!handle || handle.client !== this.client || !handle.exists()) throw new Error("Tip target must be an existing entity on this client");
|
|
857
|
+
const world = this.client.worlds.currentWorldId;
|
|
858
|
+
const scopeWorld = handle.scope === "ship" ? this.client.worlds.shipWorld() : handle.scope === "current" ? this.client.worlds.worlds.get(world) : handle.scope === "overworld" ? this.client.worlds.overworld() : this.client.worlds.worlds.get(Number(handle.scope));
|
|
859
|
+
if (scopeWorld?.id !== world) {
|
|
860
|
+
throw new Error("Tip target must be in the current world");
|
|
861
|
+
}
|
|
862
|
+
const position = handle.position;
|
|
863
|
+
if (!position) throw new Error("Tip target has no position");
|
|
864
|
+
this.#current = null;
|
|
865
|
+
this.#target = { entity: handle.id, world, command: {
|
|
866
|
+
...options.command,
|
|
867
|
+
focus_ent: handle.id,
|
|
868
|
+
mx: position.x,
|
|
869
|
+
my: position.y
|
|
870
|
+
} };
|
|
871
|
+
return waitFor(this.client, "tip-list", () => {
|
|
872
|
+
return this.#current?.entity === handle.id && this.#current.world === world ? this.#current : null;
|
|
873
|
+
}, timeout, "tip menu", () => {
|
|
874
|
+
this.client.send({ ...this.#target.command, act1: false, act2: true, tip_select: null });
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
open(entity, options = {}) {
|
|
878
|
+
return this.#exclusive(() => this.#open(entity, options));
|
|
879
|
+
}
|
|
880
|
+
close(options = {}) {
|
|
881
|
+
return this.#exclusive(async () => {
|
|
882
|
+
const timeout = timeoutValue(options);
|
|
883
|
+
const menu = this.#current;
|
|
884
|
+
if (!menu) return this.client;
|
|
885
|
+
if (!this.client.connected || !this.client.ready) throw new Error("Client must be connected and ready to close tips");
|
|
886
|
+
if (menu.world !== this.client.worlds.currentWorldId) throw new Error("Tip menu belongs to another world");
|
|
887
|
+
await waitFor(this.client, "tip-list", (update) => update?.world === menu.world && update.options.length === 0, timeout, "tip menu dismissal", () => {
|
|
888
|
+
this.client.send({
|
|
889
|
+
...options.command,
|
|
890
|
+
focus_ent: null,
|
|
891
|
+
config_ent: null,
|
|
892
|
+
act1: true,
|
|
893
|
+
act1_held: true,
|
|
894
|
+
act2: false,
|
|
895
|
+
tip_select: null
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
this.#target = null;
|
|
899
|
+
return this.client;
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
select(option, command = {}) {
|
|
903
|
+
if (this.#busy) throw new Error("A tip menu operation is already in progress");
|
|
904
|
+
return this.#select(option, command);
|
|
905
|
+
}
|
|
906
|
+
#select(option, command = {}) {
|
|
907
|
+
if (!this.client.connected || !this.client.ready) throw new Error("Client must be connected and ready to select tips");
|
|
908
|
+
const menu = this.#current;
|
|
909
|
+
if (!menu || menu.entity == null || !this.#target) throw new Error("Open an entity's tip menu before selecting an option");
|
|
910
|
+
if (menu.world !== this.client.worlds.currentWorldId) throw new Error("Tip menu belongs to another world");
|
|
911
|
+
const index = typeof option === "string" ? menu.options.indexOf(option) : option;
|
|
912
|
+
if (!Number.isInteger(index) || index < 0 || index >= menu.options.length) throw new RangeError("Tip option is not in the current menu");
|
|
913
|
+
this.client.send({
|
|
914
|
+
...this.#target.command,
|
|
915
|
+
...command,
|
|
916
|
+
focus_ent: menu.entity,
|
|
917
|
+
act1: false,
|
|
918
|
+
act2: false,
|
|
919
|
+
tip_select: index
|
|
920
|
+
});
|
|
921
|
+
this.#current = null;
|
|
922
|
+
this.#target = null;
|
|
923
|
+
return this.client;
|
|
924
|
+
}
|
|
925
|
+
choose(entity, option, options = {}) {
|
|
926
|
+
return this.#exclusive(async () => {
|
|
927
|
+
await this.#open(entity, options);
|
|
928
|
+
return this.#select(option);
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
setRank(handle, rank, options = {}) {
|
|
932
|
+
return this.#exclusive(async () => {
|
|
933
|
+
const value = normalizePlayerRank(rank);
|
|
934
|
+
const timeout = timeoutValue(options);
|
|
935
|
+
if (!handle.exists()) throw new Error("Rank target no longer exists");
|
|
936
|
+
if (handle.rank === value) return this.client;
|
|
937
|
+
const text = { 0: "Restrict to Guests", 1: "Restrict to Crew", 3: "Restrict to Captains" }[value];
|
|
938
|
+
await this.#open(handle, options);
|
|
939
|
+
await waitFor(
|
|
940
|
+
this.client,
|
|
941
|
+
"model",
|
|
942
|
+
() => handle.rank === value,
|
|
943
|
+
timeout,
|
|
944
|
+
"access rank update",
|
|
945
|
+
() => this.#select(text)
|
|
946
|
+
);
|
|
947
|
+
return this.client;
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
|
|
591
952
|
// src/client/core.js
|
|
592
953
|
init_cookies();
|
|
593
954
|
init_servers();
|
|
@@ -3534,7 +3895,6 @@
|
|
|
3534
3895
|
SHIELD_GENERATOR_BOOST_STATE_NAMES: () => SHIELD_GENERATOR_BOOST_STATE_NAMES,
|
|
3535
3896
|
SIGN_DISPLAY_MODE_NAMES: () => SIGN_DISPLAY_MODE_NAMES,
|
|
3536
3897
|
SIMPLE_LABEL_STATE_SPEC: () => SIMPLE_LABEL_STATE_SPEC,
|
|
3537
|
-
TABLE_78_FIELD_BITS: () => TABLE_78_FIELD_BITS,
|
|
3538
3898
|
TABLE_78_NUMERIC_FIELDS: () => TABLE_78_NUMERIC_FIELDS,
|
|
3539
3899
|
TEAM_RANK_NAMES: () => TEAM_RANK_NAMES,
|
|
3540
3900
|
THRUSTER_FACING_NAMES: () => THRUSTER_FACING_NAMES,
|
|
@@ -3567,7 +3927,6 @@
|
|
|
3567
3927
|
isOrangeFoolBotState: () => isOrangeFoolBotState,
|
|
3568
3928
|
isRedSentryBotState: () => isRedSentryBotState,
|
|
3569
3929
|
isRedSniperBotState: () => isRedSniperBotState,
|
|
3570
|
-
isSemanticLoaderDelta: () => isSemanticLoaderDelta2,
|
|
3571
3930
|
isShieldHelperBotState: () => isShieldHelperBotState,
|
|
3572
3931
|
isShieldMasterBotState: () => isShieldMasterBotState,
|
|
3573
3932
|
isYellowHunterBotState: () => isYellowHunterBotState,
|
|
@@ -3590,914 +3949,61 @@
|
|
|
3590
3949
|
scaledSizeSummary: () => scaledSizeSummary,
|
|
3591
3950
|
summarizeBlueprintPreview: () => summarizeBlueprintPreview,
|
|
3592
3951
|
summarizeBot: () => summarizeBot,
|
|
3593
|
-
summarizeCannon: () => summarizeCannon,
|
|
3594
|
-
summarizeCargoEjector: () => summarizeCargoEjector,
|
|
3595
|
-
summarizeCargoHatch: () => summarizeCargoHatch,
|
|
3596
|
-
summarizeCommsStation: () => summarizeCommsStation,
|
|
3597
|
-
summarizeDockingSpring: () => summarizeDockingSpring,
|
|
3598
|
-
summarizeDoor: () => summarizeDoor,
|
|
3599
|
-
summarizeExpandoBox: () => summarizeExpandoBox,
|
|
3600
|
-
summarizeFabricator: () => summarizeFabricator,
|
|
3601
|
-
summarizeHealth: () => summarizeHealth,
|
|
3602
|
-
summarizeHelm: () => summarizeHelm,
|
|
3603
|
-
summarizeHoverOutline: () => summarizeHoverOutline,
|
|
3604
|
-
summarizeHugeThruster: () => summarizeHugeThruster,
|
|
3605
|
-
summarizeItemCrate: () => summarizeItemCrate,
|
|
3606
|
-
summarizeItemHolder: () => summarizeItemHolder,
|
|
3607
|
-
summarizeItemLauncher: () => summarizeItemLauncher,
|
|
3608
|
-
summarizeLoader: () => summarizeLoader,
|
|
3609
|
-
summarizeMapMarker: () => summarizeMapMarker,
|
|
3610
|
-
summarizeNavigationUnit: () => summarizeNavigationUnit,
|
|
3611
|
-
summarizePlayer: () => summarizePlayer,
|
|
3612
|
-
summarizePlayerPreview: () => summarizePlayerPreview,
|
|
3613
|
-
summarizePusher: () => summarizePusher,
|
|
3614
|
-
summarizePusherBeam: () => summarizePusherBeam,
|
|
3615
|
-
summarizeShieldGenerator: () => summarizeShieldGenerator,
|
|
3616
|
-
summarizeShieldProjector: () => summarizeShieldProjector,
|
|
3617
|
-
summarizeShipControl: () => summarizeShipControl,
|
|
3618
|
-
summarizeShipSize: () => summarizeShipSize,
|
|
3619
|
-
summarizeShipWorldMetadata: () => summarizeShipWorldMetadata,
|
|
3620
|
-
summarizeSign: () => summarizeSign,
|
|
3621
|
-
summarizeSpawnPoint: () => summarizeSpawnPoint,
|
|
3622
|
-
summarizeThruster: () => summarizeThruster
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
[
|
|
3630
|
-
[
|
|
3631
|
-
[
|
|
3632
|
-
[
|
|
3633
|
-
[
|
|
3634
|
-
[
|
|
3635
|
-
[
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
[
|
|
3640
|
-
[
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
[
|
|
3645
|
-
[
|
|
3646
|
-
[
|
|
3647
|
-
|
|
3648
|
-
]);
|
|
3649
|
-
var DEFAULT_LOADER_PRIORITY = 0;
|
|
3650
|
-
var DEFAULT_LOADER_FILTER_MODE = 0;
|
|
3651
|
-
var DEFAULT_LOADER_STACK = 16;
|
|
3652
|
-
var DEFAULT_LOADER_CYCLE = 1;
|
|
3653
|
-
var DEFAULT_LOADER_PICK = 3;
|
|
3654
|
-
var DEFAULT_LOADER_PLACE = 4;
|
|
3655
|
-
var LOADER_CONFIG_NUMERIC_BITS = [1, 2, 4, 8, 16];
|
|
3656
|
-
var LOADER_CONFIG_NUMERIC_FIELDS = ["q20", "q24", "q28", "q32", "q36"];
|
|
3657
|
-
function wrapLoaderPosition(value) {
|
|
3658
|
-
return value == null ? null : (value % 8 + 8) % 8;
|
|
3659
|
-
}
|
|
3660
|
-
function decodeIndexedLoaderSnapshotRecord(loader, mask = 0, cumulative = null, reference = null) {
|
|
3661
|
-
const config = {
|
|
3662
|
-
pick: 3,
|
|
3663
|
-
place: 4,
|
|
3664
|
-
priority: DEFAULT_LOADER_PRIORITY,
|
|
3665
|
-
requireOutput: false,
|
|
3666
|
-
waitForStack: false,
|
|
3667
|
-
stack: DEFAULT_LOADER_STACK,
|
|
3668
|
-
cycle: DEFAULT_LOADER_CYCLE
|
|
3669
|
-
};
|
|
3670
|
-
if (mask & 32) config.requireOutput = true;
|
|
3671
|
-
if (mask & 64) config.waitForStack = true;
|
|
3672
|
-
switch (mask) {
|
|
3673
|
-
case 0:
|
|
3674
|
-
break;
|
|
3675
|
-
case 1:
|
|
3676
|
-
config.pick = wrapLoaderPosition((loader.q20 ?? 0) + 3);
|
|
3677
|
-
if (cumulative?.q40 != null) config.requireOutput = true;
|
|
3678
|
-
break;
|
|
3679
|
-
case 2:
|
|
3680
|
-
if (reference && cumulative?.q40 != null && loader.q24 != null) {
|
|
3681
|
-
if (loader.q24 <= -8) {
|
|
3682
|
-
config.pick = wrapLoaderPosition((reference.pick ?? 3) + 1);
|
|
3683
|
-
config.place = wrapLoaderPosition((reference.place ?? 4) + 3);
|
|
3684
|
-
config.requireOutput = true;
|
|
3685
|
-
} else {
|
|
3686
|
-
config.pick = wrapLoaderPosition((reference.pick ?? 3) + 2);
|
|
3687
|
-
config.place = wrapLoaderPosition((reference.place ?? 4) + 4);
|
|
3688
|
-
}
|
|
3689
|
-
} else {
|
|
3690
|
-
config.place = wrapLoaderPosition((loader.q24 ?? 0) + 4);
|
|
3691
|
-
}
|
|
3692
|
-
break;
|
|
3693
|
-
case 3:
|
|
3694
|
-
config.pick = reference && loader.q24 <= -8 ? wrapLoaderPosition((reference.pick ?? 3) + (loader.q20 ?? 0) + 3) : wrapLoaderPosition((loader.q20 ?? 0) + 3);
|
|
3695
|
-
config.place = wrapLoaderPosition((loader.q24 ?? 0) + 4);
|
|
3696
|
-
if (cumulative?.q44 != null && cumulative?.q36 == null && cumulative?.q40 == null) {
|
|
3697
|
-
config.requireOutput = true;
|
|
3698
|
-
config.waitForStack = true;
|
|
3699
|
-
}
|
|
3700
|
-
break;
|
|
3701
|
-
case 5:
|
|
3702
|
-
config.pick = wrapLoaderPosition((loader.q28 ?? 0) + 1);
|
|
3703
|
-
config.place = wrapLoaderPosition((loader.q28 ?? 0) + 3);
|
|
3704
|
-
break;
|
|
3705
|
-
case 6:
|
|
3706
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 5);
|
|
3707
|
-
config.place = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3708
|
-
config.requireOutput = true;
|
|
3709
|
-
break;
|
|
3710
|
-
case 7:
|
|
3711
|
-
if (reference && (cumulative?.q40 != null || loader.q24 <= -8 || loader.q28 >= 2)) {
|
|
3712
|
-
if (loader.q24 <= -8) {
|
|
3713
|
-
config.pick = wrapLoaderPosition((reference.pick ?? 3) + (loader.q20 ?? 0) + 5);
|
|
3714
|
-
config.place = wrapLoaderPosition(reference.place ?? 4);
|
|
3715
|
-
config.requireOutput = true;
|
|
3716
|
-
config.waitForStack = true;
|
|
3717
|
-
if (loader.q28 != null) config.priority = loader.q28;
|
|
3718
|
-
} else if (loader.q28 >= 2) {
|
|
3719
|
-
config.pick = wrapLoaderPosition((reference.pick ?? 3) + loader.q28);
|
|
3720
|
-
config.place = wrapLoaderPosition((reference.place ?? 4) + (loader.q20 ?? 0));
|
|
3721
|
-
config.priority = loader.q28 - 4;
|
|
3722
|
-
} else if ((loader.q20 ?? 0) >= 3) {
|
|
3723
|
-
config.pick = wrapLoaderPosition((reference.pick ?? 3) + (loader.q20 ?? 0));
|
|
3724
|
-
config.place = wrapLoaderPosition(reference.place ?? 4);
|
|
3725
|
-
config.priority = (loader.q28 ?? 0) + 1;
|
|
3726
|
-
config.requireOutput = Boolean(reference.requireOutput);
|
|
3727
|
-
config.waitForStack = Boolean(reference.waitForStack);
|
|
3728
|
-
} else {
|
|
3729
|
-
config.pick = wrapLoaderPosition((loader.q20 ?? 0) + 2);
|
|
3730
|
-
config.place = wrapLoaderPosition((reference.place ?? 4) + (loader.q24 ?? 0));
|
|
3731
|
-
config.priority = (loader.q28 ?? 0) + 1;
|
|
3732
|
-
}
|
|
3733
|
-
} else {
|
|
3734
|
-
config.pick = wrapLoaderPosition((loader.q20 ?? 0) + 3);
|
|
3735
|
-
config.place = wrapLoaderPosition((loader.q24 ?? 0) + 4);
|
|
3736
|
-
if (loader.q28 != null) config.priority = loader.q28;
|
|
3737
|
-
}
|
|
3738
|
-
break;
|
|
3739
|
-
case 8:
|
|
3740
|
-
config.pick = wrapLoaderPosition((cumulative?.q40 ?? 0) + 4);
|
|
3741
|
-
config.place = wrapLoaderPosition((cumulative?.q28 ?? 0) + 2);
|
|
3742
|
-
config.requireOutput = true;
|
|
3743
|
-
break;
|
|
3744
|
-
case 9:
|
|
3745
|
-
config.pick = wrapLoaderPosition((loader.q20 ?? 0) + 3);
|
|
3746
|
-
config.place = wrapLoaderPosition((cumulative?.q40 ?? 0) + 3);
|
|
3747
|
-
break;
|
|
3748
|
-
case 18:
|
|
3749
|
-
config.pick = wrapLoaderPosition(loader.q24 ?? 0);
|
|
3750
|
-
config.place = wrapLoaderPosition((loader.q36 ?? 0) + 2);
|
|
3751
|
-
if (loader.q36 != null) config.cycle = loader.q36 / 20 + 1;
|
|
3752
|
-
break;
|
|
3753
|
-
case 32:
|
|
3754
|
-
break;
|
|
3755
|
-
case 65:
|
|
3756
|
-
config.pick = wrapLoaderPosition((loader.q44 ?? 0) + 3);
|
|
3757
|
-
break;
|
|
3758
|
-
case 33:
|
|
3759
|
-
config.pick = wrapLoaderPosition((loader.q40 ?? 0) + 3);
|
|
3760
|
-
config.place = wrapLoaderPosition((loader.q20 ?? 0) + 4);
|
|
3761
|
-
break;
|
|
3762
|
-
case 34:
|
|
3763
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3764
|
-
config.place = wrapLoaderPosition((loader.q40 ?? 0) + 4);
|
|
3765
|
-
break;
|
|
3766
|
-
case 35:
|
|
3767
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3768
|
-
config.place = wrapLoaderPosition((loader.q40 ?? 0) + 4);
|
|
3769
|
-
break;
|
|
3770
|
-
case 67:
|
|
3771
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3772
|
-
config.place = wrapLoaderPosition((loader.q44 ?? 0) + 4);
|
|
3773
|
-
break;
|
|
3774
|
-
case 95:
|
|
3775
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3776
|
-
config.place = wrapLoaderPosition((loader.q28 ?? 0) + 4);
|
|
3777
|
-
if (loader.q32 != null) config.priority = loader.q32;
|
|
3778
|
-
if (loader.q36 != null) config.stack = DEFAULT_LOADER_STACK + loader.q36;
|
|
3779
|
-
if (loader.q44 != null) config.cycle = loader.q44 / 20 + 1;
|
|
3780
|
-
break;
|
|
3781
|
-
case 98:
|
|
3782
|
-
config.place = wrapLoaderPosition((loader.q40 ?? 0) + 4);
|
|
3783
|
-
break;
|
|
3784
|
-
case 99:
|
|
3785
|
-
config.pick = wrapLoaderPosition((loader.q24 ?? 0) + 3);
|
|
3786
|
-
config.place = wrapLoaderPosition((loader.q40 ?? 0) + 4);
|
|
3787
|
-
break;
|
|
3788
|
-
case 126:
|
|
3789
|
-
config.pick = wrapLoaderPosition(loader.q28 ?? 0);
|
|
3790
|
-
config.place = wrapLoaderPosition(loader.q24 ?? 0);
|
|
3791
|
-
if (loader.q32 != null) config.priority = loader.q32;
|
|
3792
|
-
if (loader.q36 != null) config.stack = DEFAULT_LOADER_STACK + loader.q36;
|
|
3793
|
-
if (loader.q40 != null) config.cycle = loader.q40 / 20 + 1;
|
|
3794
|
-
break;
|
|
3795
|
-
default:
|
|
3796
|
-
return null;
|
|
3797
|
-
}
|
|
3798
|
-
return config;
|
|
3799
|
-
}
|
|
3800
|
-
function decodeLoaderSnapshotRecord(loader, mask = loader?.lastMask ?? 0) {
|
|
3801
|
-
if (!loader) return null;
|
|
3802
|
-
const hasRequireOutput = Boolean(mask & 32);
|
|
3803
|
-
const hasWaitForStack = Boolean(mask & 64);
|
|
3804
|
-
const hasFlag = hasRequireOutput || hasWaitForStack;
|
|
3805
|
-
const slots = [];
|
|
3806
|
-
for (const [index, bit] of LOADER_CONFIG_NUMERIC_BITS.entries()) {
|
|
3807
|
-
if (!(mask & bit)) continue;
|
|
3808
|
-
const value = loader[LOADER_CONFIG_NUMERIC_FIELDS[index]];
|
|
3809
|
-
if (value == null) return null;
|
|
3810
|
-
slots.push(value);
|
|
3811
|
-
}
|
|
3812
|
-
if (hasRequireOutput) {
|
|
3813
|
-
if (loader.q40 == null) return null;
|
|
3814
|
-
slots.push(loader.q40);
|
|
3815
|
-
} else if (hasWaitForStack) {
|
|
3816
|
-
if (loader.q44 == null) return null;
|
|
3817
|
-
slots.push(loader.q44);
|
|
3818
|
-
}
|
|
3819
|
-
if (hasFlag && slots.length) slots.shift();
|
|
3820
|
-
const config = {
|
|
3821
|
-
pick: 3,
|
|
3822
|
-
place: 4,
|
|
3823
|
-
priority: DEFAULT_LOADER_PRIORITY,
|
|
3824
|
-
requireOutput: hasRequireOutput,
|
|
3825
|
-
waitForStack: hasWaitForStack,
|
|
3826
|
-
stack: DEFAULT_LOADER_STACK,
|
|
3827
|
-
cycle: DEFAULT_LOADER_CYCLE
|
|
3828
|
-
};
|
|
3829
|
-
if (mask & 1) {
|
|
3830
|
-
if (!slots.length) return null;
|
|
3831
|
-
config.pick = wrapLoaderPosition(slots.shift() + 3);
|
|
3832
|
-
}
|
|
3833
|
-
if (mask & 2) {
|
|
3834
|
-
if (!slots.length) return null;
|
|
3835
|
-
config.place = wrapLoaderPosition(slots.shift() + 4);
|
|
3836
|
-
}
|
|
3837
|
-
if (mask & 4) {
|
|
3838
|
-
if (!slots.length) return null;
|
|
3839
|
-
config.priority = slots.shift();
|
|
3840
|
-
}
|
|
3841
|
-
if (mask & 8) {
|
|
3842
|
-
if (!slots.length) return null;
|
|
3843
|
-
config.stack = DEFAULT_LOADER_STACK + slots.shift();
|
|
3844
|
-
}
|
|
3845
|
-
if (mask & 16) {
|
|
3846
|
-
if (!slots.length) return null;
|
|
3847
|
-
config.cycle = slots.shift() / 20 + 1;
|
|
3848
|
-
}
|
|
3849
|
-
return config;
|
|
3850
|
-
}
|
|
3851
|
-
function decodeLoaderSemanticDeltaRecord(loader, mask = loader?.lastMask ?? 0) {
|
|
3852
|
-
if (!loader) return null;
|
|
3853
|
-
const hasRequireOutput = Boolean(mask & 32);
|
|
3854
|
-
const hasWaitForStack = Boolean(mask & 64);
|
|
3855
|
-
if (!hasRequireOutput && !hasWaitForStack) return null;
|
|
3856
|
-
const slots = [];
|
|
3857
|
-
for (const [index, bit] of LOADER_CONFIG_NUMERIC_BITS.entries()) {
|
|
3858
|
-
if (!(mask & bit)) continue;
|
|
3859
|
-
slots.push(loader[LOADER_CONFIG_NUMERIC_FIELDS[index]] ?? 0);
|
|
3860
|
-
}
|
|
3861
|
-
if (hasRequireOutput) slots.push(loader.q40 ?? 0);
|
|
3862
|
-
else if (hasWaitForStack) slots.push(loader.q44 ?? 0);
|
|
3863
|
-
if (slots.length) slots.shift();
|
|
3864
|
-
const config = {};
|
|
3865
|
-
if (mask & 1) config.pick = slots.shift() ?? 0;
|
|
3866
|
-
if (mask & 2) config.place = slots.shift() ?? 0;
|
|
3867
|
-
if (mask & 4) config.priority = slots.shift() ?? 0;
|
|
3868
|
-
if (mask & 8) config.stack = slots.shift() ?? 0;
|
|
3869
|
-
if (mask & 16) config.cycleTicks = slots.shift() ?? 0;
|
|
3870
|
-
config.requireOutput = hasRequireOutput;
|
|
3871
|
-
config.waitForStack = hasWaitForStack;
|
|
3872
|
-
return config;
|
|
3873
|
-
}
|
|
3874
|
-
function loaderDeltaRecord(loader, mask, previous) {
|
|
3875
|
-
const record = { lastMask: mask };
|
|
3876
|
-
for (const [field, bit] of [
|
|
3877
|
-
["q20", 1],
|
|
3878
|
-
["q24", 2],
|
|
3879
|
-
["q28", 4],
|
|
3880
|
-
["q32", 8],
|
|
3881
|
-
["q36", 16],
|
|
3882
|
-
["q40", 32],
|
|
3883
|
-
["q44", 64]
|
|
3884
|
-
]) {
|
|
3885
|
-
if (!(mask & bit)) continue;
|
|
3886
|
-
if (field === "q44" && (mask & 32 || loader?.q44 == null)) continue;
|
|
3887
|
-
record[field] = (loader?.[field] ?? 0) - (previous?.[field] ?? 0);
|
|
3888
|
-
}
|
|
3889
|
-
return record;
|
|
3890
|
-
}
|
|
3891
|
-
function isSemanticLoaderDelta(changed, full) {
|
|
3892
|
-
return !full && changed.previous != null && (changed.mask & 96) === 96;
|
|
3893
|
-
}
|
|
3894
|
-
function filterSlotValue(value) {
|
|
3895
|
-
return value == null || value === 0 ? null : value;
|
|
3896
|
-
}
|
|
3897
|
-
var LoaderConfigTracker = class {
|
|
3898
|
-
constructor() {
|
|
3899
|
-
this.pickBases = /* @__PURE__ */ new Map();
|
|
3900
|
-
this.pickDeltaBases = /* @__PURE__ */ new Map();
|
|
3901
|
-
this.placeBases = /* @__PURE__ */ new Map();
|
|
3902
|
-
this.placeDeltaBases = /* @__PURE__ */ new Map();
|
|
3903
|
-
this.currentPicks = /* @__PURE__ */ new Map();
|
|
3904
|
-
this.currentPlaces = /* @__PURE__ */ new Map();
|
|
3905
|
-
this.sparsePositionBaselines = /* @__PURE__ */ new Set();
|
|
3906
|
-
this.priorities = /* @__PURE__ */ new Map();
|
|
3907
|
-
this.priorityOffsets = /* @__PURE__ */ new Map();
|
|
3908
|
-
this.filterModes = /* @__PURE__ */ new Map();
|
|
3909
|
-
this.filterSources = /* @__PURE__ */ new Map();
|
|
3910
|
-
this.requireOutputs = /* @__PURE__ */ new Map();
|
|
3911
|
-
this.waitForStacks = /* @__PURE__ */ new Map();
|
|
3912
|
-
this.stackBases = /* @__PURE__ */ new Map();
|
|
3913
|
-
this.stackSources = /* @__PURE__ */ new Map();
|
|
3914
|
-
this.cycles = /* @__PURE__ */ new Map();
|
|
3915
|
-
this.cycleModes = /* @__PURE__ */ new Map();
|
|
3916
|
-
this.cycleDeltaBases = /* @__PURE__ */ new Map();
|
|
3917
|
-
this.directCycleValues = /* @__PURE__ */ new Map();
|
|
3918
|
-
this.directCycleFields = /* @__PURE__ */ new Map();
|
|
3919
|
-
}
|
|
3920
|
-
updateFromModel(update) {
|
|
3921
|
-
const world = update?.world;
|
|
3922
|
-
const model = update?.result?.model;
|
|
3923
|
-
if (!world || !model) return;
|
|
3924
|
-
const seenEntities = /* @__PURE__ */ new Set();
|
|
3925
|
-
for (const section of model.sections || []) {
|
|
3926
|
-
if (section.table !== 78) continue;
|
|
3927
|
-
for (const changed of section.records || []) {
|
|
3928
|
-
if (changed.indexedLoaderConfig) {
|
|
3929
|
-
this.updateIndexedSnapshotRecord(world.id, changed.entity, changed.record, changed.mask, changed.cumulativeRecord, changed.configEntity);
|
|
3930
|
-
continue;
|
|
3931
|
-
}
|
|
3932
|
-
const loader = changed.record ?? world.model.record(78, changed.entity);
|
|
3933
|
-
this.updateRecord(world.id, changed.entity, loader, changed.mask, changed.previous, {
|
|
3934
|
-
repeatedInUpdate: seenEntities.has(changed.entity),
|
|
3935
|
-
repeatedInSection: changed.repeatedInSection,
|
|
3936
|
-
semanticSnapshot: Boolean(model.full),
|
|
3937
|
-
semanticDelta: isSemanticLoaderDelta(changed, model.full),
|
|
3938
|
-
deltaRecord: loaderDeltaRecord(loader, changed.mask, changed.previous)
|
|
3939
|
-
});
|
|
3940
|
-
seenEntities.add(changed.entity);
|
|
3941
|
-
}
|
|
3942
|
-
}
|
|
3943
|
-
}
|
|
3944
|
-
updateRecord(worldId, entityId, loader, mask = 0, previous = null, options = {}) {
|
|
3945
|
-
if (!loader) return;
|
|
3946
|
-
const key = this.#key(worldId, entityId);
|
|
3947
|
-
const hasTrackedConfig = this.#hasTrackedConfig(key);
|
|
3948
|
-
if (hasTrackedConfig && (options.repeatedInSection || options.repeatedInUpdate) && this.sparsePositionBaselines.has(key) && this.hasPositionConfig(worldId, entityId)) {
|
|
3949
|
-
return;
|
|
3950
|
-
}
|
|
3951
|
-
if (!hasTrackedConfig && this.#isDirectPositionCycleBaseline(loader, mask)) {
|
|
3952
|
-
this.pickBases.set(key, 3);
|
|
3953
|
-
this.pickDeltaBases.set(key, 0);
|
|
3954
|
-
this.placeBases.set(key, 4);
|
|
3955
|
-
this.placeDeltaBases.set(key, 0);
|
|
3956
|
-
this.#setCurrentPosition(key, loader);
|
|
3957
|
-
if (mask & 4 && loader.q28 >= -1 && loader.q28 <= 1) this.priorities.set(key, loader.q28);
|
|
3958
|
-
this.requireOutputs.set(key, Boolean(mask & 32));
|
|
3959
|
-
this.waitForStacks.set(key, Boolean(mask & 64));
|
|
3960
|
-
this.stackBases.set(key, 16);
|
|
3961
|
-
this.stackSources.delete(key);
|
|
3962
|
-
this.cycleModes.set(key, "direct");
|
|
3963
|
-
this.cycleDeltaBases.set(key, 0);
|
|
3964
|
-
this.directCycleValues.set(key, loader.q44 ?? loader.q36);
|
|
3965
|
-
this.directCycleFields.set(key, loader.q44 == null ? "q36" : "q44");
|
|
3966
|
-
this.cycles.set(key, (loader.q44 ?? loader.q36) / 20 + 1);
|
|
3967
|
-
return;
|
|
3968
|
-
}
|
|
3969
|
-
if (!hasTrackedConfig && options.allowSparseBaseline && this.#isSparsePositionBaseline(loader, mask)) {
|
|
3970
|
-
this.#applySparsePositionBaseline(key, loader, mask);
|
|
3971
|
-
return;
|
|
3972
|
-
}
|
|
3973
|
-
const baseline = hasTrackedConfig ? null : this.#loaderBaseline(loader, mask, options.semanticSnapshot);
|
|
3974
|
-
if (hasTrackedConfig && options.semanticDelta && this.#applySemanticDelta(worldId, entityId, loader, mask, previous, options.deltaRecord)) {
|
|
3975
|
-
return;
|
|
3976
|
-
}
|
|
3977
|
-
const hasInitialConfigFields = baseline || mask & 31 && (mask & 32 || mask & 64 && mask & 4);
|
|
3978
|
-
if (!hasTrackedConfig && hasInitialConfigFields && mask !== 32 && mask !== 64) {
|
|
3979
|
-
if (baseline) this.#applyLoaderBaseline(key, loader, baseline);
|
|
3980
|
-
else {
|
|
3981
|
-
const usedQ28AsPositionBase = this.#initializePositionBaseline(key, loader, mask);
|
|
3982
|
-
if (mask & 4 && loader.q28 != null) {
|
|
3983
|
-
if (usedQ28AsPositionBase) this.#initializePriorityOffset(key, loader);
|
|
3984
|
-
else this.priorities.set(key, loader.q28);
|
|
3985
|
-
}
|
|
3986
|
-
}
|
|
3987
|
-
this.requireOutputs.set(key, Boolean(mask & 32));
|
|
3988
|
-
this.waitForStacks.set(key, Boolean(mask & 64));
|
|
3989
|
-
if (!this.stackBases.has(key)) this.#initializeStackBaseline(key, loader);
|
|
3990
|
-
if (!this.cycles.has(key)) this.#initializeCycleBaseline(key, loader);
|
|
3991
|
-
return;
|
|
3992
|
-
}
|
|
3993
|
-
const q44CycleChanged = mask & 64 && this.#usesQ44CycleBase(key) && loader.q44 != null && (this.#fieldChanged(previous, loader, "q44") || this.directCycleValues.has(key) && loader.q44 !== this.directCycleValues.get(key));
|
|
3994
|
-
const q40DirectCycleChanged = mask & 32 && this.cycleModes.get(key) === "q40-direct" && loader.q40 != null && (this.#fieldChanged(previous, loader, "q40") || this.directCycleValues.has(key) && loader.q40 !== this.directCycleValues.get(key));
|
|
3995
|
-
if (q44CycleChanged) {
|
|
3996
|
-
this.directCycleValues.set(key, loader.q44);
|
|
3997
|
-
this.#updateCycle(key, loader);
|
|
3998
|
-
} else if (q40DirectCycleChanged) {
|
|
3999
|
-
this.directCycleValues.set(key, loader.q40);
|
|
4000
|
-
this.#updateCycle(key, loader);
|
|
4001
|
-
} else if (mask & 32 && mask === 32) {
|
|
4002
|
-
this.requireOutputs.set(key, !this.requireOutputs.get(key));
|
|
4003
|
-
} else if (mask & 32 && !this.requireOutputs.has(key)) {
|
|
4004
|
-
this.requireOutputs.set(key, true);
|
|
4005
|
-
}
|
|
4006
|
-
if (!q44CycleChanged) {
|
|
4007
|
-
if (mask & 64 && mask === 64) this.waitForStacks.set(key, !this.waitForStacks.get(key));
|
|
4008
|
-
else if (mask & 64 && !this.waitForStacks.has(key)) this.waitForStacks.set(key, true);
|
|
4009
|
-
}
|
|
4010
|
-
if (mask & 4 && loader.q28 != null) this.priorities.set(key, this.#priority(key, loader.q28));
|
|
4011
|
-
if (mask & 8 && this.filterSources.get(key) === "q32" && loader.q32 != null) this.filterModes.set(key, loader.q32);
|
|
4012
|
-
const q32FilterOnlyUpdate = this.filterSources.get(key) === "q32" && mask === 8;
|
|
4013
|
-
if (mask & 8 && !options.semanticDelta && !q32FilterOnlyUpdate && loader.q32 != null && this.stackBases.has(key)) {
|
|
4014
|
-
const previousConfig = this.getConfig(worldId, entityId, previous);
|
|
4015
|
-
this.stackBases.set(key, previousConfig.stack - (previous?.q32 ?? 0));
|
|
4016
|
-
this.stackSources.set(key, "q32");
|
|
4017
|
-
}
|
|
4018
|
-
if (mask & 16) this.#updateCycle(key, loader);
|
|
4019
|
-
if (mask & 3 && this.hasPositionConfig(worldId, entityId)) this.#setCurrentPosition(key, loader);
|
|
4020
|
-
}
|
|
4021
|
-
updateIndexedSnapshotRecord(worldId, entityId, loader, mask = 0, cumulative = null, configEntity = null) {
|
|
4022
|
-
if (!loader) return false;
|
|
4023
|
-
const reference = configEntity == null || Number(configEntity) === Number(entityId) ? null : this.#trackedConfig(worldId, configEntity);
|
|
4024
|
-
const config = decodeIndexedLoaderSnapshotRecord(loader, mask, cumulative, reference);
|
|
4025
|
-
if (!config) return false;
|
|
4026
|
-
const key = this.#key(worldId, entityId);
|
|
4027
|
-
this.pickBases.set(key, config.pick);
|
|
4028
|
-
this.pickDeltaBases.set(key, loader.q20 ?? 0);
|
|
4029
|
-
this.placeBases.set(key, config.place);
|
|
4030
|
-
this.placeDeltaBases.set(key, loader.q24 ?? 0);
|
|
4031
|
-
this.currentPicks.set(key, config.pick);
|
|
4032
|
-
this.currentPlaces.set(key, config.place);
|
|
4033
|
-
this.sparsePositionBaselines.delete(key);
|
|
4034
|
-
this.priorities.set(key, config.priority);
|
|
4035
|
-
if (mask === 95 && loader.q28 != null) this.priorityOffsets.set(key, config.priority - loader.q28);
|
|
4036
|
-
else this.priorityOffsets.delete(key);
|
|
4037
|
-
this.filterModes.delete(key);
|
|
4038
|
-
this.filterSources.delete(key);
|
|
4039
|
-
this.requireOutputs.set(key, config.requireOutput);
|
|
4040
|
-
this.waitForStacks.set(key, config.waitForStack);
|
|
4041
|
-
this.stackBases.set(key, config.stack - (loader.q32 ?? 0));
|
|
4042
|
-
this.stackSources.delete(key);
|
|
4043
|
-
this.cycles.set(key, config.cycle);
|
|
4044
|
-
if (mask === 95) {
|
|
4045
|
-
this.cycleModes.set(key, "q44-q36-delta");
|
|
4046
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4047
|
-
this.directCycleValues.set(key, loader.q44);
|
|
4048
|
-
this.directCycleFields.set(key, "q44");
|
|
4049
|
-
} else if (mask === 126) {
|
|
4050
|
-
this.cycleModes.set(key, "offset");
|
|
4051
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4052
|
-
this.directCycleValues.delete(key);
|
|
4053
|
-
this.directCycleFields.delete(key);
|
|
4054
|
-
} else {
|
|
4055
|
-
this.cycleModes.set(key, "direct");
|
|
4056
|
-
this.cycleDeltaBases.set(key, 0);
|
|
4057
|
-
}
|
|
4058
|
-
if (loader.q36 != null && mask === 18) {
|
|
4059
|
-
this.directCycleValues.set(key, loader.q36);
|
|
4060
|
-
this.directCycleFields.set(key, "q36");
|
|
4061
|
-
} else if (mask !== 95 && mask !== 126) {
|
|
4062
|
-
this.directCycleValues.delete(key);
|
|
4063
|
-
this.directCycleFields.delete(key);
|
|
4064
|
-
}
|
|
4065
|
-
return true;
|
|
4066
|
-
}
|
|
4067
|
-
delete(worldId, entityId) {
|
|
4068
|
-
const key = this.#key(worldId, entityId);
|
|
4069
|
-
this.pickBases.delete(key);
|
|
4070
|
-
this.pickDeltaBases.delete(key);
|
|
4071
|
-
this.placeBases.delete(key);
|
|
4072
|
-
this.placeDeltaBases.delete(key);
|
|
4073
|
-
this.currentPicks.delete(key);
|
|
4074
|
-
this.currentPlaces.delete(key);
|
|
4075
|
-
this.sparsePositionBaselines.delete(key);
|
|
4076
|
-
this.priorities.delete(key);
|
|
4077
|
-
this.priorityOffsets.delete(key);
|
|
4078
|
-
this.filterModes.delete(key);
|
|
4079
|
-
this.filterSources.delete(key);
|
|
4080
|
-
this.requireOutputs.delete(key);
|
|
4081
|
-
this.waitForStacks.delete(key);
|
|
4082
|
-
this.stackBases.delete(key);
|
|
4083
|
-
this.stackSources.delete(key);
|
|
4084
|
-
this.cycles.delete(key);
|
|
4085
|
-
this.cycleModes.delete(key);
|
|
4086
|
-
this.cycleDeltaBases.delete(key);
|
|
4087
|
-
this.directCycleValues.delete(key);
|
|
4088
|
-
this.directCycleFields.delete(key);
|
|
4089
|
-
}
|
|
4090
|
-
getConfig(worldId, entityId, loader, loaderFilter = null, filterSlots = null) {
|
|
4091
|
-
const key = this.#key(worldId, entityId);
|
|
4092
|
-
const pick = this.currentPicks.has(key) ? this.currentPicks.get(key) : this.#pick(key, loader);
|
|
4093
|
-
const place = this.currentPlaces.has(key) ? this.currentPlaces.get(key) : this.#place(key, loader);
|
|
4094
|
-
const stackBase = this.stackBases.get(key) ?? 16;
|
|
4095
|
-
const stackSource = this.stackSources.get(key) ?? "q32";
|
|
4096
|
-
const stackField = stackSource === "fixed" ? null : loader?.[stackSource];
|
|
4097
|
-
const stack = stackField == null ? this.stackBases.has(key) || this.hasPositionConfig(worldId, entityId) ? stackBase : null : stackBase + stackField;
|
|
4098
|
-
const cycle = this.cycles.has(key) ? this.cycles.get(key) : loader?.q40 == null || loader.q36 == null ? null : (loader.q40 + loader.q36) / 20 + 1;
|
|
4099
|
-
return {
|
|
4100
|
-
pick,
|
|
4101
|
-
place,
|
|
4102
|
-
priority: this.priorities.has(key) ? this.priorities.get(key) : DEFAULT_LOADER_PRIORITY,
|
|
4103
|
-
requireOutput: this.requireOutputs.has(key) ? this.requireOutputs.get(key) : false,
|
|
4104
|
-
waitForStack: this.waitForStacks.has(key) ? this.waitForStacks.get(key) : false,
|
|
4105
|
-
stack: stack ?? DEFAULT_LOADER_STACK,
|
|
4106
|
-
cycle: cycle ?? DEFAULT_LOADER_CYCLE,
|
|
4107
|
-
filterMode: loaderFilter ? loaderFilter.q20 ?? DEFAULT_LOADER_FILTER_MODE : this.#filterMode(key, loader) ?? DEFAULT_LOADER_FILTER_MODE,
|
|
4108
|
-
filterSlots: filterSlots ? [filterSlotValue(filterSlots.q20), filterSlotValue(filterSlots.q24), filterSlotValue(filterSlots.q28)] : null
|
|
4109
|
-
};
|
|
4110
|
-
}
|
|
4111
|
-
hasPositionConfig(worldId, entityId) {
|
|
4112
|
-
const key = this.#key(worldId, entityId);
|
|
4113
|
-
return this.pickBases.has(key) && this.placeBases.has(key);
|
|
4114
|
-
}
|
|
4115
|
-
#hasTrackedConfig(key) {
|
|
4116
|
-
return this.pickBases.has(key) || this.placeBases.has(key) || this.priorities.has(key) || this.priorityOffsets.has(key) || this.filterModes.has(key) || this.requireOutputs.has(key) || this.waitForStacks.has(key) || this.stackBases.has(key) || this.cycles.has(key);
|
|
4117
|
-
}
|
|
4118
|
-
#fieldChanged(previous, loader, field) {
|
|
4119
|
-
return previous != null && loader != null && previous[field] !== loader[field];
|
|
4120
|
-
}
|
|
4121
|
-
#usesQ44CycleBase(key) {
|
|
4122
|
-
const mode = this.cycleModes.get(key);
|
|
4123
|
-
return mode === "q44-q36-delta";
|
|
4124
|
-
}
|
|
4125
|
-
#initializePositionBaseline(key, loader, mask) {
|
|
4126
|
-
const hasQ28PositionBase = loader.q28 != null && mask & 4;
|
|
4127
|
-
if (loader.q24 != null) {
|
|
4128
|
-
this.pickBases.set(key, wrapLoaderPosition(loader.q24 + 3));
|
|
4129
|
-
this.pickDeltaBases.set(key, loader.q20 ?? 0);
|
|
4130
|
-
this.placeDeltaBases.set(key, loader.q24);
|
|
4131
|
-
const initialPlace = hasQ28PositionBase ? loader.q28 + 4 : loader.q36 == null ? null : loader.q36 + 4;
|
|
4132
|
-
if (initialPlace != null) this.placeBases.set(key, wrapLoaderPosition(initialPlace));
|
|
4133
|
-
return hasQ28PositionBase;
|
|
4134
|
-
}
|
|
4135
|
-
if (hasQ28PositionBase) {
|
|
4136
|
-
this.pickBases.set(key, wrapLoaderPosition(loader.q28 + 3));
|
|
4137
|
-
this.pickDeltaBases.set(key, 0);
|
|
4138
|
-
this.placeBases.set(key, 4);
|
|
4139
|
-
this.placeDeltaBases.set(key, 0);
|
|
4140
|
-
return true;
|
|
4141
|
-
}
|
|
4142
|
-
if (loader.q20 != null && loader.q36 != null) {
|
|
4143
|
-
this.pickBases.set(key, wrapLoaderPosition(loader.q36 + 3));
|
|
4144
|
-
this.pickDeltaBases.set(key, 0);
|
|
4145
|
-
this.placeBases.set(key, 4);
|
|
4146
|
-
this.placeDeltaBases.set(key, 0);
|
|
4147
|
-
}
|
|
4148
|
-
return false;
|
|
4149
|
-
}
|
|
4150
|
-
#initializeCycleBaseline(key, loader) {
|
|
4151
|
-
if (loader?.q44 != null && (loader.q36 == null || loader.q40 == null)) {
|
|
4152
|
-
this.cycleModes.set(key, "q44-q36-delta");
|
|
4153
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4154
|
-
this.directCycleValues.set(key, loader.q44);
|
|
4155
|
-
this.directCycleFields.set(key, "q44");
|
|
4156
|
-
this.cycles.set(key, loader.q44 / 20 + 1);
|
|
4157
|
-
return;
|
|
4158
|
-
}
|
|
4159
|
-
if (loader?.q40 == null || loader.q36 == null) return;
|
|
4160
|
-
this.cycleModes.set(key, "offset");
|
|
4161
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4162
|
-
this.directCycleValues.delete(key);
|
|
4163
|
-
this.directCycleFields.delete(key);
|
|
4164
|
-
this.cycles.set(key, loader.q40 / 20 + 1);
|
|
4165
|
-
}
|
|
4166
|
-
#initializeStackBaseline(key, loader) {
|
|
4167
|
-
if (this.stackBases.has(key)) return;
|
|
4168
|
-
if (loader?.q32 == null) return;
|
|
4169
|
-
const baseline = this.#loaderBaseline(loader, loader?.lastMask);
|
|
4170
|
-
if (baseline) {
|
|
4171
|
-
this.stackBases.set(key, baseline.stack - loader.q32);
|
|
4172
|
-
return;
|
|
4173
|
-
}
|
|
4174
|
-
if (loader.q20 == null && loader.q24 == null && loader.q28 == null && loader.q36 != null) {
|
|
4175
|
-
this.stackBases.set(key, 17 + loader.q36);
|
|
4176
|
-
return;
|
|
4177
|
-
}
|
|
4178
|
-
this.stackBases.set(key, 16);
|
|
4179
|
-
}
|
|
4180
|
-
#initializePriorityOffset(key, loader) {
|
|
4181
|
-
if (loader?.q28 == null || loader?.q36 == null) return;
|
|
4182
|
-
const offset = loader.q36 + 2;
|
|
4183
|
-
const priority = loader.q28 + offset;
|
|
4184
|
-
if (priority < -1 || priority > 1) return;
|
|
4185
|
-
this.priorityOffsets.set(key, offset);
|
|
4186
|
-
this.priorities.set(key, priority);
|
|
4187
|
-
}
|
|
4188
|
-
#priority(key, q28) {
|
|
4189
|
-
return q28 + (this.priorityOffsets.get(key) ?? 0);
|
|
4190
|
-
}
|
|
4191
|
-
#updateCycle(key, loader) {
|
|
4192
|
-
const mode = this.cycleModes.get(key);
|
|
4193
|
-
if (mode === "direct") {
|
|
4194
|
-
if (loader?.q36 != null) {
|
|
4195
|
-
this.directCycleValues.set(key, loader.q36);
|
|
4196
|
-
this.directCycleFields.set(key, "q36");
|
|
4197
|
-
this.cycles.set(key, loader.q36 / 20 + 1);
|
|
4198
|
-
} else if (loader?.q44 != null) {
|
|
4199
|
-
this.directCycleValues.set(key, loader.q44);
|
|
4200
|
-
this.directCycleFields.set(key, "q44");
|
|
4201
|
-
this.cycles.set(key, loader.q44 / 20 + 1);
|
|
4202
|
-
}
|
|
4203
|
-
return;
|
|
4204
|
-
}
|
|
4205
|
-
if (mode === "q44-q36-delta") {
|
|
4206
|
-
const base = loader?.q44 ?? this.directCycleValues.get(key);
|
|
4207
|
-
if (base != null) {
|
|
4208
|
-
this.directCycleValues.set(key, base);
|
|
4209
|
-
this.directCycleFields.set(key, "q44");
|
|
4210
|
-
const q36 = loader?.q36 ?? 0;
|
|
4211
|
-
this.cycles.set(key, base < 0 && loader?.q36 != null ? q36 / 20 + 1 : (base + q36 - (this.cycleDeltaBases.get(key) ?? 0)) / 20 + 1);
|
|
4212
|
-
}
|
|
4213
|
-
return;
|
|
4214
|
-
}
|
|
4215
|
-
if (mode === "q40-direct") {
|
|
4216
|
-
if (loader?.q40 != null) {
|
|
4217
|
-
this.directCycleValues.set(key, loader.q40);
|
|
4218
|
-
this.directCycleFields.set(key, "q40");
|
|
4219
|
-
this.cycles.set(key, loader.q40 / 20 + 1);
|
|
4220
|
-
}
|
|
4221
|
-
return;
|
|
4222
|
-
}
|
|
4223
|
-
if (loader?.q40 == null) {
|
|
4224
|
-
if (loader?.q44 != null || loader?.q36 != null) this.cycles.set(key, (loader.q44 ?? loader.q36) / 20 + 1);
|
|
4225
|
-
return;
|
|
4226
|
-
}
|
|
4227
|
-
const deltaBase = this.cycleDeltaBases.get(key) ?? 0;
|
|
4228
|
-
this.cycles.set(key, (loader.q40 + (loader.q36 ?? 0) - deltaBase) / 20 + 1);
|
|
4229
|
-
}
|
|
4230
|
-
#isDirectPositionCycleBaseline(loader, mask) {
|
|
4231
|
-
return (mask & 19) === 19 && loader.q20 != null && loader.q24 != null && loader.q36 != null && loader.q40 == null && loader.q44 == null;
|
|
4232
|
-
}
|
|
4233
|
-
#trackedConfig(worldId, entityId) {
|
|
4234
|
-
const key = this.#key(worldId, entityId);
|
|
4235
|
-
if (!this.#hasTrackedConfig(key)) return null;
|
|
4236
|
-
return {
|
|
4237
|
-
pick: this.currentPicks.has(key) ? this.currentPicks.get(key) : this.pickBases.get(key),
|
|
4238
|
-
place: this.currentPlaces.has(key) ? this.currentPlaces.get(key) : this.placeBases.get(key),
|
|
4239
|
-
priority: this.priorities.get(key) ?? DEFAULT_LOADER_PRIORITY,
|
|
4240
|
-
requireOutput: this.requireOutputs.get(key) ?? false,
|
|
4241
|
-
waitForStack: this.waitForStacks.get(key) ?? false,
|
|
4242
|
-
stack: this.stackBases.get(key) ?? DEFAULT_LOADER_STACK,
|
|
4243
|
-
cycle: this.cycles.get(key) ?? DEFAULT_LOADER_CYCLE
|
|
4244
|
-
};
|
|
4245
|
-
}
|
|
4246
|
-
#isSparsePositionBaseline(loader, mask) {
|
|
4247
|
-
return (mask & 3) === 3 && loader.q20 != null && loader.q24 != null && loader.q28 == null && loader.q32 == null && loader.q36 == null && loader.q44 == null;
|
|
4248
|
-
}
|
|
4249
|
-
#applySparsePositionBaseline(key, loader, mask) {
|
|
4250
|
-
const pickField = loader.q40 == null ? loader.q20 : loader.q24;
|
|
4251
|
-
const placeField = loader.q40 == null ? loader.q24 : loader.q40;
|
|
4252
|
-
const pick = wrapLoaderPosition(pickField + 3);
|
|
4253
|
-
const place = wrapLoaderPosition(placeField + 4);
|
|
4254
|
-
this.pickBases.set(key, pick);
|
|
4255
|
-
this.pickDeltaBases.set(key, loader.q20 ?? 0);
|
|
4256
|
-
this.placeBases.set(key, place);
|
|
4257
|
-
this.placeDeltaBases.set(key, loader.q24 ?? 0);
|
|
4258
|
-
this.currentPicks.set(key, pick);
|
|
4259
|
-
this.currentPlaces.set(key, place);
|
|
4260
|
-
this.sparsePositionBaselines.add(key);
|
|
4261
|
-
this.priorities.set(key, DEFAULT_LOADER_PRIORITY);
|
|
4262
|
-
this.requireOutputs.set(key, Boolean(mask & 32));
|
|
4263
|
-
this.waitForStacks.set(key, Boolean(mask & 64));
|
|
4264
|
-
this.stackBases.set(key, DEFAULT_LOADER_STACK);
|
|
4265
|
-
this.cycles.set(key, DEFAULT_LOADER_CYCLE);
|
|
4266
|
-
}
|
|
4267
|
-
#filterMode(key, loader) {
|
|
4268
|
-
if (this.filterSources.get(key) === "q32" && loader?.q32 != null) {
|
|
4269
|
-
return this.#validFilterMode(loader.q32);
|
|
4270
|
-
}
|
|
4271
|
-
if (this.filterModes.has(key)) return this.#validFilterMode(this.filterModes.get(key));
|
|
4272
|
-
const baseline = this.#loaderBaseline(loader, loader?.lastMask);
|
|
4273
|
-
if (!baseline) return null;
|
|
4274
|
-
return this.#validFilterMode(baseline.filterMode);
|
|
4275
|
-
}
|
|
4276
|
-
#validFilterMode(mode) {
|
|
4277
|
-
return mode >= 0 && mode <= 3 ? mode : null;
|
|
4278
|
-
}
|
|
4279
|
-
#semanticFilterMode(loader, mask) {
|
|
4280
|
-
const q28IsDirectPriority = loader.q28 != null && loader.q28 >= -1 && loader.q28 <= 1;
|
|
4281
|
-
const q24FilterMode = loader.q24 != null && loader.q32 != null && loader.q40 != null ? loader.q24 + 2 : null;
|
|
4282
|
-
const q28FilterMode = loader.q28 != null && loader.q32 != null ? loader.q28 + 1 : null;
|
|
4283
|
-
const q32FilterMode = !q28IsDirectPriority && loader.q28 != null && loader.q32 != null && loader.q40 != null ? loader.q32 + 1 : null;
|
|
4284
|
-
const q32DirectMode = loader.q28 == null && loader.q32 != null && mask & 32 ? loader.q32 : null;
|
|
4285
|
-
if (q28IsDirectPriority && this.#validFilterMode(q24FilterMode) != null) return q24FilterMode;
|
|
4286
|
-
if (this.#validFilterMode(q28FilterMode) != null) return q28FilterMode;
|
|
4287
|
-
if (this.#validFilterMode(q32FilterMode) != null) return q32FilterMode;
|
|
4288
|
-
if (this.#validFilterMode(q32DirectMode) != null) return q32DirectMode;
|
|
4289
|
-
if (this.#validFilterMode(q24FilterMode) != null) return q24FilterMode;
|
|
4290
|
-
return null;
|
|
4291
|
-
}
|
|
4292
|
-
#semanticFilterField(loader, mask) {
|
|
4293
|
-
const q32DirectMode = loader.q28 == null && loader.q32 != null && mask & 32 ? loader.q32 : null;
|
|
4294
|
-
return this.#validFilterMode(q32DirectMode) != null ? "q32" : null;
|
|
4295
|
-
}
|
|
4296
|
-
#loaderBaseline(loader, mask = loader?.lastMask, semanticSnapshot = false) {
|
|
4297
|
-
const snapshot = semanticSnapshot ? decodeLoaderSnapshotRecord(loader, mask) : null;
|
|
4298
|
-
if (snapshot) {
|
|
4299
|
-
return {
|
|
4300
|
-
pickBase: snapshot.pick,
|
|
4301
|
-
pickDeltaBase: loader.q20 ?? 0,
|
|
4302
|
-
placeBase: snapshot.place,
|
|
4303
|
-
placeDeltaBase: loader.q24 ?? 0,
|
|
4304
|
-
priority: snapshot.priority,
|
|
4305
|
-
stack: snapshot.stack,
|
|
4306
|
-
stackField: "fixed",
|
|
4307
|
-
cycle: snapshot.cycle,
|
|
4308
|
-
cycleMode: loader.q44 != null && loader.q40 == null ? "q44-q36-delta" : "offset",
|
|
4309
|
-
filterMode: this.#semanticFilterMode(loader, mask),
|
|
4310
|
-
filterField: this.#semanticFilterField(loader, mask),
|
|
4311
|
-
q32: loader.q32 ?? 0
|
|
4312
|
-
};
|
|
4313
|
-
}
|
|
4314
|
-
if (!loader || loader.q36 == null) return null;
|
|
4315
|
-
if (loader.q40 == null && loader.q44 == null) {
|
|
4316
|
-
if (loader.q20 != null || loader.q24 == null || loader.q28 == null || loader.q32 == null) return null;
|
|
4317
|
-
return {
|
|
4318
|
-
pickBase: wrapLoaderPosition(loader.q28 + 2),
|
|
4319
|
-
pickDeltaBase: 0,
|
|
4320
|
-
placeBase: wrapLoaderPosition(loader.q24 + 4),
|
|
4321
|
-
placeDeltaBase: loader.q24,
|
|
4322
|
-
priority: loader.q28,
|
|
4323
|
-
stack: 16 + loader.q32,
|
|
4324
|
-
cycle: loader.q36 / 20 + 1,
|
|
4325
|
-
cycleMode: "direct",
|
|
4326
|
-
filterMode: loader.q28 + 1,
|
|
4327
|
-
q32: loader.q32
|
|
4328
|
-
};
|
|
4329
|
-
}
|
|
4330
|
-
if (loader.q24 == null && loader.q28 == null && loader.q20 != null && loader.q32 != null && loader.q40 != null && loader.q44 != null) {
|
|
4331
|
-
return {
|
|
4332
|
-
pickBase: wrapLoaderPosition(loader.q20 + 7),
|
|
4333
|
-
pickDeltaBase: loader.q20,
|
|
4334
|
-
placeBase: 4,
|
|
4335
|
-
placeDeltaBase: 0,
|
|
4336
|
-
priority: 0,
|
|
4337
|
-
stack: 16 + loader.q36,
|
|
4338
|
-
stackField: "q36",
|
|
4339
|
-
cycle: loader.q40 / 20 + 1,
|
|
4340
|
-
cycleMode: "q40-direct",
|
|
4341
|
-
filterMode: loader.q32,
|
|
4342
|
-
filterField: "q32",
|
|
4343
|
-
q32: loader.q32
|
|
4344
|
-
};
|
|
4345
|
-
}
|
|
4346
|
-
const q20 = loader.q20 ?? 0;
|
|
4347
|
-
const q32 = loader.q32 ?? 0;
|
|
4348
|
-
let pickBase = null;
|
|
4349
|
-
let placeBase = null;
|
|
4350
|
-
if (loader.q44 != null && loader.q40 == null && loader.q28 == null && loader.q24 != null && loader.q32 != null) {
|
|
4351
|
-
pickBase = wrapLoaderPosition(loader.q24 + 3);
|
|
4352
|
-
placeBase = wrapLoaderPosition(loader.q32 + 4);
|
|
4353
|
-
} else if (loader.q24 != null) {
|
|
4354
|
-
pickBase = wrapLoaderPosition(loader.q24 + 3);
|
|
4355
|
-
placeBase = loader.q28 != null ? wrapLoaderPosition(loader.q28 + 4) : wrapLoaderPosition(loader.q36 + 4);
|
|
4356
|
-
} else if (loader.q28 != null) {
|
|
4357
|
-
pickBase = wrapLoaderPosition(loader.q28 + 3);
|
|
4358
|
-
placeBase = 4;
|
|
4359
|
-
} else if (loader.q20 != null) {
|
|
4360
|
-
pickBase = wrapLoaderPosition(loader.q36 + 3);
|
|
4361
|
-
placeBase = 4;
|
|
4362
|
-
}
|
|
4363
|
-
if (pickBase == null || placeBase == null) return null;
|
|
4364
|
-
const q28IsDirectPriority = loader.q28 != null && loader.q28 >= -1 && loader.q28 <= 1;
|
|
4365
|
-
const priority = loader.q28 != null && loader.q32 != null && loader.q44 != null && loader.q40 != null ? loader.q32 : loader.q28 != null && loader.q32 != null && loader.q44 == null && loader.q40 == null ? loader.q28 : loader.q28 != null && loader.q32 != null && loader.q44 == null && loader.q40 != null ? loader.q32 : loader.q32 != null && loader.q44 != null && loader.q40 == null ? loader.q32 : null;
|
|
4366
|
-
const q28FilterMode = loader.q28 != null && loader.q32 != null && loader.q44 != null ? loader.q28 + 1 : null;
|
|
4367
|
-
const q24FilterMode = loader.q24 != null && loader.q32 != null && loader.q44 != null && loader.q40 != null ? loader.q24 + 2 : null;
|
|
4368
|
-
const q32FilterMode = !q28IsDirectPriority && loader.q28 != null && loader.q32 != null && loader.q44 != null && loader.q40 != null ? loader.q32 + 1 : null;
|
|
4369
|
-
const filterMode = q28IsDirectPriority && q24FilterMode != null && q24FilterMode >= 0 && q24FilterMode <= 3 ? q24FilterMode : q28FilterMode != null && q28FilterMode >= 0 && q28FilterMode <= 3 ? q28FilterMode : q32FilterMode != null && q32FilterMode >= 0 && q32FilterMode <= 3 ? q32FilterMode : q24FilterMode;
|
|
4370
|
-
return {
|
|
4371
|
-
pickBase,
|
|
4372
|
-
pickDeltaBase: q20,
|
|
4373
|
-
placeBase,
|
|
4374
|
-
placeDeltaBase: loader.q24 ?? 0,
|
|
4375
|
-
priority,
|
|
4376
|
-
stack: loader.q32 == null ? null : 16 + loader.q36,
|
|
4377
|
-
cycle: (loader.q40 ?? loader.q44) / 20 + 1,
|
|
4378
|
-
cycleMode: loader.q44 != null && loader.q40 == null ? "q44-q36-delta" : "offset",
|
|
4379
|
-
filterMode,
|
|
4380
|
-
q32
|
|
4381
|
-
};
|
|
4382
|
-
}
|
|
4383
|
-
#applyLoaderBaseline(key, loader, baseline) {
|
|
4384
|
-
this.pickBases.set(key, baseline.pickBase);
|
|
4385
|
-
this.pickDeltaBases.set(key, baseline.pickDeltaBase);
|
|
4386
|
-
this.placeBases.set(key, baseline.placeBase);
|
|
4387
|
-
this.placeDeltaBases.set(key, baseline.placeDeltaBase);
|
|
4388
|
-
this.sparsePositionBaselines.delete(key);
|
|
4389
|
-
this.#setCurrentPosition(key, loader);
|
|
4390
|
-
if (baseline.filterMode != null) {
|
|
4391
|
-
this.filterModes.set(key, baseline.filterMode);
|
|
4392
|
-
if (baseline.filterField) this.filterSources.set(key, baseline.filterField);
|
|
4393
|
-
else this.filterSources.delete(key);
|
|
4394
|
-
}
|
|
4395
|
-
if (baseline.stack != null) {
|
|
4396
|
-
const stackField = baseline.stackField === "fixed" ? 0 : baseline.stackField ? loader[baseline.stackField] ?? 0 : baseline.q32;
|
|
4397
|
-
this.stackBases.set(key, baseline.stack - stackField);
|
|
4398
|
-
if (baseline.stackField) this.stackSources.set(key, baseline.stackField);
|
|
4399
|
-
else this.stackSources.delete(key);
|
|
4400
|
-
}
|
|
4401
|
-
this.cycleModes.set(key, baseline.cycleMode);
|
|
4402
|
-
if (baseline.cycleMode === "direct") {
|
|
4403
|
-
this.cycleDeltaBases.set(key, 0);
|
|
4404
|
-
this.directCycleValues.set(key, loader.q44 ?? loader.q36);
|
|
4405
|
-
this.directCycleFields.set(key, loader.q44 == null ? "q36" : "q44");
|
|
4406
|
-
} else if (baseline.cycleMode === "q44-q36-delta") {
|
|
4407
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4408
|
-
this.directCycleValues.set(key, loader.q44);
|
|
4409
|
-
this.directCycleFields.set(key, "q44");
|
|
4410
|
-
} else if (baseline.cycleMode === "q40-direct") {
|
|
4411
|
-
this.cycleDeltaBases.set(key, 0);
|
|
4412
|
-
this.directCycleValues.set(key, loader.q40);
|
|
4413
|
-
this.directCycleFields.set(key, "q40");
|
|
4414
|
-
} else {
|
|
4415
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4416
|
-
this.directCycleValues.delete(key);
|
|
4417
|
-
this.directCycleFields.delete(key);
|
|
4418
|
-
}
|
|
4419
|
-
this.cycles.set(key, baseline.cycle);
|
|
4420
|
-
if (baseline.priority != null && baseline.priority >= -1 && baseline.priority <= 1) {
|
|
4421
|
-
if (loader.q28 != null) this.priorityOffsets.set(key, baseline.priority - loader.q28);
|
|
4422
|
-
this.priorities.set(key, baseline.priority);
|
|
4423
|
-
} else if (loader.q28 != null && loader.q36 != null) this.#initializePriorityOffset(key, loader);
|
|
4424
|
-
}
|
|
4425
|
-
#applySemanticDelta(worldId, entityId, loader, mask, previous, deltaRecord) {
|
|
4426
|
-
const key = this.#key(worldId, entityId);
|
|
4427
|
-
const delta = decodeLoaderSemanticDeltaRecord(deltaRecord ?? loaderDeltaRecord(loader, mask, previous), mask);
|
|
4428
|
-
if (!delta) return false;
|
|
4429
|
-
const previousConfig = this.getConfig(worldId, entityId, previous);
|
|
4430
|
-
const pick = delta.pick == null ? previousConfig.pick : wrapLoaderPosition((previousConfig.pick ?? DEFAULT_LOADER_PICK) + delta.pick);
|
|
4431
|
-
const place = delta.place == null ? previousConfig.place : wrapLoaderPosition((previousConfig.place ?? DEFAULT_LOADER_PLACE) + delta.place);
|
|
4432
|
-
if (pick != null) {
|
|
4433
|
-
this.pickBases.set(key, pick);
|
|
4434
|
-
this.pickDeltaBases.set(key, loader?.q20 ?? 0);
|
|
4435
|
-
this.currentPicks.set(key, pick);
|
|
4436
|
-
}
|
|
4437
|
-
if (place != null) {
|
|
4438
|
-
this.placeBases.set(key, place);
|
|
4439
|
-
this.placeDeltaBases.set(key, loader?.q24 ?? 0);
|
|
4440
|
-
this.currentPlaces.set(key, place);
|
|
4441
|
-
}
|
|
4442
|
-
if (delta.priority != null) {
|
|
4443
|
-
const priority = previousConfig.priority + delta.priority;
|
|
4444
|
-
this.priorities.set(key, priority);
|
|
4445
|
-
if (loader?.q28 != null) this.priorityOffsets.set(key, priority - loader.q28);
|
|
4446
|
-
else this.priorityOffsets.delete(key);
|
|
4447
|
-
}
|
|
4448
|
-
if (delta.stack != null) {
|
|
4449
|
-
this.stackBases.set(key, previousConfig.stack + delta.stack);
|
|
4450
|
-
this.stackSources.set(key, "fixed");
|
|
4451
|
-
}
|
|
4452
|
-
if (delta.cycleTicks != null) {
|
|
4453
|
-
this.cycles.set(key, previousConfig.cycle + delta.cycleTicks / 20);
|
|
4454
|
-
if (loader?.q44 != null && loader.q40 == null) {
|
|
4455
|
-
this.cycleModes.set(key, "q44-q36-delta");
|
|
4456
|
-
this.cycleDeltaBases.set(key, loader.q36 ?? 0);
|
|
4457
|
-
this.directCycleValues.set(key, loader.q44);
|
|
4458
|
-
this.directCycleFields.set(key, "q44");
|
|
4459
|
-
} else {
|
|
4460
|
-
this.cycleModes.set(key, "offset");
|
|
4461
|
-
this.cycleDeltaBases.set(key, loader?.q36 ?? 0);
|
|
4462
|
-
this.directCycleValues.delete(key);
|
|
4463
|
-
this.directCycleFields.delete(key);
|
|
4464
|
-
}
|
|
4465
|
-
}
|
|
4466
|
-
if (delta.requireOutput) this.requireOutputs.set(key, !previousConfig.requireOutput);
|
|
4467
|
-
if (delta.waitForStack) this.waitForStacks.set(key, !previousConfig.waitForStack);
|
|
4468
|
-
this.sparsePositionBaselines.delete(key);
|
|
4469
|
-
return true;
|
|
4470
|
-
}
|
|
4471
|
-
#setCurrentPosition(key, loader) {
|
|
4472
|
-
const pick = this.#pick(key, loader);
|
|
4473
|
-
const place = this.#place(key, loader);
|
|
4474
|
-
if (pick != null) this.currentPicks.set(key, pick);
|
|
4475
|
-
if (place != null) this.currentPlaces.set(key, place);
|
|
4476
|
-
}
|
|
4477
|
-
#pick(key, loader) {
|
|
4478
|
-
if (!loader) return null;
|
|
4479
|
-
if (this.pickBases.has(key)) return wrapLoaderPosition(this.pickBases.get(key) + ((loader.q20 ?? 0) - (this.pickDeltaBases.get(key) ?? 0)));
|
|
4480
|
-
if (loader.q24 != null) return wrapLoaderPosition(loader.q24 + 3);
|
|
4481
|
-
if (loader.q36 != null) return wrapLoaderPosition(loader.q36 + 3);
|
|
4482
|
-
if (loader.q20 != null) return wrapLoaderPosition(loader.q20);
|
|
4483
|
-
return null;
|
|
4484
|
-
}
|
|
4485
|
-
#place(key, loader) {
|
|
4486
|
-
if (!loader) return null;
|
|
4487
|
-
if (this.placeBases.has(key)) {
|
|
4488
|
-
const base = this.placeBases.get(key);
|
|
4489
|
-
if (loader.q24 != null && this.placeDeltaBases.has(key)) {
|
|
4490
|
-
return wrapLoaderPosition(base + (loader.q24 - this.placeDeltaBases.get(key)));
|
|
4491
|
-
}
|
|
4492
|
-
return wrapLoaderPosition(base);
|
|
4493
|
-
}
|
|
4494
|
-
if (loader.q36 != null) return loader.q24 == null ? 4 : wrapLoaderPosition(loader.q36 + 4);
|
|
4495
|
-
return null;
|
|
4496
|
-
}
|
|
4497
|
-
#key(worldId, entityId) {
|
|
4498
|
-
return `${worldId ?? "-"}:${entityId}`;
|
|
4499
|
-
}
|
|
4500
|
-
};
|
|
3952
|
+
summarizeCannon: () => summarizeCannon,
|
|
3953
|
+
summarizeCargoEjector: () => summarizeCargoEjector,
|
|
3954
|
+
summarizeCargoHatch: () => summarizeCargoHatch,
|
|
3955
|
+
summarizeCommsStation: () => summarizeCommsStation,
|
|
3956
|
+
summarizeDockingSpring: () => summarizeDockingSpring,
|
|
3957
|
+
summarizeDoor: () => summarizeDoor,
|
|
3958
|
+
summarizeExpandoBox: () => summarizeExpandoBox,
|
|
3959
|
+
summarizeFabricator: () => summarizeFabricator,
|
|
3960
|
+
summarizeHealth: () => summarizeHealth,
|
|
3961
|
+
summarizeHelm: () => summarizeHelm,
|
|
3962
|
+
summarizeHoverOutline: () => summarizeHoverOutline,
|
|
3963
|
+
summarizeHugeThruster: () => summarizeHugeThruster,
|
|
3964
|
+
summarizeItemCrate: () => summarizeItemCrate,
|
|
3965
|
+
summarizeItemHolder: () => summarizeItemHolder,
|
|
3966
|
+
summarizeItemLauncher: () => summarizeItemLauncher,
|
|
3967
|
+
summarizeLoader: () => summarizeLoader,
|
|
3968
|
+
summarizeMapMarker: () => summarizeMapMarker,
|
|
3969
|
+
summarizeNavigationUnit: () => summarizeNavigationUnit,
|
|
3970
|
+
summarizePlayer: () => summarizePlayer,
|
|
3971
|
+
summarizePlayerPreview: () => summarizePlayerPreview,
|
|
3972
|
+
summarizePusher: () => summarizePusher,
|
|
3973
|
+
summarizePusherBeam: () => summarizePusherBeam,
|
|
3974
|
+
summarizeShieldGenerator: () => summarizeShieldGenerator,
|
|
3975
|
+
summarizeShieldProjector: () => summarizeShieldProjector,
|
|
3976
|
+
summarizeShipControl: () => summarizeShipControl,
|
|
3977
|
+
summarizeShipSize: () => summarizeShipSize,
|
|
3978
|
+
summarizeShipWorldMetadata: () => summarizeShipWorldMetadata,
|
|
3979
|
+
summarizeSign: () => summarizeSign,
|
|
3980
|
+
summarizeSpawnPoint: () => summarizeSpawnPoint,
|
|
3981
|
+
summarizeThruster: () => summarizeThruster
|
|
3982
|
+
});
|
|
3983
|
+
init_constants();
|
|
3984
|
+
|
|
3985
|
+
// src/state/model/loader-config.js
|
|
3986
|
+
var LOADER_POSITION_NAMES = /* @__PURE__ */ new Map([
|
|
3987
|
+
[0, "top-left"],
|
|
3988
|
+
[1, "top-middle"],
|
|
3989
|
+
[2, "top-right"],
|
|
3990
|
+
[3, "middle-left"],
|
|
3991
|
+
[4, "middle-right"],
|
|
3992
|
+
[5, "bottom-left"],
|
|
3993
|
+
[6, "bottom-middle"],
|
|
3994
|
+
[7, "bottom-right"]
|
|
3995
|
+
]);
|
|
3996
|
+
var LOADER_PRIORITY_NAMES = /* @__PURE__ */ new Map([
|
|
3997
|
+
[-1, "low"],
|
|
3998
|
+
[0, "normal"],
|
|
3999
|
+
[1, "high"]
|
|
4000
|
+
]);
|
|
4001
|
+
var LOADER_FILTER_MODE_NAMES = /* @__PURE__ */ new Map([
|
|
4002
|
+
[0, "allow-all"],
|
|
4003
|
+
[1, "block-filter"],
|
|
4004
|
+
[2, "allow-filter"],
|
|
4005
|
+
[3, "block-all"]
|
|
4006
|
+
]);
|
|
4501
4007
|
|
|
4502
4008
|
// src/state/overworld.js
|
|
4503
4009
|
var OVERWORLD_ZONES = Object.freeze([
|
|
@@ -5184,7 +4690,11 @@
|
|
|
5184
4690
|
[63, { name: "numeric_pair", ...TWO_FIELD_SPEC }],
|
|
5185
4691
|
[67, { name: "numeric_single", fields: numericFields({ 1: 20 }) }],
|
|
5186
4692
|
[69, {
|
|
5187
|
-
name: "
|
|
4693
|
+
name: "loader_config",
|
|
4694
|
+
// The official loader component starts with these values. Wire section
|
|
4695
|
+
// 162 sends a packed absolute flag word before the five numeric deltas.
|
|
4696
|
+
defaults: { q20: 3, q24: 4, q28: 1, q32: 16, q36: 20, q41: 0, q42: 0 },
|
|
4697
|
+
packedBeforeValues: true,
|
|
5188
4698
|
packedBits: [{ bit: 32, offset: 41 }, { bit: 64, offset: 42 }],
|
|
5189
4699
|
fields: numericFields({ 1: 20, 2: 24, 4: 28, 8: 32, 16: 36 })
|
|
5190
4700
|
}],
|
|
@@ -5300,7 +4810,8 @@
|
|
|
5300
4810
|
[158, 75],
|
|
5301
4811
|
[160, 76],
|
|
5302
4812
|
[161, 77],
|
|
5303
|
-
[162,
|
|
4813
|
+
[162, 69],
|
|
4814
|
+
// Loader configuration; distinct from navigation state (168).
|
|
5304
4815
|
[163, 72],
|
|
5305
4816
|
[164, 73],
|
|
5306
4817
|
[165, 74],
|
|
@@ -5474,27 +4985,6 @@
|
|
|
5474
4985
|
}
|
|
5475
4986
|
return null;
|
|
5476
4987
|
}
|
|
5477
|
-
var TABLE_78_FIELD_BITS = [
|
|
5478
|
-
["q20", 1],
|
|
5479
|
-
["q24", 2],
|
|
5480
|
-
["q28", 4],
|
|
5481
|
-
["q32", 8],
|
|
5482
|
-
["q36", 16],
|
|
5483
|
-
["q40", 32],
|
|
5484
|
-
["q44", 64]
|
|
5485
|
-
];
|
|
5486
|
-
function table78DeltaRecord(changed) {
|
|
5487
|
-
const record = { lastMask: changed.mask };
|
|
5488
|
-
for (const [field, bit] of TABLE_78_FIELD_BITS) {
|
|
5489
|
-
if (!(changed.mask & bit)) continue;
|
|
5490
|
-
if (field === "q44" && (changed.mask & 32 || changed.record?.q44 == null)) continue;
|
|
5491
|
-
record[field] = (changed.record?.[field] ?? 0) - (changed.previous?.[field] ?? 0);
|
|
5492
|
-
}
|
|
5493
|
-
return record;
|
|
5494
|
-
}
|
|
5495
|
-
function isSemanticLoaderDelta2(changed, full) {
|
|
5496
|
-
return !full && changed.previous != null && (changed.mask & 96) === 96;
|
|
5497
|
-
}
|
|
5498
4988
|
function decodeText(blob) {
|
|
5499
4989
|
if (!(blob instanceof Uint8Array)) return null;
|
|
5500
4990
|
try {
|
|
@@ -5566,8 +5056,12 @@
|
|
|
5566
5056
|
active: record?.q33 == null ? null : Boolean(record.q33)
|
|
5567
5057
|
};
|
|
5568
5058
|
}
|
|
5569
|
-
function summarizeCannon(entity, record, typeId = null) {
|
|
5059
|
+
function summarizeCannon(entity, record, typeId = null, transformRecord = null) {
|
|
5570
5060
|
if (!record || !CANNON_TYPE_IDS.has(typeId)) return null;
|
|
5061
|
+
const relativeAngleRadians = numberOrNull(record.q32, 200);
|
|
5062
|
+
const mountingAngleRadians = numberOrNull(transformRecord?.q28, 127.324);
|
|
5063
|
+
const tau = 2 * Math.PI;
|
|
5064
|
+
const absoluteAngleRadians = relativeAngleRadians == null || mountingAngleRadians == null ? null : ((mountingAngleRadians + relativeAngleRadians) % tau + tau) % tau;
|
|
5571
5065
|
const ammoItemId = record.q24 == null ? null : CANNON_AMMO_COLOR_ITEM_IDS.get(record.q24) ?? null;
|
|
5572
5066
|
const charge = record.q40 ?? null;
|
|
5573
5067
|
const recoil = record.q36 ?? null;
|
|
@@ -5579,7 +5073,8 @@
|
|
|
5579
5073
|
ammoItemId,
|
|
5580
5074
|
ammoName: entityNameFromType(ammoItemId),
|
|
5581
5075
|
ammoCount: record.q28 ?? 0,
|
|
5582
|
-
|
|
5076
|
+
relativeAngleRadians,
|
|
5077
|
+
absoluteAngleRadians,
|
|
5583
5078
|
recoil,
|
|
5584
5079
|
recoil2,
|
|
5585
5080
|
recoils: [recoil, recoil2],
|
|
@@ -5955,15 +5450,13 @@
|
|
|
5955
5450
|
state: cloneRecord(markerRecord)
|
|
5956
5451
|
};
|
|
5957
5452
|
}
|
|
5958
|
-
function summarizeLoader(entity, loaderRecord, loaderFilterRecord = null, filterSlotsRecord = null,
|
|
5453
|
+
function summarizeLoader(entity, loaderRecord, loaderFilterRecord = null, filterSlotsRecord = null, includeDefaults = false, itemHolderRecord = null) {
|
|
5959
5454
|
if (!loaderRecord && !loaderFilterRecord && !includeDefaults) return null;
|
|
5960
|
-
const
|
|
5961
|
-
const
|
|
5962
|
-
const
|
|
5963
|
-
const
|
|
5964
|
-
const
|
|
5965
|
-
const priority = config.priority ?? 0;
|
|
5966
|
-
const filterMode = config.filterMode ?? null;
|
|
5455
|
+
const loader = { ...MODEL_TABLE_SPECS.get(69).defaults, ...loaderRecord };
|
|
5456
|
+
const pick = loader.q20;
|
|
5457
|
+
const place = loader.q24;
|
|
5458
|
+
const priority = loader.q28 - 1;
|
|
5459
|
+
const filterMode = loaderFilterRecord?.q20 ?? 0;
|
|
5967
5460
|
const heldItem = itemSummary(itemHolderRecord?.q20, itemHolderRecord?.q24 ?? null);
|
|
5968
5461
|
return {
|
|
5969
5462
|
entity,
|
|
@@ -5973,13 +5466,13 @@
|
|
|
5973
5466
|
placeName: enumValueName(LOADER_POSITION_NAMES, place),
|
|
5974
5467
|
priority,
|
|
5975
5468
|
priorityName: enumValueName(LOADER_PRIORITY_NAMES, priority),
|
|
5976
|
-
requireOutput:
|
|
5977
|
-
waitForStack:
|
|
5978
|
-
stack:
|
|
5979
|
-
cycle:
|
|
5469
|
+
requireOutput: Boolean(loader.q41),
|
|
5470
|
+
waitForStack: Boolean(loader.q42),
|
|
5471
|
+
stack: loader.q32,
|
|
5472
|
+
cycle: loader.q36 / 20,
|
|
5980
5473
|
filterMode,
|
|
5981
5474
|
filterModeName: enumValueName(LOADER_FILTER_MODE_NAMES, filterMode),
|
|
5982
|
-
filterSlots:
|
|
5475
|
+
filterSlots: filterSlotsRecord ? [filterSlotsRecord.q20, filterSlotsRecord.q24, filterSlotsRecord.q28].map((value) => value || null) : null,
|
|
5983
5476
|
heldItemId: heldItem.itemId,
|
|
5984
5477
|
heldItemName: heldItem.itemName,
|
|
5985
5478
|
heldCount: heldItem.count,
|
|
@@ -6017,7 +5510,7 @@
|
|
|
6017
5510
|
filteredModeName: enumValueName(PUSHER_MODE_NAMES, filteredMode),
|
|
6018
5511
|
angle: numberOrNull(pusherRecord.q28, 10),
|
|
6019
5512
|
speed: pusherRecord.q32 == null ? 20 : pusherRecord.q32 / 100 + 20,
|
|
6020
|
-
length:
|
|
5513
|
+
length: 1e3 + (pusherRecord.q40 ?? 0) / 10,
|
|
6021
5514
|
filterInventory: pusherRecord.q36 === 1,
|
|
6022
5515
|
filterSlots: filterSlotsRecord ? [filterSlotsRecord.q20 ?? null, filterSlotsRecord.q24 ?? null, filterSlotsRecord.q28 ?? null] : null,
|
|
6023
5516
|
state: cloneRecord(pusherRecord),
|
|
@@ -6370,9 +5863,6 @@
|
|
|
6370
5863
|
blobKey: blobKey2,
|
|
6371
5864
|
cloneRecord: cloneRecord2,
|
|
6372
5865
|
firstRecord: firstRecord2,
|
|
6373
|
-
TABLE_78_FIELD_BITS: TABLE_78_FIELD_BITS2,
|
|
6374
|
-
table78DeltaRecord: table78DeltaRecord2,
|
|
6375
|
-
isSemanticLoaderDelta: isSemanticLoaderDelta3,
|
|
6376
5866
|
decodeText: decodeText2,
|
|
6377
5867
|
entityNameFromType: entityNameFromType2,
|
|
6378
5868
|
markerTypeIdForTables: markerTypeIdForTables2,
|
|
@@ -6448,7 +5938,6 @@
|
|
|
6448
5938
|
defineLazyProperty: defineLazyProperty2
|
|
6449
5939
|
} = decoder_exports;
|
|
6450
5940
|
var ModelState = class {
|
|
6451
|
-
#loaderConfig = new LoaderConfigTracker();
|
|
6452
5941
|
#blueprintItems = null;
|
|
6453
5942
|
#helmOccupied = /* @__PURE__ */ new Map();
|
|
6454
5943
|
#commsStationOccupied = /* @__PURE__ */ new Map();
|
|
@@ -6537,8 +6026,6 @@
|
|
|
6537
6026
|
this.totalErrorCount += 1;
|
|
6538
6027
|
pushCapped2(this.errors, { message: error.message, generation: update.generation }, MAX_RETAINED_ERRORS2);
|
|
6539
6028
|
}
|
|
6540
|
-
this.#remapIndexedLoaderConfig(update);
|
|
6541
|
-
this.#updateLoaderConfig(update);
|
|
6542
6029
|
this.#updateNavigationUnitAutoWarp(update);
|
|
6543
6030
|
this.#updateHelmOccupancy(update);
|
|
6544
6031
|
this.#updateCommsStationOccupancy(update);
|
|
@@ -6640,53 +6127,6 @@
|
|
|
6640
6127
|
this._derived.summariesDirty = true;
|
|
6641
6128
|
this._derived.tableSummariesDirty = true;
|
|
6642
6129
|
}
|
|
6643
|
-
#updateLoaderConfig(update) {
|
|
6644
|
-
const seenEntities = /* @__PURE__ */ new Set();
|
|
6645
|
-
for (const section of update.sections || []) {
|
|
6646
|
-
if (section.table !== 78) continue;
|
|
6647
|
-
for (const changed of section.records || []) {
|
|
6648
|
-
if (changed.indexedLoaderConfig) {
|
|
6649
|
-
this.#loaderConfig.updateIndexedSnapshotRecord(null, changed.entity, changed.record, changed.mask, changed.cumulativeRecord, changed.configEntity);
|
|
6650
|
-
continue;
|
|
6651
|
-
}
|
|
6652
|
-
const typeId = entityTypeIdFromRecord2(this.record(7, changed.entity));
|
|
6653
|
-
this.#loaderConfig.updateRecord(null, changed.entity, changed.record ?? this.record(78, changed.entity), changed.mask, changed.previous, {
|
|
6654
|
-
repeatedInUpdate: seenEntities.has(changed.entity),
|
|
6655
|
-
allowSparseBaseline: typeId === LOADER_TYPE_ID2,
|
|
6656
|
-
repeatedInSection: changed.repeatedInSection,
|
|
6657
|
-
semanticSnapshot: Boolean(update.full),
|
|
6658
|
-
semanticDelta: isSemanticLoaderDelta3(changed, update.full),
|
|
6659
|
-
deltaRecord: table78DeltaRecord2(changed)
|
|
6660
|
-
});
|
|
6661
|
-
seenEntities.add(changed.entity);
|
|
6662
|
-
}
|
|
6663
|
-
}
|
|
6664
|
-
}
|
|
6665
|
-
#remapIndexedLoaderConfig(update) {
|
|
6666
|
-
if (!update.full || update.error) return;
|
|
6667
|
-
const rows = [];
|
|
6668
|
-
for (const section of update.sections || []) {
|
|
6669
|
-
if (section.table !== 78) continue;
|
|
6670
|
-
for (const changed of section.records || []) rows.push(changed);
|
|
6671
|
-
}
|
|
6672
|
-
if (!rows.length) return;
|
|
6673
|
-
const loaderIds = [...this.table(7).entries()].filter(([, record]) => entityTypeIdFromRecord2(record) === LOADER_TYPE_ID2).map(([entity]) => entity).sort((a, b) => a - b);
|
|
6674
|
-
if (loaderIds.length !== rows.length) return;
|
|
6675
|
-
if (rows.every((row, index) => row.entity === loaderIds[index])) return;
|
|
6676
|
-
const remappedTable = /* @__PURE__ */ new Map();
|
|
6677
|
-
for (const [index, changed] of rows.entries()) {
|
|
6678
|
-
const rawRecord = table78DeltaRecord2(changed);
|
|
6679
|
-
changed.configEntity = changed.entity;
|
|
6680
|
-
changed.entity = loaderIds[index];
|
|
6681
|
-
changed.cumulativeRecord = cloneRecord2(changed.record || {});
|
|
6682
|
-
changed.record = cloneRecord2(rawRecord);
|
|
6683
|
-
delete changed.previous;
|
|
6684
|
-
changed.indexedLoaderConfig = true;
|
|
6685
|
-
remappedTable.set(changed.entity, cloneRecord2(rawRecord));
|
|
6686
|
-
update.changedEntities.add(changed.entity);
|
|
6687
|
-
}
|
|
6688
|
-
this.tables.set(78, remappedTable);
|
|
6689
|
-
}
|
|
6690
6130
|
#updateNavigationUnitAutoWarp(update) {
|
|
6691
6131
|
const trackedBeforeUpdate = new Set(this.#navigationUnitAutoWarp.keys());
|
|
6692
6132
|
const initializedThisUpdate = /* @__PURE__ */ new Set();
|
|
@@ -7053,7 +6493,8 @@
|
|
|
7053
6493
|
const pusherRecord = rec(72);
|
|
7054
6494
|
const pusherBeamRecord = rec(42);
|
|
7055
6495
|
const launcherRecord = rec(44);
|
|
7056
|
-
const loaderRecord = rec(
|
|
6496
|
+
const loaderRecord = rec(69);
|
|
6497
|
+
const navigationRecord = rec(78);
|
|
7057
6498
|
const loaderFilterRecord = rec(76);
|
|
7058
6499
|
const loaderFilterSlotsRecord = rec(77);
|
|
7059
6500
|
const commsStationRecord = rec(39);
|
|
@@ -7088,14 +6529,14 @@
|
|
|
7088
6529
|
const health = summarizeHealth2(entityId, healthRecord);
|
|
7089
6530
|
const fabricator = summarizeFabricator2(entityId, fabricatorRecord, itemHolderRecord, typeRecord);
|
|
7090
6531
|
const cargoEjector = summarizeCargoEjector2(entityId, typeId, cargoEjectorRecord);
|
|
7091
|
-
const cannon = summarizeCannon2(entityId, cannonRecord, typeId);
|
|
6532
|
+
const cannon = summarizeCannon2(entityId, cannonRecord, typeId, transformRecord);
|
|
7092
6533
|
const thruster = summarizeThruster2(entityId, typeId, thrusterRecord);
|
|
7093
6534
|
const pusher = summarizePusher2(entityId, pusherRecord, loaderFilterSlotsRecord);
|
|
7094
6535
|
const pusherBeam = summarizePusherBeam2(entityId, pusherBeamRecord);
|
|
7095
6536
|
const launcher = summarizeItemLauncher2(entityId, typeId, launcherRecord);
|
|
7096
|
-
const loader = typeId === LOADER_TYPE_ID2 || typeId == null && (loaderRecord || loaderFilterRecord || loaderFilterSlotsRecord) ? summarizeLoader2(entityId, loaderRecord, loaderFilterRecord, loaderFilterSlotsRecord,
|
|
6537
|
+
const loader = typeId === LOADER_TYPE_ID2 || typeId == null && (loaderRecord || loaderFilterRecord || loaderFilterSlotsRecord) ? summarizeLoader2(entityId, loaderRecord, loaderFilterRecord, loaderFilterSlotsRecord, typeId === LOADER_TYPE_ID2, itemHolderRecord) : null;
|
|
7097
6538
|
const cargoHatch = summarizeCargoHatch2(entityId, typeId, loaderFilterRecord, loaderFilterSlotsRecord, rec(45));
|
|
7098
|
-
const navigationUnit = summarizeNavigationUnit2(entityId, typeId,
|
|
6539
|
+
const navigationUnit = summarizeNavigationUnit2(entityId, typeId, navigationRecord, this.#navigationUnitAutoWarp.get(entityId));
|
|
7099
6540
|
const fluidTank = fluidTankRecord ? {
|
|
7100
6541
|
entity: entityId,
|
|
7101
6542
|
amount: fluidTankRecord.q24 ?? null,
|
|
@@ -7342,7 +6783,6 @@
|
|
|
7342
6783
|
} else {
|
|
7343
6784
|
for (const records of this.tables.values()) records.delete(entity);
|
|
7344
6785
|
}
|
|
7345
|
-
this.#loaderConfig.delete(null, entity);
|
|
7346
6786
|
this.#helmOccupied.delete(entity);
|
|
7347
6787
|
this.#commsStationOccupied.delete(entity);
|
|
7348
6788
|
this.#navigationUnitAutoWarp.delete(entity);
|
|
@@ -7358,7 +6798,6 @@
|
|
|
7358
6798
|
#readSectionRecords(reader, tag, tableId, spec) {
|
|
7359
6799
|
const section = { tag, table: tableId, name: spec?.name || null, records: [] };
|
|
7360
6800
|
let entity = 0;
|
|
7361
|
-
const seenEntities = tableId === 78 ? /* @__PURE__ */ new Set() : null;
|
|
7362
6801
|
while (reader.remaining > 0) {
|
|
7363
6802
|
const recordOffset = reader.offset;
|
|
7364
6803
|
let delta;
|
|
@@ -7376,7 +6815,6 @@
|
|
|
7376
6815
|
throw new Error(`model table ${tableId} tag ${tag} entity ${entity} mask offset ${reader.offset}: ${error.message}`);
|
|
7377
6816
|
}
|
|
7378
6817
|
const record = this.#getRecord(tableId, entity);
|
|
7379
|
-
const previous = tableId === 78 ? cloneRecord2(record) : null;
|
|
7380
6818
|
record.lastMask = mask;
|
|
7381
6819
|
try {
|
|
7382
6820
|
if (spec) this.#applyRecordSpec(reader, record, mask, spec);
|
|
@@ -7385,10 +6823,6 @@
|
|
|
7385
6823
|
throw new Error(`model table ${tableId} tag ${tag} entity ${entity} mask ${mask} offset ${reader.offset}: ${error.message}`);
|
|
7386
6824
|
}
|
|
7387
6825
|
const changed = { entity, mask };
|
|
7388
|
-
if (previous) changed.previous = previous;
|
|
7389
|
-
if (seenEntities?.has(entity)) changed.repeatedInSection = true;
|
|
7390
|
-
seenEntities?.add(entity);
|
|
7391
|
-
if (tableId === 78) changed.record = cloneRecord2(record);
|
|
7392
6826
|
section.records.push(changed);
|
|
7393
6827
|
}
|
|
7394
6828
|
return section;
|
|
@@ -7396,7 +6830,7 @@
|
|
|
7396
6830
|
#getRecord(tableId, entity) {
|
|
7397
6831
|
if (!this.tables.has(tableId)) this.tables.set(tableId, /* @__PURE__ */ new Map());
|
|
7398
6832
|
const records = this.tables.get(tableId);
|
|
7399
|
-
if (!records.has(entity)) records.set(entity, {});
|
|
6833
|
+
if (!records.has(entity)) records.set(entity, { ...MODEL_TABLE_SPECS2.get(tableId)?.defaults });
|
|
7400
6834
|
return records.get(entity);
|
|
7401
6835
|
}
|
|
7402
6836
|
#applyRecordSpec(reader, record, mask, spec) {
|
|
@@ -8433,184 +7867,6 @@
|
|
|
8433
7867
|
return number === 0 && count === 0 ? null : number;
|
|
8434
7868
|
}
|
|
8435
7869
|
|
|
8436
|
-
// src/protocol/outbound/ship-management.js
|
|
8437
|
-
var SHIP_MANAGEMENT_TYPE = 4;
|
|
8438
|
-
var SET_PRIVACY_ACTION = "set_privacy";
|
|
8439
|
-
var STARTER_RECOVERY_ACTION = "starter_recovery";
|
|
8440
|
-
var PLAYER_LIST_ACTION = "player_list";
|
|
8441
|
-
var INVITE_RESET_ACTION = "invite_reset";
|
|
8442
|
-
var SET_RANK_ACTION = "set_rank";
|
|
8443
|
-
var KICK_ACTION = "kick";
|
|
8444
|
-
var BAN_ACTION = "ban";
|
|
8445
|
-
var DEMOTE_SELF_ACTION = "demote_self";
|
|
8446
|
-
function requireNonNegativeInteger(value, name) {
|
|
8447
|
-
const number = Number(value);
|
|
8448
|
-
if (!Number.isInteger(number) || number < 0) throw new RangeError(`${name} must be a non-negative integer`);
|
|
8449
|
-
return number;
|
|
8450
|
-
}
|
|
8451
|
-
function normalizePrivacy(value) {
|
|
8452
|
-
if (value === true || value === 1 || value === "private") return 1;
|
|
8453
|
-
if (value === false || value === 0 || value === "public") return 0;
|
|
8454
|
-
throw new RangeError(`privacy must be 0, 1, true, false, "public", or "private"`);
|
|
8455
|
-
}
|
|
8456
|
-
function normalizePlayerRef(value) {
|
|
8457
|
-
return requireNonNegativeInteger(value, "refId");
|
|
8458
|
-
}
|
|
8459
|
-
function normalizePlayerRank(value) {
|
|
8460
|
-
if (value === 0 || value === "guest") return 0;
|
|
8461
|
-
if (value === 1 || value === "crew") return 1;
|
|
8462
|
-
if (value === 3 || value === "captain") return 3;
|
|
8463
|
-
throw new RangeError(`rank must be 0, 1, 3, "guest", "crew", or "captain"`);
|
|
8464
|
-
}
|
|
8465
|
-
function buildShipManagementMessage(act, arg = null, extra = null) {
|
|
8466
|
-
if (typeof act !== "string" || !act) throw new TypeError(`act must be a non-empty string`);
|
|
8467
|
-
const message = { type: SHIP_MANAGEMENT_TYPE, act, arg };
|
|
8468
|
-
if (extra && typeof extra === "object") Object.assign(message, extra);
|
|
8469
|
-
return message;
|
|
8470
|
-
}
|
|
8471
|
-
function buildShipPrivacyMessage(privacy) {
|
|
8472
|
-
return buildShipManagementMessage(SET_PRIVACY_ACTION, normalizePrivacy(privacy));
|
|
8473
|
-
}
|
|
8474
|
-
function buildStarterRecoveryMessage(itemId) {
|
|
8475
|
-
return buildShipManagementMessage(STARTER_RECOVERY_ACTION, requireNonNegativeInteger(itemId, "itemId"));
|
|
8476
|
-
}
|
|
8477
|
-
function buildPlayerListMessage() {
|
|
8478
|
-
return buildShipManagementMessage(PLAYER_LIST_ACTION);
|
|
8479
|
-
}
|
|
8480
|
-
function buildInviteResetMessage() {
|
|
8481
|
-
return buildShipManagementMessage(INVITE_RESET_ACTION);
|
|
8482
|
-
}
|
|
8483
|
-
function buildSetPlayerRankMessage(refId, rank) {
|
|
8484
|
-
return buildShipManagementMessage(SET_RANK_ACTION, normalizePlayerRef(refId), { rank: normalizePlayerRank(rank) });
|
|
8485
|
-
}
|
|
8486
|
-
function buildKickPlayerMessage(refId) {
|
|
8487
|
-
return buildShipManagementMessage(KICK_ACTION, normalizePlayerRef(refId));
|
|
8488
|
-
}
|
|
8489
|
-
function buildBanPlayerMessage(refId) {
|
|
8490
|
-
return buildShipManagementMessage(BAN_ACTION, normalizePlayerRef(refId));
|
|
8491
|
-
}
|
|
8492
|
-
function buildDemoteSelfMessage() {
|
|
8493
|
-
return buildShipManagementMessage(DEMOTE_SELF_ACTION);
|
|
8494
|
-
}
|
|
8495
|
-
function normalizeShipConfig(event = {}) {
|
|
8496
|
-
const source = event && typeof event === "object" ? event : {};
|
|
8497
|
-
const config = source.config && typeof source.config === "object" ? source.config : {};
|
|
8498
|
-
return {
|
|
8499
|
-
privacy: config.privacy ?? null,
|
|
8500
|
-
privacyName: config.privacy === 0 ? "public" : config.privacy === 1 ? "private" : null,
|
|
8501
|
-
inviteKey: config.invite_key ?? null,
|
|
8502
|
-
teamId: source.team_id ?? null,
|
|
8503
|
-
patronPerks: Array.isArray(source.patron_perks) ? source.patron_perks.slice() : []
|
|
8504
|
-
};
|
|
8505
|
-
}
|
|
8506
|
-
function normalizeCaptainSubrank(event = {}) {
|
|
8507
|
-
const source = event && typeof event === "object" ? event : {};
|
|
8508
|
-
return {
|
|
8509
|
-
subrank: source.subrank ?? null,
|
|
8510
|
-
enableCheats: Boolean(source.enable_cheats)
|
|
8511
|
-
};
|
|
8512
|
-
}
|
|
8513
|
-
function normalizeShipPlayerList(event = {}, previous = null, currentCaptainSubrank = null) {
|
|
8514
|
-
const source = event && typeof event === "object" ? event : {};
|
|
8515
|
-
const changes = Array.isArray(source.player_list) ? source.player_list.map(normalizePlayerListChange) : [];
|
|
8516
|
-
const removedPlayers = changes.filter((change) => change.remove && Number.isFinite(Number(change.refId))).map((change) => Number(change.refId));
|
|
8517
|
-
const changedPlayers = changes.filter((change) => !change.remove).map(({ remove: _remove, ...change }) => change);
|
|
8518
|
-
const players = mergePlayerListChanges(previous?.players, changes);
|
|
8519
|
-
const ownerCaptainRank = ownerRankForPlayers(players);
|
|
8520
|
-
applyPlayerControlState(players, currentCaptainSubrank);
|
|
8521
|
-
applyPlayerControlState(changedPlayers, currentCaptainSubrank);
|
|
8522
|
-
return {
|
|
8523
|
-
ownerCaptainRank,
|
|
8524
|
-
shipOwners: players.filter((player) => player.isShipOwner),
|
|
8525
|
-
players,
|
|
8526
|
-
changes: changedPlayers,
|
|
8527
|
-
removedPlayers
|
|
8528
|
-
};
|
|
8529
|
-
}
|
|
8530
|
-
function mergePlayerListChanges(previousPlayers, changes) {
|
|
8531
|
-
if (!Array.isArray(previousPlayers) || !previousPlayers.length) return changes.filter((change) => !change.remove).map(({
|
|
8532
|
-
remove: _remove,
|
|
8533
|
-
...player
|
|
8534
|
-
}) => ({ ...player }));
|
|
8535
|
-
const existing = /* @__PURE__ */ new Map();
|
|
8536
|
-
for (const player of previousPlayers) {
|
|
8537
|
-
if (player?.refId == null) continue;
|
|
8538
|
-
existing.set(player.refId, { ...player, isShipOwner: false });
|
|
8539
|
-
}
|
|
8540
|
-
const changedRefs = /* @__PURE__ */ new Set();
|
|
8541
|
-
const merged = [];
|
|
8542
|
-
for (const change of changes) {
|
|
8543
|
-
if (change.refId == null) {
|
|
8544
|
-
if (!change.remove) {
|
|
8545
|
-
const { remove: _remove2, ...player2 } = change;
|
|
8546
|
-
merged.push({ ...player2, isShipOwner: false });
|
|
8547
|
-
}
|
|
8548
|
-
continue;
|
|
8549
|
-
}
|
|
8550
|
-
changedRefs.add(change.refId);
|
|
8551
|
-
if (change.remove) {
|
|
8552
|
-
existing.delete(change.refId);
|
|
8553
|
-
continue;
|
|
8554
|
-
}
|
|
8555
|
-
const { remove: _remove, ...changePlayer } = change;
|
|
8556
|
-
const player = { ...existing.get(change.refId) || {}, ...changePlayer, isShipOwner: false };
|
|
8557
|
-
existing.set(change.refId, player);
|
|
8558
|
-
merged.push(player);
|
|
8559
|
-
}
|
|
8560
|
-
for (const player of previousPlayers) {
|
|
8561
|
-
if (player?.refId == null || changedRefs.has(player.refId)) continue;
|
|
8562
|
-
const retained = existing.get(player.refId);
|
|
8563
|
-
if (retained) merged.push(retained);
|
|
8564
|
-
}
|
|
8565
|
-
return merged;
|
|
8566
|
-
}
|
|
8567
|
-
function normalizePlayerListChange(entry = {}) {
|
|
8568
|
-
const source = entry && typeof entry === "object" ? entry : {};
|
|
8569
|
-
if (source._removed) return { refId: source.ref_id ?? null, remove: true };
|
|
8570
|
-
return {
|
|
8571
|
-
refId: source.ref_id ?? null,
|
|
8572
|
-
remove: false,
|
|
8573
|
-
discrim: source.discrim ?? null,
|
|
8574
|
-
discrimColor: source.discrim_color ?? null,
|
|
8575
|
-
teamRank: source.team_rank ?? null,
|
|
8576
|
-
captainRank: source.captain_rank ?? null,
|
|
8577
|
-
isCaptain: Number(source.captain_rank) > 0,
|
|
8578
|
-
isShipOwner: false,
|
|
8579
|
-
canBeManaged: false,
|
|
8580
|
-
time: source.time ?? null,
|
|
8581
|
-
items: Array.isArray(source.items) ? source.items.slice() : [],
|
|
8582
|
-
aliasDiscrims: Array.isArray(source.alias_discrims) ? source.alias_discrims.slice() : [],
|
|
8583
|
-
extraAliasCount: normalizeNonNegativeNumber(source.extra_aliases),
|
|
8584
|
-
onlineCount: source.online_count ?? null
|
|
8585
|
-
};
|
|
8586
|
-
}
|
|
8587
|
-
function normalizeNonNegativeNumber(value) {
|
|
8588
|
-
const number = Number(value);
|
|
8589
|
-
return Number.isFinite(number) && number > 0 ? number : 0;
|
|
8590
|
-
}
|
|
8591
|
-
function ownerRankForPlayers(players) {
|
|
8592
|
-
const ranks = players.filter((player) => Number(player.captainRank) > 0).map((player) => Number(player.captainRank)).filter(Number.isFinite);
|
|
8593
|
-
if (!ranks.length) return null;
|
|
8594
|
-
const ownerRank = Math.min(...ranks);
|
|
8595
|
-
for (const player of players) player.isShipOwner = Number(player.captainRank) === ownerRank;
|
|
8596
|
-
return ownerRank;
|
|
8597
|
-
}
|
|
8598
|
-
function applyPlayerControlState(players, currentCaptainSubrank) {
|
|
8599
|
-
const currentRank = currentCaptainRank(currentCaptainSubrank);
|
|
8600
|
-
for (const player of players) player.canBeManaged = playerCanBeManagedBy(player, currentRank);
|
|
8601
|
-
}
|
|
8602
|
-
function currentCaptainRank(currentCaptainSubrank) {
|
|
8603
|
-
const rank = Number(currentCaptainSubrank?.subrank);
|
|
8604
|
-
return Number.isFinite(rank) && rank > 0 ? rank : null;
|
|
8605
|
-
}
|
|
8606
|
-
function playerCanBeManagedBy(player, currentRank) {
|
|
8607
|
-
if (!Number.isFinite(currentRank) || !player) return false;
|
|
8608
|
-
const targetCaptainRank = Number(player.captainRank);
|
|
8609
|
-
if (Number.isFinite(targetCaptainRank) && targetCaptainRank > 0) return currentRank < targetCaptainRank;
|
|
8610
|
-
const targetTeamRank = Number(player.teamRank);
|
|
8611
|
-
return targetTeamRank === 0 || targetTeamRank === 1;
|
|
8612
|
-
}
|
|
8613
|
-
|
|
8614
7870
|
// src/protocol/outbound/sign.js
|
|
8615
7871
|
var SIGN_TEXT_COMMAND = "sign_text";
|
|
8616
7872
|
var SignDisplayMode = Object.freeze({
|
|
@@ -9800,6 +9056,9 @@
|
|
|
9800
9056
|
use(options = {}, command = {}) {
|
|
9801
9057
|
return this.client.player.useEntity(this.id, options, command);
|
|
9802
9058
|
}
|
|
9059
|
+
openTips(options = {}) {
|
|
9060
|
+
return this.client.tips.open(this, options);
|
|
9061
|
+
}
|
|
9803
9062
|
};
|
|
9804
9063
|
var MachineHandle = class extends EntityHandle {
|
|
9805
9064
|
open(options = {}, command = {}) {
|
|
@@ -10102,6 +9361,9 @@
|
|
|
10102
9361
|
}
|
|
10103
9362
|
};
|
|
10104
9363
|
var DoorHandle = class extends MachineHandle {
|
|
9364
|
+
setRank(rank, options = {}) {
|
|
9365
|
+
return this.client.tips.setRank(this, rank, options);
|
|
9366
|
+
}
|
|
10105
9367
|
get state() {
|
|
10106
9368
|
return summaryForEntity(this.client, this.scope, this.id)?.contents?.door || null;
|
|
10107
9369
|
}
|
|
@@ -10113,6 +9375,9 @@
|
|
|
10113
9375
|
}
|
|
10114
9376
|
};
|
|
10115
9377
|
var SpawnPointHandle = class extends MachineHandle {
|
|
9378
|
+
setRank(rank, options = {}) {
|
|
9379
|
+
return this.client.tips.setRank(this, rank, options);
|
|
9380
|
+
}
|
|
10116
9381
|
get state() {
|
|
10117
9382
|
return summaryForEntity(this.client, this.scope, this.id)?.contents?.spawnPoint || null;
|
|
10118
9383
|
}
|
|
@@ -10657,6 +9922,7 @@
|
|
|
10657
9922
|
this.debug = new ClientDebugDomain(this);
|
|
10658
9923
|
this.player = new PlayerDomain(this);
|
|
10659
9924
|
this.inventory = new InventoryDomain(this);
|
|
9925
|
+
this.tips = new TipDomain(this);
|
|
10660
9926
|
this.management = new ShipManagementDomain(this);
|
|
10661
9927
|
this.cpuLoad = null;
|
|
10662
9928
|
this.inventoryState = normalizeInventoryEvent({ type: "inventory", general_slots: 5 });
|
|
@@ -11410,6 +10676,7 @@
|
|
|
11410
10676
|
}
|
|
11411
10677
|
#handleSideEvent(event, world) {
|
|
11412
10678
|
if (!event || typeof event !== "object") return;
|
|
10679
|
+
if (event.type === "tip_list") this.tips.receive(event, world);
|
|
11413
10680
|
if (event.type === "inventory") {
|
|
11414
10681
|
this.inventoryState = normalizeInventoryEvent(event);
|
|
11415
10682
|
this.emit("inventory", this.inventoryState, world);
|