shapes.test.ts 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { describe, expect, it } from "vitest";
  2. import type { Entity } from "@nengine/core";
  3. import {
  4. CROP_STAGE_COLORS,
  5. ENTITY_COLORS,
  6. PLOT_COLORS,
  7. UNKNOWN_ENTITY_COLOR,
  8. cropColor,
  9. entityShapes,
  10. } from "../src/shapes.js";
  11. const TILE = 32;
  12. describe("entityShapes (viewport entity drawing)", () => {
  13. it("draws a tilled plot as a full tile rect", () => {
  14. const shapes = entityShapes([{ id: "plot:4:4", type: "plot", x: 4, y: 4, tilled: true }], TILE);
  15. expect(shapes).toEqual([
  16. { kind: "rect", x: 128, y: 128, w: 32, h: 32, color: PLOT_COLORS.tilled },
  17. ]);
  18. });
  19. it("draws an untilled plot darker", () => {
  20. const shapes = entityShapes([{ id: "plot:1:1", type: "plot", x: 1, y: 1, tilled: false }], TILE);
  21. expect(shapes[0]).toMatchObject({ color: PLOT_COLORS.untilled });
  22. });
  23. it("adds a watered inset rect on watered plots", () => {
  24. const shapes = entityShapes([{ id: "plot:2:2", type: "plot", x: 2, y: 2, watered: true }], TILE);
  25. expect(shapes).toHaveLength(2);
  26. expect(shapes[1]).toMatchObject({
  27. kind: "rect",
  28. x: 64 + TILE * 0.15,
  29. y: 64 + TILE * 0.15,
  30. w: TILE * 0.7,
  31. h: TILE * 0.7,
  32. color: PLOT_COLORS.watered,
  33. });
  34. });
  35. it("draws a crop-stage dot whose size grows with stageIndex", () => {
  36. const early = entityShapes([{ id: "plot:0:0", type: "plot", x: 0, y: 0, stageIndex: 0 }], TILE);
  37. const late = entityShapes([{ id: "plot:0:0", type: "plot", x: 0, y: 0, stageIndex: 2 }], TILE);
  38. expect(early[1]).toMatchObject({ kind: "circle", color: CROP_STAGE_COLORS[0] });
  39. expect(late[1]).toMatchObject({ kind: "circle", color: CROP_STAGE_COLORS[2] });
  40. expect((late[1] as { w: number }).w).toBeGreaterThan((early[1] as { w: number }).w);
  41. });
  42. it("falls back to the mature color for out-of-range stages", () => {
  43. expect(cropColor(9)).toBe(CROP_STAGE_COLORS[2]);
  44. });
  45. it("draws buildings as footprint-sized blocks", () => {
  46. const shapes = entityShapes([{ id: "building:shed:3:3", type: "building", x: 3, y: 3, w: 2, h: 2 }], TILE);
  47. expect(shapes).toEqual([
  48. { kind: "rect", x: 96, y: 96, w: 64, h: 64, color: ENTITY_COLORS.building },
  49. ]);
  50. });
  51. it("draws npc/player/animal entities as colored dots", () => {
  52. const entities: Entity[] = [
  53. { id: "npc:mayor", type: "npc", x: 6, y: 5 },
  54. { id: "player", type: "player", x: 2, y: 4 },
  55. { id: "animal:chicken:1", type: "animal", x: 9, y: 3 },
  56. ];
  57. const shapes = entityShapes(entities, TILE);
  58. expect(shapes).toEqual([
  59. { kind: "circle", x: 6 * TILE + 16, y: 5 * TILE + 16, w: TILE * 0.32, h: TILE * 0.32, color: ENTITY_COLORS.npc },
  60. { kind: "circle", x: 2 * TILE + 16, y: 4 * TILE + 16, w: TILE * 0.32, h: TILE * 0.32, color: ENTITY_COLORS.player },
  61. { kind: "circle", x: 9 * TILE + 16, y: 3 * TILE + 16, w: TILE * 0.32, h: TILE * 0.32, color: ENTITY_COLORS.animal },
  62. ]);
  63. });
  64. it("skips entities without numeric coordinates", () => {
  65. const shapes = entityShapes([{ id: "ghost", type: "npc" }], TILE);
  66. expect(shapes).toEqual([]);
  67. });
  68. it("draws statemachine/mod-state entities as nothing (no coords) but neutral dots for unknown positioned kinds", () => {
  69. const noCoord = entityShapes([{ id: "sm:quest", type: "statemachine" }], TILE);
  70. expect(noCoord).toEqual([]);
  71. const dot = entityShapes([{ id: "weird", type: "mystery", x: 0, y: 0 }], TILE);
  72. expect(dot).toEqual([
  73. { kind: "circle", x: 16, y: 16, w: TILE * 0.32, h: TILE * 0.32, color: UNKNOWN_ENTITY_COLOR },
  74. ]);
  75. });
  76. });