mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-17 22:31:26 +02:00
fix(iso): infer facing (not always down) + render features as tiles not avatars
Two iso bugs from reusing the tavern renderer for the SP dungeon: - Character always faced down/SW: sceneFromGameState hardcoded facing:"down", so the renderers ignored their movement-inferred facing (truthy default won). Now facing defaults to null (SP server sends none) so iso/3D infer it from movement; facingDelta(null)=down keeps tiled fine. - "Copy of himself at the origin": the iso renderer drew EVERY entity via _charFrame, so the entrance feature rendered as a male character at the start. Features/items now draw as pack tiles (stairs/chest) or a glyph; monsters get a red tint so they do not read as a second player.
This commit is contained in:
@@ -73,6 +73,27 @@
|
||||
this.ctx.drawImage(img, cx - w / 2, baseY - h, w, h);
|
||||
};
|
||||
|
||||
// Map a dungeon FEATURE entity (entrance/exit/treasure/item) to a pack tile: stairs for the
|
||||
// entrance/exit, a chest for treasure/items. Null if the pack has no fitting tile (→ glyph).
|
||||
IsoRenderer.prototype._featureTileUrl = function (e) {
|
||||
var tiles = this.assets.tiles || {};
|
||||
var c = e.char;
|
||||
if (c === '<' || c === '>') return tiles.stairs || null;
|
||||
if (c === '$' || c === '$W' || c === '$M') return tiles.chestClosed || tiles.chest || null;
|
||||
return null;
|
||||
};
|
||||
|
||||
// Draw a text glyph centered at a projected cell (feature fallback when no pack tile fits).
|
||||
IsoRenderer.prototype._glyph = function (cx, cy, ch, color) {
|
||||
var ctx = this.ctx;
|
||||
ctx.save();
|
||||
ctx.font = 'bold ' + Math.round(this.tileH * 0.95) + "px monospace";
|
||||
ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = color || '#fff';
|
||||
ctx.fillText(ch, cx, cy);
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
// A flat iso diamond in the legend colour — the placeholder a tile draws while its pack image
|
||||
// loads (or if an image is missing), so the view shows the dungeon shape instead of going black.
|
||||
IsoRenderer.prototype._diamond = function (cx, cy, color) {
|
||||
@@ -325,12 +346,25 @@
|
||||
RK.fx.fire(ctx, fcx, fgy, fscale, now, (it.x * 7 + it.y * 13) % 97);
|
||||
}
|
||||
} else if (it.type === 'entity') {
|
||||
// Dungeon FEATURES/ITEMS (entrance/exit/treasure/items) are tiles/glyphs, NOT avatars.
|
||||
// The iso renderer is shared with the tavern (where every entity is an avatar); without
|
||||
// this branch the entrance was drawn as a male character — the "copy of the player at
|
||||
// the start" the map origin showed.
|
||||
if (it.e.kind === 'feature' || it.e.kind === 'item') {
|
||||
var furl = this._featureTileUrl(it.e);
|
||||
var frec = furl && this._load(furl);
|
||||
if (frec && frec.ready) this._drawImage(frec.img, it.sx, it.sy + this.tileH, this.imageW, this.imageH);
|
||||
else this._glyph(it.sx, it.sy + this.tileH * 0.4, it.e.char || '?', it.e.color || '#fff');
|
||||
continue;
|
||||
}
|
||||
this._contactShadow(it.sx, it.sy + this.tileH * 1.15, 18, 7);
|
||||
var frame = this._charFrame(it.e, now);
|
||||
rec = this._load(frame && frame.url);
|
||||
if (rec && rec.ready) {
|
||||
var ch = frame.character || this.assets.character || {};
|
||||
var tint = this._skinTintFor(frame.visual);
|
||||
// Monsters use the same character art — tint them RED so they don't read as a
|
||||
// second player following you around.
|
||||
var tint = it.e.kind === 'monster' ? '#f85149' : this._skinTintFor(frame.visual);
|
||||
this._drawSpriteImage(this._tintedImage(rec.img, tint), it.sx, it.sy + this.tileH * 0.95, ch.imageH || 92);
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
|
||||
@@ -251,7 +251,9 @@ function sceneFromGameState(state, opts) {
|
||||
var playerEntity = {
|
||||
id: 'player', x: state.player.x, y: state.player.y,
|
||||
kind: 'player', char: '@', color: '#9aa4b2',
|
||||
facing: state.player.facing || 'down', label: null,
|
||||
// No bogus default: the SP server doesn't send facing, so leave it null and let the iso/3D
|
||||
// renderers INFER facing from movement. A hardcoded 'down' made them always face down/SW.
|
||||
facing: state.player.facing || null, label: null,
|
||||
you: !state.isSpectating
|
||||
};
|
||||
// Attach the player's appearance if available (for render-kit character rendering).
|
||||
|
||||
Reference in New Issue
Block a user