fix designed-room iso character rendering

This commit is contained in:
jwinterm
2026-07-06 07:04:26 -04:00
parent f505a4fb8a
commit 49ea01606e
88 changed files with 389 additions and 45 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

+24 -17
View File
@@ -189,32 +189,39 @@
return out;
};
function isoMale(n) {
var base = 'assets/kenney/iso-dungeon/characters/male' + n + '/Male_' + n + '_';
var run = [];
for (var i = 0; i < 10; i++) run.push(base + 'Run' + i + '.png');
return {
idle: base + 'Idle0.png',
run: run,
imageW: 48,
imageH: 92
};
}
RK.isoAssets = {
pack: 'iso-dungeon',
tile: { w: 84, h: 42, imageW: 92, imageH: 184 },
tiles: {
floor: 'assets/kenney/iso-dungeon/tiles/planks_S.png',
wall: 'assets/kenney/iso-dungeon/tiles/stoneWall_S.png',
wall: 'assets/kenney/iso-dungeon/tiles/stoneWallHalf_S.png',
bar: 'assets/kenney/iso-dungeon/tiles/barrelsStacked_S.png',
table: 'assets/kenney/iso-dungeon/tiles/chestClosed_S.png',
fallback: 'assets/kenney/iso-dungeon/tiles/planks_S.png'
},
character: {
idle: 'assets/kenney/iso-dungeon/characters/male0/Male_0_Idle0.png',
run: [
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run0.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run1.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run2.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run3.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run4.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run5.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run6.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run7.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run8.png',
'assets/kenney/iso-dungeon/characters/male0/Male_0_Run9.png'
],
imageW: 74,
imageH: 148
character: isoMale(0),
characters: {
fallback: isoMale(0),
'char-villager': isoMale(0),
'char-elder': isoMale(1),
'char-barbarian': isoMale(2),
'char-monk': isoMale(3),
'char-ranger': isoMale(4),
'char-bard': isoMale(5),
'char-rogue': isoMale(6),
'char-merchant': isoMale(7)
}
};
+241 -23
View File
@@ -7,6 +7,8 @@
var DEFAULT_EQUIPMENT = { body: 'none', head: 'none', shield: 'none', weapon: 'none' };
var DEFAULT_COLORS = { base: 'none', skin: 'natural', hair: 'copper', body: 'none', head: 'none', shield: 'none', weapon: 'none' };
var thumbImages = {};
var thumbBounds = {};
function cloneEquipment(eq) {
eq = eq || {};
@@ -110,8 +112,169 @@
} catch (_) { return null; }
};
function drawBaseThumb(ctx, a, draft, onReady) {
function projectionForMode(mode) {
if (mode === 'iso' || mode === '3d' || mode === 'ascii') return mode;
return 'topdown';
}
function hasIsoCharacter(a) {
return !!(a && a.kind === 'char' && RK.isoAssets && RK.isoAssets.characters && RK.isoAssets.characters[a.id]);
}
function appearanceVisibleInProjection(a, projection) {
if (!a) return false;
if (a.kind === 'color') return true;
if (projection === 'topdown') return a.kind === 'char' || a.kind === 'skin';
if (projection === 'iso') return hasIsoCharacter(a);
if (projection === '3d') return a.kind === 'model3d';
return false;
}
function loadThumbImage(url, onReady) {
if (!url) return null;
if (thumbImages[url]) return thumbImages[url];
var rec = thumbImages[url] = { ready: false, error: false, img: new Image() };
rec.img.onload = function () { rec.ready = true; if (onReady) onReady(); };
rec.img.onerror = function () { rec.error = true; };
rec.img.src = url;
return rec;
}
function tintColorForThumb(a, draft) {
var source = {};
var d = draft || {};
for (var dk in d) source[dk] = d[dk];
source.avatar = a.id;
if (a.kind === 'color') return a.color;
if (RK.avatarVisuals && RK.avatarVisuals.tintColorFor) return RK.avatarVisuals.tintColorFor(source, '#9aa4b2');
return '#9aa4b2';
}
function isoCharacterForThumb(a, draft) {
var source = {};
var d = draft || {};
for (var dk in d) source[dk] = d[dk];
source.avatar = a.id;
if (RK.avatarVisuals && RK.avatarVisuals.resolve) {
var visual = RK.avatarVisuals.resolve(source, { projection: 'iso', context: 'customizer' });
if (visual && visual.character) return visual.character;
}
var chars = RK.isoAssets && RK.isoAssets.characters;
return (chars && (chars[a.id] || chars.fallback)) || (RK.isoAssets && RK.isoAssets.character) || null;
}
function imageBounds(img) {
var key = img && img.src;
if (!img || !key) return null;
if (thumbBounds[key]) return thumbBounds[key];
var w = img.naturalWidth || img.width;
var h = img.naturalHeight || img.height;
var cv = document.createElement('canvas');
cv.width = w;
cv.height = h;
var ctx = cv.getContext('2d');
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, w, h).data;
var minX = w, minY = h, maxX = -1, maxY = -1;
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
if (data[(y * w + x) * 4 + 3] < 8) continue;
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
}
thumbBounds[key] = maxX < minX ? { x: 0, y: 0, w: w, h: h } : { x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1 };
return thumbBounds[key];
}
function drawTintedImage(ctx, img, bounds, x, y, w, h, tint) {
bounds = bounds || { x: 0, y: 0, w: img.naturalWidth || img.width, h: img.naturalHeight || img.height };
if (!tint) {
ctx.drawImage(img, bounds.x, bounds.y, bounds.w, bounds.h, x, y, w, h);
return;
}
var cv = document.createElement('canvas');
cv.width = bounds.w;
cv.height = bounds.h;
var tctx = cv.getContext('2d');
tctx.drawImage(img, bounds.x, bounds.y, bounds.w, bounds.h, 0, 0, bounds.w, bounds.h);
tctx.globalCompositeOperation = 'source-atop';
tctx.globalAlpha = 0.42;
tctx.fillStyle = tint;
tctx.fillRect(0, 0, cv.width, cv.height);
tctx.globalAlpha = 1;
tctx.globalCompositeOperation = 'source-over';
ctx.drawImage(cv, x, y, w, h);
}
function drawProjectionThumb(ctx, a, draft, projection, onReady) {
var color = tintColorForThumb(a, draft);
ctx.clearRect(0, 0, 72, 80);
if (projection === 'ascii') {
ctx.fillStyle = color || '#9aa4b2';
ctx.font = '42px monospace';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('@', 36, 43);
return;
}
if (projection === 'iso') {
ctx.imageSmoothingEnabled = true;
ctx.fillStyle = '#705842';
ctx.beginPath();
ctx.moveTo(36, 54);
ctx.lineTo(62, 42);
ctx.lineTo(36, 30);
ctx.lineTo(10, 42);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = 'rgba(255,255,255,0.22)';
ctx.stroke();
var ch = isoCharacterForThumb(a, draft);
var rec = loadThumbImage(ch && ch.idle, onReady);
if (rec && rec.ready) {
var b = imageBounds(rec.img);
var dh = 52;
var dw = dh * (b.w / b.h);
drawTintedImage(ctx, rec.img, b, 36 - dw / 2, 74 - dh, dw, dh, color);
} else {
ctx.fillStyle = color || '#9aa4b2';
ctx.beginPath();
ctx.ellipse(36, 37, 8, 16, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#0a0c0f';
ctx.fillRect(32, 34, 8, 3);
}
return;
}
if (projection === '3d') {
ctx.imageSmoothingEnabled = true;
ctx.fillStyle = color || '#64748b';
ctx.beginPath();
ctx.ellipse(36, 45, 17, 24, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = 'rgba(255,255,255,0.28)';
ctx.beginPath();
ctx.ellipse(29, 34, 6, 9, -0.5, 0, Math.PI * 2);
ctx.fill();
if (a.kind === 'model3d') {
ctx.fillStyle = '#d7dbe0';
ctx.font = '15px monospace';
ctx.textAlign = 'center';
ctx.fillText('3D', 36, 49);
}
return;
}
}
function drawBaseThumb(ctx, a, draft, projection, onReady) {
ctx.clearRect(0, 0, 72, 80);
if (projection && projection !== 'topdown') {
drawProjectionThumb(ctx, a, draft, projection, onReady);
return;
}
if (a.kind === 'color') {
ctx.beginPath(); ctx.arc(36, 44, 21, 0, Math.PI * 2);
ctx.fillStyle = a.color; ctx.fill();
@@ -163,7 +326,11 @@
cv.width = 72; cv.height = 80;
cv.style.cssText = 'display:block;margin:0 auto;image-rendering:pixelated;';
var ctx = cv.getContext('2d');
function draw() { drawBaseThumb(ctx, a, getDraft && getDraft(), draw); }
function draw() {
var d = getDraft && getDraft();
var projection = (d && d.__projection) || 'topdown';
drawBaseThumb(ctx, a, d, projection, draw);
}
draw();
if (redraw) redraw.push(draw);
return cv;
@@ -266,8 +433,7 @@
}
function activeProjection() {
if (selectedMode === 'iso' || selectedMode === '3d' || selectedMode === 'ascii') return selectedMode;
return 'topdown';
return projectionForMode(selectedMode);
}
function ensureColorDraft() {
@@ -455,7 +621,9 @@
selectedMode = mode.id;
if (RK.saveMode) RK.saveMode(mode.id);
markRenderMode();
buildAvatarGrid();
renderEditor();
redrawAll();
}
function buildRenderModes() {
@@ -567,26 +735,74 @@
redrawAll();
}
RK.appearances().forEach(function (a) {
var card = document.createElement('button');
var locked = !!(RK.canUseAppearance && !RK.canUseAppearance(a));
card.type = 'button';
card.className = 'rk-option-card' + (locked ? ' is-locked' : '');
if (locked) card.title = 'Premium pack - buy credits to unlock';
card.appendChild(thumbCanvas(a, function () { return draft; }, redrawers));
var lab = document.createElement('div');
lab.className = 'rk-option-label';
lab.textContent = a.label + (a.premium ? ' *' : '');
card.appendChild(lab);
card.onclick = function () { selectAvatar(a); };
grid.appendChild(card);
cards[a.id] = card;
});
function visibleAppearances() {
var projection = activeProjection();
return RK.appearances().filter(function (a) {
return appearanceVisibleInProjection(a, projection);
});
}
function appearanceForId(list, id) {
for (var i = 0; i < list.length; i++) if (list[i].id === id) return list[i];
return null;
}
function ensureVisibleAvatar() {
var list = visibleAppearances();
if (appearanceForId(list, draft.avatar)) return;
if (!list.length) return;
draft.avatar = list[0].id;
if (RK.isChar && RK.isChar(draft.avatar)) ensureCharDraft();
else if (draftKind() === 'model3d') {
ensureColorDraft();
draft.equipment = cloneEquipment(DEFAULT_EQUIPMENT);
} else {
draft.tint = 'none';
draft.equipment = cloneEquipment(DEFAULT_EQUIPMENT);
delete draft.colors;
}
}
function buildAvatarGrid() {
ensureVisibleAvatar();
grid.innerHTML = '';
cards = {};
redrawers = [];
visibleAppearances().forEach(function (a) {
var card = document.createElement('button');
var locked = !!(RK.canUseAppearance && !RK.canUseAppearance(a));
card.type = 'button';
card.className = 'rk-option-card' + (locked ? ' is-locked' : '');
if (locked) card.title = 'Premium pack - buy credits to unlock';
card.appendChild(thumbCanvas(a, function () {
var d = {};
for (var dk in draft) d[dk] = draft[dk];
d.__projection = activeProjection();
return d;
}, redrawers));
var lab = document.createElement('div');
lab.className = 'rk-option-label';
lab.textContent = a.label + (a.premium ? ' *' : '');
card.appendChild(lab);
card.onclick = function () { selectAvatar(a); };
grid.appendChild(card);
cards[a.id] = card;
});
mark();
}
function drawPreview() {
pctx.clearRect(0, 0, preview.width, preview.height);
var base = baseAppearance(draft.avatar);
if (base.kind === 'color') {
var projection = activeProjection();
if (projection !== 'topdown') {
var temp = document.createElement('canvas');
temp.width = 72;
temp.height = 80;
drawProjectionThumb(temp.getContext('2d'), base, draft, projection, redrawAll);
pctx.imageSmoothingEnabled = projection !== 'ascii';
pctx.drawImage(temp, 0, 0, 72, 80, 21, 12, 108, 120);
} else if (base.kind === 'color') {
pctx.beginPath(); pctx.arc(75, 86, 34, 0, Math.PI * 2);
pctx.fillStyle = base.color; pctx.fill();
pctx.lineWidth = 3; pctx.strokeStyle = 'rgba(255,255,255,0.35)'; pctx.stroke();
@@ -610,10 +826,12 @@
pctx.drawImage(rec.img, 0, row * s.frameH, s.frameW, s.frameH, 75 - dw / 2, 158 - dh, dw, dh);
}
} else {
drawBaseThumb(pctx, base, draft, redrawAll);
drawBaseThumb(pctx, base, draft, 'topdown', redrawAll);
}
previewName.textContent = base.label || base.id;
previewMeta.textContent = base.premium ? 'Premium pack' : (base.kind === 'char' ? 'Customizable' : 'Free');
previewMeta.textContent = projection !== 'topdown'
? (projection.toUpperCase() + ' identity')
: (base.premium ? 'Premium pack' : (base.kind === 'char' ? 'Customizable' : 'Free'));
}
function redrawAll() {
@@ -638,7 +856,7 @@
document.body.appendChild(wrap);
buildRenderModes();
mark();
buildAvatarGrid();
renderEditor();
redrawAll();
};
+38 -1
View File
@@ -17,6 +17,7 @@
this.ctx = this.canvas.getContext('2d');
this.cache = {};
this.tintCache = {};
this.boundsCache = {};
this.last = {};
this.lastScene = null;
this.enabled = !(root.RK && RK.canUsePack && this.assets.pack && !RK.canUsePack(this.assets.pack));
@@ -65,6 +66,40 @@
this.ctx.drawImage(img, cx - w / 2, baseY - h, w, h);
};
IsoRenderer.prototype._imageBounds = function (img) {
if (!img) return null;
var key = img.src || img._rkBoundsKey || null;
if (key && this.boundsCache[key]) return this.boundsCache[key];
var w = img.naturalWidth || img.width;
var h = img.naturalHeight || img.height;
var cv = document.createElement('canvas');
cv.width = w;
cv.height = h;
var ctx = cv.getContext('2d');
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, w, h).data;
var minX = w, minY = h, maxX = -1, maxY = -1;
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
if (data[(y * w + x) * 4 + 3] < 8) continue;
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
}
var bounds = maxX < minX ? { x: 0, y: 0, w: w, h: h } : { x: minX, y: minY, w: maxX - minX + 1, h: maxY - minY + 1 };
if (key) this.boundsCache[key] = bounds;
return bounds;
};
IsoRenderer.prototype._drawSpriteImage = function (img, cx, baseY, h) {
var b = this._imageBounds(img);
if (!b) return;
var w = h * (b.w / b.h);
this.ctx.drawImage(img, b.x, b.y, b.w, b.h, cx - w / 2, baseY - h, w, h);
};
IsoRenderer.prototype._tintedImage = function (img, tint) {
if (!img || !tint) return img;
var key = img.src + '|' + tint;
@@ -80,6 +115,7 @@
ctx.fillRect(0, 0, cv.width, cv.height);
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = 'source-over';
cv._rkBoundsKey = key;
this.tintCache[key] = cv;
return cv;
};
@@ -163,7 +199,7 @@
var tint = root.RK && RK.avatarVisuals && RK.avatarVisuals.tintColorFor
? RK.avatarVisuals.tintColorFor(frame.visual && frame.visual.appearance)
: null;
this._drawImage(this._tintedImage(rec.img, tint), it.sx, it.sy + this.tileH * 0.95, ch.imageW || 74, ch.imageH || 148);
this._drawSpriteImage(this._tintedImage(rec.img, tint), it.sx, it.sy + this.tileH * 0.95, ch.imageH || 92);
} else {
ctx.beginPath();
ctx.arc(it.sx, it.sy, 8, 0, Math.PI * 2);
@@ -195,6 +231,7 @@
this.ctx = null;
this.cache = {};
this.tintCache = {};
this.boundsCache = {};
this.last = {};
this.lastScene = null;
};
+4 -1
View File
@@ -23,6 +23,7 @@
function sceneFromTavern(state, youId) {
state = state || {};
var layout = state.layout || [];
var walkable = state.walkable || null;
var rows = state.rows || layout.length;
var cols = state.cols || (layout[0] ? layout[0].length : 0);
@@ -31,7 +32,9 @@
var srcRow = layout[y] || '';
var row = [];
for (var x = 0; x < cols; x++) {
row.push(TAVERN_TILE_OF[srcRow[x]] || 'wall');
if (layout[y]) row.push(TAVERN_TILE_OF[srcRow[x]] || 'wall');
else if (walkable && walkable[y]) row.push(walkable[y][x] ? 'floor' : 'wall');
else row.push('wall');
}
grid.push(row);
}
+6 -1
View File
@@ -232,7 +232,11 @@
buildModebar();
setMode(RK.loadMode('tiles'));
// Load the designed room (if the server is using one); re-render when ready.
if (state.roomUrl) RK.loadRoom(state.roomUrl, function () { draw(); });
if (state.roomUrl) RK.loadRoom(state.roomUrl, function (room) {
if (room && room.desc && room.desc.walkable) state.walkable = room.desc.walkable;
rebuildScene();
draw();
});
setStatus('You are in the tavern.');
});
@@ -245,6 +249,7 @@
function applyFull(s) {
state.layout = s.layout || [];
state.walkable = s.walkable || null;
state.cols = s.cols || (state.layout[0] ? state.layout[0].length : 0);
state.rows = s.rows || state.layout.length;
state.occupants = s.occupants || [];