diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3030c1a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,30 @@ +# Line endings: LF everywhere, on every OS, whatever core.autocrlf says. +* text=auto eol=lf + +# cmd.exe misreads labels and goto in LF batch files, so they stay CRLF. +*.bat text eol=crlf +*.cmd text eol=crlf + +# Binaries: never converted, never diffed as text. +*.png binary +*.jpg binary +*.jpeg binary +*.webp binary +*.svg text +*.ogg binary +*.wav binary +*.mp3 binary +*.ttf binary +*.otf binary +*.woff binary +*.woff2 binary +*.dll binary +*.so binary +*.dylib binary +*.pdb binary +*.exe binary +*.zip binary +*.pck binary +*.moc3 binary +*.res binary +*.scn binary diff --git a/collection_settings.json b/collection_settings.json new file mode 100644 index 0000000..6d0ed34 --- /dev/null +++ b/collection_settings.json @@ -0,0 +1,9 @@ +{ + "options": [ + { + "key": "tile.renderer", + "value": "topdown", + "name": "collection_settings/topdown" + } + ] +} diff --git a/docs/assets/same-map-two-projections.jpg b/docs/assets/same-map-two-projections.jpg new file mode 100644 index 0000000..15aa14c Binary files /dev/null and b/docs/assets/same-map-two-projections.jpg differ diff --git a/docs/assets/village-topdown.jpg b/docs/assets/village-topdown.jpg new file mode 100644 index 0000000..0ea1601 Binary files /dev/null and b/docs/assets/village-topdown.jpg differ diff --git a/docs/en.md b/docs/en.md new file mode 100644 index 0000000..7a93eb9 --- /dev/null +++ b/docs/en.md @@ -0,0 +1,33 @@ +# Top-down Tiles — the square map view + +Top-down Tiles draws tile maps straight from above, on a square grid, in the style of classic 2D RPGs. It is one of two map views for the shared Tile Rendering engine; the other is Isometric Tiles. RPG Plus uses this view. + +![The village of RPG Plus at noon in the top-down view: houses, the square with lamps, villagers, the pond and the hero.](assets/village-topdown.jpg) + +## What changes and what does not + +This mod only decides **how a map cell becomes pixels on screen**: each cell is a square of the tileset's tile size, and a raised object is drawn higher on screen without changing its cell. + +Everything else is owned by other mods and does not change when you switch views: + +- **the map and its content** — tiles, buildings, people, chests — come from content mods (for example RPG Demo and Village Pack); +- **walking, collisions, events, battles and saves** belong to the RPG mod and use the same grid in both views; +- **drawing, lighting and time of day** are done by Tile Rendering. + +The arrow keys and WASD move along the screen's up, down, left and right. + +![The same village map drawn in both views: top-down on the left, isometric on the right.](assets/same-map-two-projections.jpg) + +## Turn it on + +In the game's scheme (**Mods & Collections → Collections → the game → Edit scheme**), include this mod and set **Map projection** to **Top-down**. The value of the `tile.renderer` setting is `topdown`: + +```json +"settings": { "tile.renderer": "topdown" } +``` + +For a single run, add `--tile-renderer=topdown` to the command line. If a game includes only this renderer and leaves the setting empty, it is used automatically. + +## If something goes wrong + +1. **The map is empty.** The game's **Map projection** asks for a renderer that is not included; include this mod or choose another projection. diff --git a/docs/es.md b/docs/es.md new file mode 100644 index 0000000..7e12a19 --- /dev/null +++ b/docs/es.md @@ -0,0 +1,33 @@ +# Top-down Tiles — la vista cuadrada del mapa + +Top-down Tiles dibuja los mapas de tiles directamente desde arriba, sobre una cuadrícula cuadrada, al estilo de los RPG clásicos en 2D. Es una de las dos vistas de mapa del motor común Tile Rendering; la otra es Isometric Tiles. RPG Plus usa esta vista. + +![La aldea de RPG Plus al mediodía en la vista superior: casas, la plaza con farolas, aldeanos, el estanque y el héroe.](assets/village-topdown.jpg) + +## Qué cambia y qué no + +Este mod solo decide **cómo una casilla del mapa se convierte en píxeles en pantalla**: cada casilla es un cuadrado del tamaño del tile del tileset, y un objeto elevado se dibuja más arriba en pantalla sin cambiar de casilla. + +Todo lo demás pertenece a otros mods y no cambia al alternar de vista: + +- **el mapa y su contenido** — tiles, edificios, gente, cofres — vienen de mods de contenido (por ejemplo RPG Demo y Village Pack); +- **caminar, colisiones, eventos, combates y guardado** corresponden al mod RPG y usan la misma cuadrícula en ambas vistas; +- **el dibujo, la iluminación y la hora del día** los hace Tile Rendering. + +Las flechas y WASD mueven hacia arriba, abajo, izquierda y derecha de la pantalla. + +![El mismo mapa de la aldea en ambas vistas: vista superior a la izquierda, isométrica a la derecha.](assets/same-map-two-projections.jpg) + +## Actívalo + +En el esquema del juego (**Mods → Colecciones → el juego → Editar esquema**), incluye este mod y pon **Proyección del mapa** en **Vista superior**. El valor del ajuste `tile.renderer` es `topdown`: + +```json +"settings": { "tile.renderer": "topdown" } +``` + +Para una sola partida, añade `--tile-renderer=topdown` a la línea de comandos. Si un juego incluye solo este renderizador y deja el ajuste vacío, se usa automáticamente. + +## Si algo falla + +1. **El mapa está vacío.** La **Proyección del mapa** del juego pide un renderizador que no está incluido; incluye este mod o elige otra proyección. diff --git a/docs/ja.md b/docs/ja.md new file mode 100644 index 0000000..31eaf3b --- /dev/null +++ b/docs/ja.md @@ -0,0 +1,33 @@ +# Top-down Tiles — 正方形のマップビュー + +Top-down Tiles は、クラシックな 2D RPG のスタイルで、正方形のグリッドに沿ってタイルマップを真上から描きます。共通エンジン Tile Rendering の 2 つのマップビューのうちの 1 つで、もう 1 つは Isometric Tiles です。RPG Plus はこのビューを使います。 + +![見下ろしビューでの正午の RPG Plus の村: 家、灯りの並ぶ広場、村人、池、そして主人公。](assets/village-topdown.jpg) + +## 何が変わり、何が変わらないか + +この Mod が決めるのは、**マップのマスがどう画面のピクセルになるか**だけです。各マスはタイルセットのタイル 1 枚ぶんの正方形で、持ち上がった物体はマスを変えずに画面の高い位置へ描かれます。 + +ほかはすべて別の Mod の持ち物で、ビューを切り替えても変わりません。 + +- **マップとその中身** — タイル、建物、人、宝箱 — はコンテンツ Mod にあります(たとえば RPG Demo と Village Pack)。 +- **歩行、衝突、イベント、バトル、セーブ**は RPG Mod の担当で、どちらのビューでも同じグリッドを使います。 +- **描画、照明、時間の流れ**は Tile Rendering が行います。 + +矢印キーと WASD は、画面の上下左右に沿って動かします。 + +![同じ村のマップを両方のビューで: 左が見下ろし、右がアイソメトリック。](assets/same-map-two-projections.jpg) + +## 有効にする + +ゲームの構成(**MOD とコレクション → コレクション → ゲーム → 構成を編集**)でこの Mod を含め、**マップの投影**を **見下ろし** にします。設定 `tile.renderer` の値は `topdown` です。 + +```json +"settings": { "tile.renderer": "topdown" } +``` + +1 回だけ試すなら、コマンドラインに `--tile-renderer=topdown` を付けます。このレンダラーだけを含み、設定を空のままにしたゲームでは、自動的に使われます。 + +## うまくいかないとき + +1. **マップが空です。** ゲームの **マップの投影** が、含まれていないレンダラーを求めています。この Mod を含めるか、別の投影を選んでください。 diff --git a/docs/ko.md b/docs/ko.md new file mode 100644 index 0000000..31055d7 --- /dev/null +++ b/docs/ko.md @@ -0,0 +1,33 @@ +# Top-down Tiles — 정사각형 맵 보기 + +Top-down Tiles는 클래식 2D RPG 스타일로, 정사각형 격자 위에서 타일 맵을 곧바로 위에서 그립니다. 공유 엔진 Tile Rendering의 두 맵 보기 중 하나이며, 다른 하나는 Isometric Tiles입니다. RPG Plus는 이 보기를 씁니다. + +![탑다운 보기의 정오 무렵 RPG Plus 마을: 집들, 가로등이 늘어선 광장, 마을 사람들, 연못, 그리고 주인공.](assets/village-topdown.jpg) + +## 무엇이 바뀌고 무엇이 안 바뀌나 + +이 모드는 **맵의 한 칸이 어떻게 화면 픽셀이 되는지**만 정합니다. 각 칸은 타일셋 타일 하나 크기의 정사각형이고, 높이 솟은 물체는 칸을 바꾸지 않은 채 화면에서 더 높게 그려집니다. + +나머지는 모두 다른 모드의 소유이며, 보기를 바꿔도 변하지 않습니다. + +- **맵과 그 내용** — 타일, 건물, 사람, 상자 — 은 콘텐츠 모드에 있습니다(예: RPG Demo, Village Pack). +- **걷기, 충돌, 이벤트, 전투, 저장**은 RPG 모드의 몫이며, 두 보기에서 같은 격자를 씁니다. +- **그리기, 조명, 시간대**는 Tile Rendering이 맡습니다. + +방향키와 WASD는 화면의 위·아래·왼쪽·오른쪽을 따라 움직입니다. + +![같은 마을 맵의 두 보기: 왼쪽 탑다운, 오른쪽 아이소메트릭.](assets/same-map-two-projections.jpg) + +## 켜는 법 + +게임 구성(**모드 및 컬렉션 → 컬렉션 → 게임 → 구성 편집**)에 이 모드를 넣고 **지도 투영**을 **탑다운**으로 정하세요. 설정 `tile.renderer`의 값은 `topdown`입니다. + +```json +"settings": { "tile.renderer": "topdown" } +``` + +한 번만 실행하려면 명령줄에 `--tile-renderer=topdown`을 붙이세요. 이 렌더러만 포함하고 설정을 비워 둔 게임에서는 자동으로 쓰입니다. + +## 문제가 생겼을 때 + +1. **맵이 비어 있습니다.** 게임의 **지도 투영**이 포함되지 않은 렌더러를 요청합니다. 이 모드를 넣거나 다른 투영을 고르세요. diff --git a/docs/ru.md b/docs/ru.md new file mode 100644 index 0000000..e128f14 --- /dev/null +++ b/docs/ru.md @@ -0,0 +1,33 @@ +# Top-down Tiles — вид сверху на квадратной сетке + +Top-down Tiles рисует тайловые карты строго сверху, на квадратной сетке, в духе классических двухмерных RPG. Это один из двух видов карты общего движка Tile Rendering; второй — Isometric Tiles. В RPG Plus используется именно этот вид. + +![Деревня RPG Plus в полдень в виде сверху: дома, площадь с фонарями, жители, пруд и герой.](assets/village-topdown.jpg) + +## Что меняется, а что нет + +Этот мод решает только одно: **как клетка карты превращается в пиксели на экране**. Каждая клетка — квадрат размером с тайл тайлсета, а приподнятый объект рисуется выше на экране, оставаясь в своей клетке. + +Всё остальное принадлежит другим модам и при смене вида не меняется: + +- **карта и её содержимое** — тайлы, здания, люди, сундуки — лежат в контентных модах (например, RPG Demo и Village Pack); +- **ходьба, коллизии, события, бои и сохранения** — забота мода RPG, и сетка в обоих видах одна и та же; +- **отрисовка, освещение и время суток** — движка Tile Rendering. + +Стрелки и WASD двигают героя вверх, вниз, влево и вправо по экрану. + +![Та же карта деревни в обоих видах: слева вид сверху, справа изометрия.](assets/same-map-two-projections.jpg) + +## Как включить + +В схеме игры (**Моды и коллекции → Коллекции → игра → Изменить схему**) подключите этот мод и установите **Проекцию карты** в **Вид сверху**. Значение настройки `tile.renderer` при этом `topdown`: + +```json +"settings": { "tile.renderer": "topdown" } +``` + +Для одного запуска добавьте `--tile-renderer=topdown` в командную строку. Если в игру входит только этот рендерер, а настройка пуста, он выбирается автоматически. + +## Если что-то пошло не так + +1. **Карта пуста.** **Проекция карты** игры просит рендерер, которого нет в составе; подключите этот мод или выберите другую проекцию. diff --git a/docs/vi.md b/docs/vi.md new file mode 100644 index 0000000..98eb346 --- /dev/null +++ b/docs/vi.md @@ -0,0 +1,33 @@ +# Top-down Tiles — chế độ xem ô vuông + +Top-down Tiles vẽ các bản đồ ô thẳng từ trên xuống, trên lưới ô vuông, theo phong cách các game nhập vai 2D cổ điển. Đây là một trong hai chế độ xem bản đồ của nền chung Tile Rendering; chế độ kia là Isometric Tiles. RPG Plus dùng chế độ này. + +![Làng RPG Plus lúc trưa trong chế độ nhìn từ trên: những ngôi nhà, quảng trường có đèn, dân làng, chiếc ao và nhân vật chính.](assets/village-topdown.jpg) + +## Thay đổi gì, không đổi gì + +Mod này chỉ quyết định **một ô bản đồ biến thành điểm ảnh trên màn hình như thế nào**: mỗi ô là một hình vuông đúng cỡ ô của tileset, còn vật thể được nhô lên sẽ vẽ cao hơn trên màn hình nhưng vẫn nằm đúng ô của nó. + +Mọi thứ còn lại thuộc về các mod khác và không đổi khi chuyển chế độ xem: + +- **bản đồ và nội dung của nó** — ô, nhà cửa, con người, rương — đến từ các mod nội dung (ví dụ RPG Demo và Village Pack); +- **đi lại, va chạm, sự kiện, chiến đấu và save** thuộc về mod RPG, dùng cùng một lưới ở cả hai chế độ; +- **vẽ, chiếu sáng và thời gian trong ngày** do Tile Rendering đảm nhiệm. + +Phím mũi tên và WASD di chuyển theo hướng lên, xuống, trái, phải của màn hình. + +![Cùng bản đồ làng ở hai chế độ: nhìn từ trên bên trái, đẳng cự bên phải.](assets/same-map-two-projections.jpg) + +## Cách bật + +Trong sơ đồ game (**Mod & Bộ sưu tập → Bộ sưu tập → game → Sửa sơ đồ**), đưa mod này vào và đặt **Phép chiếu bản đồ** thành **Nhìn từ trên**. Giá trị của cài đặt `tile.renderer` là `topdown`: + +```json +"settings": { "tile.renderer": "topdown" } +``` + +Chỉ chạy một lần thì thêm `--tile-renderer=topdown` vào dòng lệnh. Nếu game chỉ có riêng trình kết xuất này và để cài đặt trống, nó sẽ được dùng tự động. + +## Khi có trục trặc + +1. **Bản đồ trống trơn.** **Phép chiếu bản đồ** của game yêu cầu một trình kết xuất không có trong game; hãy đưa mod này vào hoặc chọn phép chiếu khác. diff --git a/docs/zh.md b/docs/zh.md new file mode 100644 index 0000000..963aa4d --- /dev/null +++ b/docs/zh.md @@ -0,0 +1,33 @@ +# Top-down Tiles — 方格地图视图 + +Top-down Tiles 以经典 2D RPG 的风格,在方格网格上从正上方绘制图块地图。它是共享引擎 Tile Rendering 的两种地图视图之一;另一种是 Isometric Tiles。RPG Plus 用的就是这种视图。 + +![正午时俯视下的 RPG Plus 村庄:房屋、挂着路灯的广场、村民、池塘和主角。](assets/village-topdown.jpg) + +## 什么变了,什么没变 + +这个模组只决定**地图的一格如何变成屏幕上的像素**:每格都是一个图块集图块大小的正方形,抬升的物件画在屏幕上更高的位置,但所在格子不变。 + +其余一切都归其他模组所有,切换视图时不会改变: + +- **地图及其内容**——图块、建筑、人物、宝箱——来自内容模组(例如 RPG Demo 和 Village Pack); +- **行走、碰撞、事件、战斗和存档**属于 RPG 模组,两种视图下用的都是同一网格; +- **绘制、光照和昼夜**由 Tile Rendering 完成。 + +方向键和 WASD 沿屏幕的上、下、左、右移动。 + +![同一张村庄地图的两种视图:左边俯视,右边等距。](assets/same-map-two-projections.jpg) + +## 如何启用 + +在游戏的方案(**模组与合集 → 合集 → 对应游戏 → 编辑结构**)中加入这个模组,并把**地图投影**设为**俯视**。设置 `tile.renderer` 的值为 `topdown`: + +```json +"settings": { "tile.renderer": "topdown" } +``` + +只想用一次时,在命令行加上 `--tile-renderer=topdown`。如果游戏只包含这一个渲染器而设置留空,它会自动启用。 + +## 如果遇到问题 + +1. **地图是空的。** 游戏的**地图投影**要求一个未包含的渲染器;请加入这个模组,或选择其他投影。 diff --git a/locale/collection_settings_en.properties b/locale/collection_settings_en.properties new file mode 100644 index 0000000..23a2ca0 --- /dev/null +++ b/locale/collection_settings_en.properties @@ -0,0 +1 @@ +collection_settings/topdown = Top-down diff --git a/locale/collection_settings_es.properties b/locale/collection_settings_es.properties new file mode 100644 index 0000000..173cce7 --- /dev/null +++ b/locale/collection_settings_es.properties @@ -0,0 +1 @@ +collection_settings/topdown = Vista desde arriba diff --git a/locale/collection_settings_ja.properties b/locale/collection_settings_ja.properties new file mode 100644 index 0000000..873a145 --- /dev/null +++ b/locale/collection_settings_ja.properties @@ -0,0 +1 @@ +collection_settings/topdown = 見下ろし diff --git a/locale/collection_settings_ko.properties b/locale/collection_settings_ko.properties new file mode 100644 index 0000000..291a785 --- /dev/null +++ b/locale/collection_settings_ko.properties @@ -0,0 +1 @@ +collection_settings/topdown = 탑다운 diff --git a/locale/collection_settings_ru.properties b/locale/collection_settings_ru.properties new file mode 100644 index 0000000..4d631f9 --- /dev/null +++ b/locale/collection_settings_ru.properties @@ -0,0 +1 @@ +collection_settings/topdown = Вид сверху diff --git a/locale/collection_settings_vi.properties b/locale/collection_settings_vi.properties new file mode 100644 index 0000000..1bc0d04 --- /dev/null +++ b/locale/collection_settings_vi.properties @@ -0,0 +1 @@ +collection_settings/topdown = Nhìn từ trên xuống diff --git a/locale/collection_settings_zh.properties b/locale/collection_settings_zh.properties new file mode 100644 index 0000000..ecb4558 --- /dev/null +++ b/locale/collection_settings_zh.properties @@ -0,0 +1 @@ +collection_settings/topdown = 俯视 diff --git a/locale/en.properties b/locale/en.properties new file mode 100644 index 0000000..c385491 --- /dev/null +++ b/locale/en.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name = Top-down Tiles +mod_tile_topdown_base_desc = Draws tile maps straight from above, on a square grid, in the style of classic 2D RPGs. One of the two views of Tile Rendering; RPG Plus uses it. diff --git a/locale/es.properties b/locale/es.properties new file mode 100644 index 0000000..3497e96 --- /dev/null +++ b/locale/es.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=Vista superior de casillas +mod_tile_topdown_base_desc=Dibuja los mapas de tiles directamente desde arriba, sobre una cuadrícula cuadrada, al estilo de los RPG clásicos en 2D. Una de las dos vistas de Tile Rendering; la usa RPG Plus. diff --git a/locale/ja.properties b/locale/ja.properties new file mode 100644 index 0000000..a9583ae --- /dev/null +++ b/locale/ja.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=見下ろしタイル +mod_tile_topdown_base_desc=クラシックな 2D RPG のスタイルで、正方形のグリッドに沿ってタイルマップを真上から描きます。Tile Rendering の 2 つのビューの 1 つで、RPG Plus が使います。 diff --git a/locale/ko.properties b/locale/ko.properties new file mode 100644 index 0000000..c204ed8 --- /dev/null +++ b/locale/ko.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=탑다운 타일 +mod_tile_topdown_base_desc=클래식 2D RPG 스타일로, 정사각형 격자 위에서 타일 맵을 곧바로 위에서 그립니다. Tile Rendering의 두 보기 중 하나로, RPG Plus가 사용합니다. diff --git a/locale/ru.properties b/locale/ru.properties new file mode 100644 index 0000000..d5d91ac --- /dev/null +++ b/locale/ru.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=Тайлы: вид сверху +mod_tile_topdown_base_desc=Рисует тайловые карты строго сверху, на квадратной сетке, в духе классических двухмерных RPG. Один из двух видов Tile Rendering; его использует RPG Plus. diff --git a/locale/vi.properties b/locale/vi.properties new file mode 100644 index 0000000..172e09a --- /dev/null +++ b/locale/vi.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=Ô nhìn từ trên +mod_tile_topdown_base_desc=Vẽ các bản đồ ô thẳng từ trên xuống, trên lưới ô vuông, theo phong cách các game nhập vai 2D cổ điển. Một trong hai chế độ xem của Tile Rendering; RPG Plus dùng nó. diff --git a/locale/zh.properties b/locale/zh.properties new file mode 100644 index 0000000..7587a2d --- /dev/null +++ b/locale/zh.properties @@ -0,0 +1,2 @@ +mod_tile_topdown_base_name=俯视图块 +mod_tile_topdown_base_desc=以经典 2D RPG 的风格,在方格网格上从正上方绘制图块地图。Tile Rendering 的两种视图之一;RPG Plus 使用的就是它。 diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..8a778e9 --- /dev/null +++ b/manifest.json @@ -0,0 +1,17 @@ +{ + "id": "tile_topdown_base", + "name": "Top-down Tiles", + "version": "1.0.0", + "author": "ct", + "description": "Draws tile maps straight from above, on a square grid, in the style of classic 2D RPGs. One of the two views of Tile Rendering; RPG Plus uses it.", + "category": "visual, engine", + "sources": [ + "src/**/*.cs" + ], + "test_sources": [ + "tests/*.cs" + ], + "depends": [ + "tile_render_base>=1" + ] +} diff --git a/mod.jpg b/mod.jpg new file mode 100644 index 0000000..4ecaab7 Binary files /dev/null and b/mod.jpg differ diff --git a/src/SquareTileProjection.cs b/src/SquareTileProjection.cs new file mode 100644 index 0000000..7787fae --- /dev/null +++ b/src/SquareTileProjection.cs @@ -0,0 +1,17 @@ +namespace Cthangover.Mods.TileTopdown +{ + using Cthangover.Mods.TileRender; + using Godot; + /// Square cells. Elevation changes the vertical image position without changing map coordinates. + public class SquareTileProjection : ITileProjection + { + public float Unit { get; } + public SquareTileProjection(int size) { Unit = size > 0 ? size : throw new System.ArgumentOutOfRangeException(nameof(size)); } + public Vector2 Project(Vector3 p) => new(p.X * Unit, (p.Y - p.Z) * Unit); + public Vector2 Unproject(Vector2 p) => p / Unit; + public int CharsetRow(int facing) => facing; + public TileVisualPlacement Place(TileVisual visual) + => TileVisualPlacement.FromQuad(TileDrawing.CellPolygon(this, visual.Bounds), + TileDrawing.Project(this, visual.Anchor), false); + } +} diff --git a/src/TopdownRendererFactory.cs b/src/TopdownRendererFactory.cs new file mode 100644 index 0000000..a0a3e7a --- /dev/null +++ b/src/TopdownRendererFactory.cs @@ -0,0 +1,11 @@ +namespace Cthangover.Mods.TileTopdown +{ + using Cthangover.Mods.TileRender; + /// Square projection implementation; does not depend on RPG or the isometric implementation. + public class TopdownRendererFactory : ITileRendererFactory + { + public string Id => "topdown"; + public ITileProjection Projection(int size) => new SquareTileProjection(size); + public ITileWorldPresentation Create() => new TileCanvasPresentation(this); + } +} diff --git a/tests/ProjectionTests.cs b/tests/ProjectionTests.cs new file mode 100644 index 0000000..396b36c --- /dev/null +++ b/tests/ProjectionTests.cs @@ -0,0 +1,27 @@ +namespace Cthangover.Mods.TileTopdown.Tests +{ + using Cthangover.Core.Mods.Testing; + using Godot; + /// Ground projection is invertible in every quadrant, before rounding to cells. + public class ProjectionTests + { + [ModTest("projection/ground_roundtrip_and_elevation")] + static void GroundRoundtrip(ModTestContext ctx) + { + var projection = new SquareTileProjection(32); + for (var y = -4; y <= 4; y++) + for (var x = -4; x <= 4; x++) + { + var point = new Vector2(x + 0.25f, y + 0.75f); + var pixel = projection.Project(new Vector3(point.X, point.Y, 0)); + ModAssert.True(projection.Unproject(pixel).IsEqualApprox(point), "ground inverse including negative coordinates"); + } + var ground = projection.Project(new Vector3(2, 3, 0)); + var above = projection.Project(new Vector3(2, 3, 1)); + ModAssert.CloseTo(32, ground.Y - above.Y, what: "one cell elevation"); + ModAssert.CloseTo(32, projection.Unit, what: "projection pixel scale"); + for (var direction = 0; direction < 4; direction++) + ModAssert.True(projection.CharsetRow(direction) >= 0 && projection.CharsetRow(direction) < 4, "valid facing row"); + } + } +}