mirror of
https://github.com/4ian/GDevelop.git
synced 2026-10-12 02:01:17 +00:00
Add support for Tileset resources with .tsj extension (#4737)
This commit is contained in:
@@ -727,6 +727,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "imageResource" ||
|
||||
metadata.GetType() == "jsonResource" ||
|
||||
metadata.GetType() == "tilemapResource" ||
|
||||
metadata.GetType() == "tilesetResource" ||
|
||||
metadata.GetType() == "videoResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
|
||||
@@ -40,6 +40,11 @@ void ArbitraryResourceWorker::ExposeTilemap(gd::String& tilemapName){
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeTileset(gd::String& tilesetName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
@@ -137,6 +142,8 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
|
||||
ExposeJson(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "tilemap") {
|
||||
ExposeTilemap(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "tileset") {
|
||||
ExposeTileset(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "video") {
|
||||
ExposeVideo(potentiallyUpdatedTargetResourceName);
|
||||
}
|
||||
@@ -222,6 +229,10 @@ class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTilemap(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "tilesetResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTileset(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
*/
|
||||
virtual void ExposeTilemap(gd::String &tilemapName);
|
||||
|
||||
/**
|
||||
* \brief Expose a Tileset, which is always a reference to a "tileset" resource.
|
||||
*/
|
||||
virtual void ExposeTileset(gd::String &tilesetName);
|
||||
|
||||
/**
|
||||
* \brief Expose a video, which is always a reference to a "video" resource.
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
|
||||
std::set<gd::String>& GetAllJsons() { return GetAll("json"); };
|
||||
std::set<gd::String>& GetAllTilemaps() { return GetAll("tilemap"); };
|
||||
std::set<gd::String>& GetAllTilesets() { return GetAll("tileset"); };
|
||||
std::set<gd::String>& GetAllVideos() { return GetAll("video"); };
|
||||
std::set<gd::String>& GetAllBitmapFonts() { return GetAll("bitmapFont"); };
|
||||
std::set<gd::String>& GetAll(const gd::String& resourceType) {
|
||||
@@ -49,6 +50,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
if (resourceType == "font") return allFonts;
|
||||
if (resourceType == "json") return allJsons;
|
||||
if (resourceType == "tilemap") return allTilemaps;
|
||||
if (resourceType == "tileset") return allTilesets;
|
||||
if (resourceType == "video") return allVideos;
|
||||
if (resourceType == "bitmapFont") return allBitmapFonts;
|
||||
|
||||
@@ -73,6 +75,9 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeTilemap(gd::String& tilemapResourceName) override {
|
||||
allTilemaps.insert(tilemapResourceName);
|
||||
};
|
||||
virtual void ExposeTileset(gd::String& tilesetResourceName) override {
|
||||
allTilesets.insert(tilesetResourceName);
|
||||
};
|
||||
virtual void ExposeVideo(gd::String& videoResourceName) override {
|
||||
allVideos.insert(videoResourceName);
|
||||
};
|
||||
@@ -86,6 +91,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
std::set<gd::String> allFonts;
|
||||
std::set<gd::String> allJsons;
|
||||
std::set<gd::String> allTilemaps;
|
||||
std::set<gd::String> allTilesets;
|
||||
std::set<gd::String> allVideos;
|
||||
std::set<gd::String> allBitmapFonts;
|
||||
std::set<gd::String> emptyResources;
|
||||
|
||||
@@ -52,6 +52,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeTilemap(gd::String& tilemapResourceName) override {
|
||||
RenameIfNeeded(tilemapResourceName);
|
||||
};
|
||||
virtual void ExposeTileset(gd::String& tilesetResourceName) override {
|
||||
RenameIfNeeded(tilesetResourceName);
|
||||
};
|
||||
virtual void ExposeVideo(gd::String& videoResourceName) override {
|
||||
RenameIfNeeded(videoResourceName);
|
||||
};
|
||||
|
||||
@@ -149,6 +149,8 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor
|
||||
worker.ExposeJson(newPropertyValue);
|
||||
} else if (resourceType == "tilemap") {
|
||||
worker.ExposeTilemap(newPropertyValue);
|
||||
} else if (resourceType == "tileset") {
|
||||
worker.ExposeTileset(newPropertyValue);
|
||||
} else if (resourceType == "bitmapFont") {
|
||||
worker.ExposeBitmapFont(newPropertyValue);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ std::shared_ptr<Resource> ResourcesManager::CreateResource(
|
||||
return std::make_shared<JsonResource>();
|
||||
else if (kind == "tilemap")
|
||||
return std::make_shared<TilemapResource>();
|
||||
else if (kind == "tileset")
|
||||
return std::make_shared<TilesetResource>();
|
||||
else if (kind == "bitmapFont")
|
||||
return std::make_shared<BitmapFontResource>();
|
||||
|
||||
@@ -686,6 +688,40 @@ bool TilemapResource::UpdateProperty(const gd::String& name,
|
||||
return true;
|
||||
}
|
||||
|
||||
void TilesetResource::SetFile(const gd::String& newFile) {
|
||||
file = NormalizePathSeparator(newFile);
|
||||
}
|
||||
|
||||
void TilesetResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetUserAdded(element.GetBoolAttribute("userAdded"));
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
DisablePreload(element.GetBoolAttribute("disablePreload", false));
|
||||
}
|
||||
|
||||
void TilesetResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
element.SetAttribute("disablePreload", IsPreloadDisabled());
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> TilesetResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["disablePreload"]
|
||||
.SetValue(disablePreload ? "true" : "false")
|
||||
.SetType("Boolean")
|
||||
.SetLabel(_("Disable preloading at game startup"));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool TilesetResource::UpdateProperty(const gd::String& name,
|
||||
const gd::String& value) {
|
||||
if (name == "disablePreload") disablePreload = value == "1";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BitmapFontResource::SetFile(const gd::String& newFile) {
|
||||
file = NormalizePathSeparator(newFile);
|
||||
}
|
||||
|
||||
@@ -414,6 +414,47 @@ class GD_CORE_API TilemapResource : public Resource {
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describe a tileset file used by a project.
|
||||
*
|
||||
* \see Resource
|
||||
* \ingroup ResourcesManagement
|
||||
*/
|
||||
class GD_CORE_API TilesetResource : public Resource {
|
||||
public:
|
||||
TilesetResource() : Resource(), disablePreload(false) { SetKind("tileset"); };
|
||||
virtual ~TilesetResource(){};
|
||||
virtual TilesetResource* Clone() const override {
|
||||
return new TilesetResource(*this);
|
||||
}
|
||||
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
virtual bool UseFile() const override { return true; }
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
/**
|
||||
* \brief Return true if the loading at game startup must be disabled
|
||||
*/
|
||||
bool IsPreloadDisabled() const { return disablePreload; }
|
||||
|
||||
/**
|
||||
* \brief Set if the tilemap preload at game startup must be disabled
|
||||
*/
|
||||
void DisablePreload(bool disable = true) { disablePreload = disable; }
|
||||
|
||||
private:
|
||||
bool disablePreload; ///< If "true", don't load the tilemap at game startup
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describe a bitmap font file used by a project.
|
||||
*
|
||||
|
||||
@@ -89,6 +89,7 @@ const defineTileMap = function (
|
||||
'tilesetJsonFile',
|
||||
new gd.PropertyDescriptor(objectContent.tilesetJsonFile || '')
|
||||
.setType('resource')
|
||||
.addExtraInfo('tileset')
|
||||
.addExtraInfo('json')
|
||||
.setLabel(_('Tileset JSON file (optional)'))
|
||||
.setDescription(
|
||||
@@ -254,7 +255,7 @@ const defineTileMap = function (
|
||||
'JsPlatform/Extensions/tile_map.svg'
|
||||
)
|
||||
.addParameter('object', _('Tile map'), 'TileMap', false)
|
||||
.addParameter('jsonResource', _('Tileset JSON file'), '', false)
|
||||
.addParameter('tilesetResource', _('Tileset JSON file'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('isTilesetJsonFile');
|
||||
|
||||
@@ -271,7 +272,7 @@ const defineTileMap = function (
|
||||
'JsPlatform/Extensions/tile_map.svg'
|
||||
)
|
||||
.addParameter('object', _('Tile map'), 'TileMap', false)
|
||||
.addParameter('jsonResource', _('Tileset JSON file'), '', false)
|
||||
.addParameter('tilesetResource', _('Tileset JSON file'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('setTilesetJsonFile');
|
||||
|
||||
|
||||
@@ -76,7 +76,12 @@ namespace gdjs {
|
||||
): void {
|
||||
const resources = this._resources;
|
||||
const jsonResources = resources.filter(function (resource) {
|
||||
return resource.kind === 'json' && !resource.disablePreload;
|
||||
return (
|
||||
(resource.kind === 'json' ||
|
||||
resource.kind === 'tilemap' ||
|
||||
resource.kind === 'tileset') &&
|
||||
!resource.disablePreload
|
||||
);
|
||||
});
|
||||
if (jsonResources.length === 0) {
|
||||
return onComplete(jsonResources.length);
|
||||
@@ -110,7 +115,9 @@ namespace gdjs {
|
||||
loadJson(resourceName: string, callback: JsonManagerRequestCallback): void {
|
||||
const resource = this._resources.find(function (resource) {
|
||||
return (
|
||||
(resource.kind === 'json' || resource.kind === 'tilemap') &&
|
||||
(resource.kind === 'json' ||
|
||||
resource.kind === 'tilemap' ||
|
||||
resource.kind === 'tileset') &&
|
||||
resource.name === resourceName
|
||||
);
|
||||
});
|
||||
|
||||
Vendored
+1
@@ -241,4 +241,5 @@ declare type ResourceKind =
|
||||
| 'video'
|
||||
| 'json'
|
||||
| 'tilemap'
|
||||
| 'tileset'
|
||||
| 'bitmapFont';
|
||||
|
||||
@@ -981,6 +981,11 @@ interface TilemapResource {
|
||||
};
|
||||
TilemapResource implements Resource;
|
||||
|
||||
interface TilesetResource {
|
||||
void TilesetResource();
|
||||
};
|
||||
TilesetResource implements Resource;
|
||||
|
||||
interface InitialInstance {
|
||||
void InitialInstance();
|
||||
|
||||
|
||||
@@ -189,6 +189,8 @@ void ObjectJsImplementation::ExposeResources(gd::ArbitraryResourceWorker& worker
|
||||
} else if (resourceType == "tilemap") {
|
||||
worker.ExposeTilemap(newPropertyValue);
|
||||
worker.ExposeEmbeddeds(newPropertyValue);
|
||||
} else if (resourceType == "tileset") {
|
||||
worker.ExposeTileset(newPropertyValue);
|
||||
} else if (resourceType == "bitmapFont") {
|
||||
worker.ExposeBitmapFont(newPropertyValue);
|
||||
}
|
||||
|
||||
@@ -327,13 +327,13 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2`
|
||||
shell.sed(
|
||||
'-i',
|
||||
/setKind\(kind: string\): void/,
|
||||
"setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap'): void",
|
||||
"setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset'): void",
|
||||
'types/gdresource.js'
|
||||
);
|
||||
shell.sed(
|
||||
'-i',
|
||||
/getKind\(\): string/,
|
||||
"getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap'",
|
||||
"getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset'",
|
||||
'types/gdresource.js'
|
||||
);
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ declare class gdResource {
|
||||
clone(): gdResource;
|
||||
setName(name: string): void;
|
||||
getName(): string;
|
||||
setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap'): void;
|
||||
getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap';
|
||||
setKind(kind: 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset'): void;
|
||||
getKind(): 'image' | 'audio' | 'font' | 'video' | 'json' | 'tilemap' | 'tileset';
|
||||
isUserAdded(): boolean;
|
||||
setUserAdded(yes: boolean): void;
|
||||
useFile(): boolean;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdTilesetResource extends gdResource {
|
||||
constructor(): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
||||
@@ -99,6 +99,7 @@ declare class libGDevelop {
|
||||
VideoResource: Class<gdVideoResource>;
|
||||
JsonResource: Class<gdJsonResource>;
|
||||
TilemapResource: Class<gdTilemapResource>;
|
||||
TilesetResource: Class<gdTilesetResource>;
|
||||
InitialInstance: Class<gdInitialInstance>;
|
||||
InitialInstancesContainer: Class<gdInitialInstancesContainer>;
|
||||
HighestZOrderFinder: Class<gdHighestZOrderFinder>;
|
||||
|
||||
@@ -177,6 +177,7 @@ export const ResourceCard = ({ resource, onChoose, size }: Props) => {
|
||||
);
|
||||
case 'json':
|
||||
case 'tilemap':
|
||||
case 'tileset':
|
||||
return (
|
||||
<GenericCard onChoose={onChoose} resource={resource} size={size}>
|
||||
<Line justifyContent="center">
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// @flow
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import ResourceSelector from '../../ResourcesList/ResourceSelector';
|
||||
import ResourcesLoader from '../../ResourcesLoader';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
|
||||
export default class TilesetResourceField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?ResourceSelector;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.resourceManagementProps || !this.props.project) {
|
||||
console.error(
|
||||
'Missing project or resourceManagementProps for TilesetResourceField'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ResourceSelector
|
||||
margin={this.props.isInline ? 'none' : 'dense'}
|
||||
project={this.props.project}
|
||||
resourceManagementProps={this.props.resourceManagementProps}
|
||||
resourcesLoader={ResourcesLoader}
|
||||
resourceKind="tileset"
|
||||
fallbackResourceKind="json"
|
||||
fullWidth
|
||||
initialResourceName={this.props.value}
|
||||
onChange={this.props.onChange}
|
||||
floatingLabelText={<Trans>Choose the tileset to use</Trans>}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
onApply={this.props.onApply}
|
||||
ref={field => (this._field = field)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ import LeaderboardIdField, {
|
||||
} from './ParameterFields/LeaderboardIdField';
|
||||
import { IdentifierField } from './ParameterFields/IdentifierField';
|
||||
import TilemapResourceField from './ParameterFields/TilemapResourceField';
|
||||
import TilesetResourceField from './ParameterFields/TilesetResourceField';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
@@ -107,6 +108,7 @@ const components = {
|
||||
leaderboardId: LeaderboardIdField,
|
||||
identifier: IdentifierField,
|
||||
tilemapResource: TilemapResourceField,
|
||||
tilesetResource: TilesetResourceField,
|
||||
};
|
||||
const inlineRenderers: { [string]: ParameterInlineRenderer } = {
|
||||
default: renderInlineDefaultField,
|
||||
|
||||
@@ -308,7 +308,11 @@ export default class PixiResourcesLoader {
|
||||
);
|
||||
|
||||
const resource = project.getResourcesManager().getResource(resourceName);
|
||||
if (resource.getKind() !== 'json' && resource.getKind() !== 'tilemap')
|
||||
if (
|
||||
resource.getKind() !== 'json' &&
|
||||
resource.getKind() !== 'tilemap' &&
|
||||
resource.getKind() !== 'tileset'
|
||||
)
|
||||
return Promise.reject(
|
||||
new Error(`The resource called ${resourceName} is not a json file.`)
|
||||
);
|
||||
|
||||
@@ -33,6 +33,7 @@ const resourceKindToInputAcceptedFiles = {
|
||||
video: 'video/mp4,video/webm',
|
||||
json: 'application/json',
|
||||
tilemap: 'application/json',
|
||||
tileset: 'application/json',
|
||||
bitmapFont: '.fnt,.xml',
|
||||
};
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ export default class ResourcePreview extends React.PureComponent<Props, State> {
|
||||
);
|
||||
case 'json':
|
||||
case 'tilemap':
|
||||
case 'tileset':
|
||||
return (
|
||||
<GenericIconPreview
|
||||
renderIcon={props => <InsertDriveFile {...props} />}
|
||||
|
||||
@@ -273,7 +273,11 @@ export default class ResourceSelector extends React.Component<Props, State> {
|
||||
},
|
||||
};
|
||||
resourceExternalEditor.edit(externalEditorOptions);
|
||||
} else if (resourceKind === 'json' || resourceKind === 'tilemap') {
|
||||
} else if (
|
||||
resourceKind === 'json' ||
|
||||
resourceKind === 'tilemap' ||
|
||||
resourceKind === 'tileset'
|
||||
) {
|
||||
const externalEditorOptions = {
|
||||
project,
|
||||
resourcesLoader,
|
||||
|
||||
@@ -18,6 +18,7 @@ export type ResourceKind =
|
||||
| 'video'
|
||||
| 'json'
|
||||
| 'tilemap'
|
||||
| 'tileset'
|
||||
| 'bitmapFont';
|
||||
|
||||
export const allResourceKindsAndMetadata = [
|
||||
@@ -57,6 +58,12 @@ export const allResourceKindsAndMetadata = [
|
||||
fileExtensions: ['json', 'ldtk', 'tmj'],
|
||||
createNewResource: () => new gd.TilemapResource(),
|
||||
},
|
||||
{
|
||||
kind: 'tileset',
|
||||
displayName: t`Tile Set`,
|
||||
fileExtensions: ['json', 'tsj'],
|
||||
createNewResource: () => new gd.TilesetResource(),
|
||||
},
|
||||
{
|
||||
kind: 'bitmapFont',
|
||||
displayName: t`Bitmap Font`,
|
||||
|
||||
@@ -198,7 +198,9 @@ export default class ResourcesList extends React.Component<Props, State> {
|
||||
case 'json':
|
||||
return 'res/actions/fichier24.png';
|
||||
case 'tilemap':
|
||||
return 'res/actions/star24.png';
|
||||
return 'res/actions/fichier24.png';
|
||||
case 'tileset':
|
||||
return 'res/actions/fichier24.png';
|
||||
case 'video':
|
||||
return 'JsPlatform/Extensions/videoicon24.png';
|
||||
case 'font':
|
||||
|
||||
Reference in New Issue
Block a user