Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions .github/workflows/packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ on:
- '.travis.yml'

env:
QBS_VERSION: 3.1.1
QBS_VERSION: 3.2.0
CMAKE_VERSION: 3.31
SENTRY_VERSION: 0.12.8
SENTRY_ORG: mapeditor
Expand Down Expand Up @@ -241,17 +241,19 @@ jobs:
with:
cmake-version: '${{ env.CMAKE_VERSION }}'

- name: Install Qbs
run: |
tarball=qbs-macos-$(uname -m)-${{ env.QBS_VERSION }}.tar.gz
curl -fLO "https://download.qt.io/official_releases/qbs/${{ env.QBS_VERSION }}/${tarball}"
mkdir -p "${HOME}/qbs"
tar xzf "${tarball}" -C "${HOME}/qbs"
dirname "$(find "${HOME}/qbs" -name qbs -type f | head -n1)" >> "$GITHUB_PATH"

- name: Setup Qbs
run: |
brew update
brew install qbs
export PATH="$(brew --prefix qbs)/bin:$PATH"
echo "$(brew --prefix qbs)/bin" >> "$GITHUB_PATH"
qbs --version
qbs setup-toolchains --detect
qbs setup-qt --detect
qbs config profiles.qt-6-9-3.baseProfile xcode
qbs config defaultProfile qt-6-9-3
qbs config defaultProfile xcode

- name: Build Zstandard
run: |
Expand Down Expand Up @@ -385,7 +387,8 @@ jobs:

- name: Install Qbs
run: |
choco install -y qbs --version ${{ env.QBS_VERSION }}
curl -fLO https://download.qt.io/official_releases/qbs/${{ env.QBS_VERSION }}/qbs.${{ env.QBS_VERSION }}.nupkg
choco install -y qbs --version ${{ env.QBS_VERSION }} --source .

- name: Setup Qbs
run: |
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

