Files
max bittkerandClaude Opus 4.6 392487b6e0 Upgrade LostCity from revision 245.2 to 254
Updates all three upstream repos (Engine-TS, Content, Client-TS) to the
September 7, 2004 game snapshot with all rs-sdk modifications re-applied.

## New Game Content (254)
- Duel Arena — full PvP dueling with configurable rule sets
- Death Plateau quest — find a safe route past trolls in Burthorpe
- Troll Stronghold quest — infiltrate the stronghold to rescue Godric
- Quest journals — proper progress tracking for all quests
- Mime random event — emote-copying theater event
- Maze random event — navigate a maze to the center
- Varbit support — engine-level variable bit support
- Combat formula fixes and improvements
- New map areas around Burthorpe/Trollheim

## SDK & Engine Changes
- Regenerated collision data (+51k new tiles for 254 map areas)
- Fixed playerpositions API (World.playerLoop.all() for 254 HashTable)
- Updated StateCollector for 254 field renames (scene→world, varps→var,
  skillLevel→statEffectiveLevel, etc.)
- Re-applied all bot framework, auth, session, and hiscore modifications
- MapView: restored unified underground map, player tracking, wheel/touch
  zoom, trails, and teleport markers on 254 webclient API
- MapView: tighter region packing (underground overlaps overworld edge)
- Generated worldmap.jag for mapview

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 16:08:16 -04:00

89 lines
2.2 KiB
JavaScript

function mergeSort(array, cmp) {
if (array.length < 2) return array.slice();
function merge(a, b) {
var r = [],
ai = 0,
bi = 0,
i = 0;
while (ai < a.length && bi < b.length) {
cmp(a[ai], b[bi]) <= 0 ? (r[i++] = a[ai++]) : (r[i++] = b[bi++]);
}
if (ai < a.length) r.push.apply(r, a.slice(ai));
if (bi < b.length) r.push.apply(r, b.slice(bi));
return r;
}
function _ms(a) {
if (a.length <= 1) return a;
var m = Math.floor(a.length / 2),
left = a.slice(0, m),
right = a.slice(m);
left = _ms(left);
right = _ms(right);
return merge(left, right);
}
return _ms(array);
}
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
export const nth_identifier = (() => {
let leading = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'.split('');
let digits = '0123456789'.split('');
shuffle(leading);
shuffle(digits);
let chars;
let frequency;
function reset() {
frequency = new Map();
leading.forEach(ch => frequency.set(ch, 0));
digits.forEach(ch => frequency.set(ch, 0));
}
function consider(str, delta) {
for (var i = str.length; --i >= 0; ) {
frequency.set(str[i], frequency.get(str[i]) + delta);
}
}
function compare(a, b) {
return frequency.get(b) - frequency.get(a);
}
function sort() {
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
}
reset();
sort();
function baseN(num) {
// comment out this code if you want stability between runs
if (num === 0) {
reset();
sort();
}
var ret = '',
base = 54;
num++;
do {
num--;
ret += chars[num % base];
num = Math.floor(num / base);
base = 64;
} while (num > 0);
return ret;
}
return {
get: baseN,
consider,
reset,
sort
};
})();