* Added 'Collapse All' action and 'Only Expand to Current' mode to Project view (with rhythmcache, #4346)
* Added command variables %exportfile and %exportpath (#4476)
* Scripting: Added 'tiled.cell' function, 'cell.flags' property and 'TileLayerEdit.setCell' function (#4538)
* Scripting: Added MapObject.resolvedClassName() (by MatusGuy, #4529)

### Tiled 1.12.2 (27 May 2026)

Expand Down
51 changes: 51 additions & 0 deletions docs/scripting-doc/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1826,6 +1826,15 @@ declare class MapObject extends TiledObject {
*/
layer: ObjectGroup | null;

/**
* Returns the resolved class name of this object.
* This may be the class name of the object's template or the class name of its tile,
* in the case of the object not having an explicitly set class name.
*
* @since 1.13
*/
resolvedClassName(): string;

/**
* Map this object is part of (or `null` in case of a
* standalone object).
Expand Down Expand Up @@ -3589,6 +3598,17 @@ interface cell {
*/
empty: boolean;

/**
* The flags used for the tile.
*
* This is a combination of {@link Tile.FlippedHorizontally},
* {@link Tile.FlippedVertically}, {@link Tile.FlippedAntiDiagonally} and
* {@link Tile.RotatedHexagonal120}.
*
* @since 1.13
*/
flags: number;

/**
* Whether the tile is flipped horizontally.
*/
Expand Down Expand Up @@ -3718,6 +3738,24 @@ interface TileLayerEdit {
*/
setTile(x: number, y: number, tile: Tile | null, flags?: number): void;

/**
* Sets the cell at the given location. This is an alternative to
* {@link setTile} that takes a {@link cell} value, which is convenient for
* copying cells along with their flags (for example a value returned by
* {@link TileLayer.cellAt}).
*
* New cells can be created with {@link tiled.cell}. To remove a tile, set an
* empty cell (`tiled.cell()`).
*
* As with {@link setTile}, all locations which have been set retain a special
* flag that is taken into account by {@link TileMap.merge} and
* {@link Tool.preview}, to enable erasing tiles and highlighting the erased
* area, respectively.
*
* @since 1.13
*/
setCell(x: number, y: number, cell: cell): void;

/**
* Applies the changes made through this object to the target layer. This
* object can be reused to make further changes.
Expand Down Expand Up @@ -5220,6 +5258,19 @@ declare namespace tiled {
*/
export function color(r: number, g: number, b: number, a?: number): color;

/**
* Creates a {@link cell} referring to the given tile, optionally with the
* given flags (any combination of {@link Tile.FlippedHorizontally},
* {@link Tile.FlippedVertically}, {@link Tile.FlippedAntiDiagonally} and
* {@link Tile.RotatedHexagonal120}).
*
* Pass no tile (or `null`) to create an empty cell, which can be used with
* {@link TileLayerEdit.setCell} to erase a tile.
*
* @since 1.13
*/
export function cell(tile?: Tile | null, flags?: number): cell;

/**
* Creates a {@link FilePath} object with the given URL.
*/
Expand Down
28 changes: 28 additions & 0 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ base: core24
grade: stable
confinement: strict

platforms:
amd64:
arm64:
s390x:
ppc64el:

apps:
tiled:
command-chain: &command-chain
Expand Down Expand Up @@ -82,6 +88,28 @@ parts:
- -DUSE_SHARED_PIXMAN=on
- -DUSE_SHARED_FREETYPE=on
- -DUSE_SHARED_HARFBUZZ=on
# Aseprite's vendored `laf` library hardcodes the CPU-architecture
# whitelist (x86/x64/arm64/riscv64) and refuses to compile on s390x
# or ppc64el. Skip the plugin entirely on those arches so the rest
# of Tiled still builds; users there lose .ase/.aseprite import.
override-pull: |
case "$CRAFT_ARCH_BUILD_FOR" in
s390x|ppc64el)
echo "Skipping qaseprite pull on $CRAFT_ARCH_BUILD_FOR"
;;
*)
craftctl default
;;
esac
override-build: |
case "$CRAFT_ARCH_BUILD_FOR" in
s390x|ppc64el)
echo "Skipping qaseprite build on $CRAFT_ARCH_BUILD_FOR"
;;
*)
craftctl default
;;
esac
build-packages:
- libfreetype-dev
- libgl1-mesa-dev
Expand Down
5 changes: 4 additions & 1 deletion src/libtiled/tilelayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
#include "tiled_global.h"

#include "layer.h"
#include "tiled.h"
#include "tile.h"
#include "tiled.h"
#include "tileset.h"

#include <QHash>
Expand Down Expand Up @@ -67,6 +67,7 @@ class TILEDSHARED_EXPORT Cell

Q_PROPERTY(int tileId READ tileId)
Q_PROPERTY(bool empty READ isEmpty)
Q_PROPERTY(int flags READ flags WRITE setFlags)
Q_PROPERTY(bool flippedHorizontally READ flippedHorizontally WRITE setFlippedHorizontally)
Q_PROPERTY(bool flippedVertically READ flippedVertically WRITE setFlippedVertically)
Q_PROPERTY(bool flippedAntiDiagonally READ flippedAntiDiagonally WRITE setFlippedAntiDiagonally)
Expand Down Expand Up @@ -117,6 +118,8 @@ class TILEDSHARED_EXPORT Cell
bool flippedAntiDiagonally() const { return _flags & FlippedAntiDiagonally; }
bool rotatedHexagonal120() const { return _flags & RotatedHexagonal120; }

void setFlags(int flags) { _flags = (_flags & ~VisualFlags) | (flags & VisualFlags); }

void setFlippedHorizontally(bool v) { v ? _flags |= FlippedHorizontally : _flags &= ~FlippedHorizontally; }
void setFlippedVertically(bool v) { v ? _flags |= FlippedVertically : _flags &= ~FlippedVertically; }
void setFlippedAntiDiagonally(bool v) { v ? _flags |= FlippedAntiDiagonally : _flags &= ~FlippedAntiDiagonally; }
Expand Down
7 changes: 7 additions & 0 deletions src/tiled/editablemapobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class EditableMapObject : public EditableObject

MapObject *mapObject() const;

Q_INVOKABLE QString resolvedClassName() const;

void detach();
MapObject *attach(EditableAsset *asset);
void hold(std::unique_ptr<MapObject> mapObject);
Expand Down Expand Up @@ -273,6 +275,11 @@ inline MapObject *EditableMapObject::mapObject() const
return static_cast<MapObject*>(object());
}

inline QString EditableMapObject::resolvedClassName() const
{
return mapObject()->effectiveClassName();
}

inline bool EditableMapObject::isOwning() const
{
return mDetachedMapObject.get() == object();
Expand Down
8 changes: 8 additions & 0 deletions src/tiled/scriptmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "commandmanager.h"
#include "compression.h"
#include "documentmanager.h"
#include "editabletile.h"
#include "editabletileset.h"
#include "issuesmodel.h"
#include "logginginterface.h"
Expand Down Expand Up @@ -261,6 +262,13 @@ QColor ScriptModule::color(float r, float g, float b, float a) const
return QColor::fromRgbF(r, g, b, a);
}

Cell ScriptModule::cell(EditableTile *tile, int flags) const
{
Cell cell(tile ? tile->tile() : nullptr);
cell.setFlags(flags);
return cell;
}

FilePath ScriptModule::filePath(const QUrl &path) const
{
return { path };
Expand Down
3 changes: 3 additions & 0 deletions src/tiled/scriptmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "id.h"
#include "issuesdock.h"
#include "properties.h"
#include "tilelayer.h"

#include <QJSValue>
#include <QObject>
Expand All @@ -36,6 +37,7 @@ namespace Tiled {

class Document;
class EditableAsset;
class EditableTile;
class MapEditor;
class ScriptImage;
class ScriptMapFormatWrapper;
Expand Down Expand Up @@ -111,6 +113,7 @@ class ScriptModule : public QObject

Q_INVOKABLE QColor color(const QString &name) const;
Q_INVOKABLE QColor color(float r, float g, float b, float a = 1.0f) const;
Q_INVOKABLE Tiled::Cell cell(Tiled::EditableTile *tile = nullptr, int flags = 0) const;
Q_INVOKABLE Tiled::FilePath filePath(const QUrl &path) const;
Q_INVOKABLE Tiled::ObjectRef objectRef(int id) const;
Q_INVOKABLE QVariant propertyValue(const QString &typeName, const QJSValue &value) const;
Expand Down
18 changes: 8 additions & 10 deletions src/tiled/tilelayeredit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,16 @@ TileLayerEdit::~TileLayerEdit()
void TileLayerEdit::setTile(int x, int y, EditableTile *tile, int flags)
{
Cell cell(tile ? tile->tile() : nullptr);
cell.setChecked(true); // Used to find painted region later (allows erasing)
cell.setFlags(flags);
setCell(x, y, cell);
}

if (flags & EditableTile::FlippedHorizontally)
cell.setFlippedHorizontally(true);
if (flags & EditableTile::FlippedVertically)
cell.setFlippedVertically(true);
if (flags & EditableTile::FlippedAntiDiagonally)
cell.setFlippedAntiDiagonally(true);
if (flags & EditableTile::RotatedHexagonal120)
cell.setRotatedHexagonal120(true);
void TileLayerEdit::setCell(int x, int y, const Cell &cell)
{
Cell changedCell = cell;
changedCell.setChecked(true); // Used to find painted region later (allows erasing)

mChanges.setCell(x, y, cell);
mChanges.setCell(x, y, changedCell);
}

void TileLayerEdit::apply()
Expand Down
1 change: 1 addition & 0 deletions src/tiled/tilelayeredit.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class TileLayerEdit : public QObject

public slots:
void setTile(int x, int y, EditableTile *tile, int flags = 0);
void setCell(int x, int y, const Tiled::Cell &cell);
void apply();

private:
Expand Down
Loading