mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Merge remote-tracking branch 'official/master' into move-instance-in-game-2
This commit is contained in:
@@ -59,36 +59,44 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
// end of compatibility code
|
||||
|
||||
extension
|
||||
.AddCondition("Or",
|
||||
_("Or"),
|
||||
_("Check if one of the sub conditions is true"),
|
||||
_("If one of these conditions is true:"),
|
||||
"",
|
||||
"res/conditions/or24_black.png",
|
||||
"res/conditions/or_black.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("And",
|
||||
_("And"),
|
||||
_("Check if all sub conditions are true"),
|
||||
_("If all of these conditions are true:"),
|
||||
"",
|
||||
"res/conditions/and24_black.png",
|
||||
"res/conditions/and_black.png")
|
||||
.AddCondition(
|
||||
"Or",
|
||||
_("Or"),
|
||||
_("Checks if at least one sub-condition is true. If no "
|
||||
"sub-condition is specified, it will always be false. "
|
||||
"This is rarely used — multiple events and sub-events are "
|
||||
"usually a better approach."),
|
||||
_("If one of these conditions is true:"),
|
||||
"",
|
||||
"res/conditions/or24_black.png",
|
||||
"res/conditions/or_black.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"Not",
|
||||
_("Not"),
|
||||
_("Return the contrary of the result of the sub conditions"),
|
||||
_("Invert the logical result of these conditions:"),
|
||||
"And",
|
||||
_("And"),
|
||||
_("Checks if all sub-conditions are true. If no sub-condition is "
|
||||
"specified, it will always be false. This is rarely needed, as "
|
||||
"events already check all conditions before running actions."),
|
||||
_("If all of these conditions are true:"),
|
||||
"",
|
||||
"res/conditions/not24_black.png",
|
||||
"res/conditions/not_black.png")
|
||||
"res/conditions/and24_black.png",
|
||||
"res/conditions/and_black.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("Not",
|
||||
_("Not"),
|
||||
_("Returns the opposite of the sub-condition(s) result. "
|
||||
"This is rarely needed, as most conditions can be "
|
||||
"inverted or expressed more simply."),
|
||||
_("Invert the logical result of these conditions:"),
|
||||
"",
|
||||
"res/conditions/not24_black.png",
|
||||
"res/conditions/not_black.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
|
@@ -128,24 +128,25 @@ void ObjectAssetSerializer::SerializeUsedVariantsTo(
|
||||
if (!project.HasEventsBasedObject(object.GetType())) {
|
||||
return;
|
||||
}
|
||||
const auto &eventsBasedObject =
|
||||
project.GetEventsBasedObject(object.GetType());
|
||||
const auto &variants = eventsBasedObject.GetVariants();
|
||||
const auto *customObjectConfiguration =
|
||||
dynamic_cast<const gd::CustomObjectConfiguration *>(
|
||||
&object.GetConfiguration());
|
||||
if (customObjectConfiguration
|
||||
->IsMarkedAsOverridingEventsBasedObjectChildrenConfiguration() ||
|
||||
customObjectConfiguration
|
||||
->IsForcedToOverrideEventsBasedObjectChildrenConfiguration()) {
|
||||
const auto &variantName = customObjectConfiguration->GetVariantName();
|
||||
if (!variants.HasVariantNamed(variantName) &&
|
||||
(customObjectConfiguration
|
||||
->IsMarkedAsOverridingEventsBasedObjectChildrenConfiguration() ||
|
||||
customObjectConfiguration
|
||||
->IsForcedToOverrideEventsBasedObjectChildrenConfiguration())) {
|
||||
return;
|
||||
}
|
||||
const auto &variantName = customObjectConfiguration->GetVariantName();
|
||||
const auto &variantIdentifier =
|
||||
object.GetType() + gd::PlatformExtension::GetNamespaceSeparator() +
|
||||
variantName;
|
||||
auto insertResult = alreadyUsedVariantIdentifiers.insert(variantIdentifier);
|
||||
if (insertResult.second) {
|
||||
const auto &eventsBasedObject =
|
||||
project.GetEventsBasedObject(object.GetType());
|
||||
const auto &variants = eventsBasedObject.GetVariants();
|
||||
const auto &variant = variants.HasVariantNamed(variantName)
|
||||
? variants.GetVariant(variantName)
|
||||
: eventsBasedObject.GetDefaultVariant();
|
||||
@@ -154,7 +155,7 @@ void ObjectAssetSerializer::SerializeUsedVariantsTo(
|
||||
pairElement.SetAttribute("objectType", object.GetType());
|
||||
SerializerElement &variantElement = pairElement.AddChild("variant");
|
||||
variant.SerializeTo(variantElement);
|
||||
// TODO Recursivity
|
||||
|
||||
for (auto &object : variant.GetObjects().GetObjects()) {
|
||||
gd::ObjectAssetSerializer::SerializeUsedVariantsTo(
|
||||
project, *object, variantsElement, alreadyUsedVariantIdentifiers);
|
||||
|
@@ -33,7 +33,132 @@ using namespace gd;
|
||||
|
||||
TEST_CASE("ObjectAssetSerializer", "[common]") {
|
||||
|
||||
SECTION("Can serialize custom objects as assets") {
|
||||
SECTION("Can serialize custom objects as assets with variant") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
eventsBasedObject.SetFullName("My events based object");
|
||||
eventsBasedObject.SetDescription("An events based object for test");
|
||||
auto &childObject = eventsBasedObject.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyChild", 0);
|
||||
auto &childInstance =
|
||||
eventsBasedObject.GetInitialInstances().InsertNewInitialInstance();
|
||||
childInstance.SetObjectName("MyChild");
|
||||
|
||||
auto &resourceManager = project.GetResourcesManager();
|
||||
gd::ImageResource imageResource;
|
||||
imageResource.SetName("assets/Idle.png");
|
||||
imageResource.SetFile("assets/Idle.png");
|
||||
imageResource.SetSmooth(true);
|
||||
resourceManager.AddResource(imageResource);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyEventsExtension::MyEventsBasedObject", "MyObject", 0);
|
||||
auto *spriteConfiguration =
|
||||
dynamic_cast<gd::SpriteObject *>(&childObject.GetConfiguration());
|
||||
REQUIRE(spriteConfiguration != nullptr);
|
||||
{
|
||||
gd::Animation animation;
|
||||
animation.SetName("Idle");
|
||||
animation.SetDirectionsCount(1);
|
||||
auto &direction = animation.GetDirection(0);
|
||||
gd::Sprite frame;
|
||||
frame.SetImageName("assets/Idle.png");
|
||||
direction.AddSprite(frame);
|
||||
|
||||
spriteConfiguration->GetAnimations().AddAnimation(animation);
|
||||
}
|
||||
|
||||
SerializerElement assetElement;
|
||||
std::vector<gd::String> usedResourceNames;
|
||||
ObjectAssetSerializer::SerializeTo(project, object, "My Object",
|
||||
assetElement, usedResourceNames);
|
||||
|
||||
// This list is used to copy resource files.
|
||||
REQUIRE(usedResourceNames.size() == 1);
|
||||
REQUIRE(usedResourceNames[0] == "assets/Idle.png");
|
||||
|
||||
// Check that the project is left untouched.
|
||||
REQUIRE(resourceManager.HasResource("assets/Idle.png"));
|
||||
REQUIRE(resourceManager.GetResource("assets/Idle.png").GetFile() ==
|
||||
"assets/Idle.png");
|
||||
REQUIRE(!resourceManager.HasResource("Idle.png"));
|
||||
|
||||
REQUIRE(assetElement.HasChild("objectAssets"));
|
||||
auto &objectAssetsElement = assetElement.GetChild("objectAssets");
|
||||
objectAssetsElement.ConsiderAsArrayOf("objectAsset");
|
||||
REQUIRE(objectAssetsElement.GetChildrenCount() == 1);
|
||||
auto &objectAssetElement = objectAssetsElement.GetChild(0);
|
||||
|
||||
REQUIRE(objectAssetElement.HasChild("variants"));
|
||||
auto &variantsElement = objectAssetElement.GetChild("variants");
|
||||
variantsElement.ConsiderAsArrayOf("variant");
|
||||
REQUIRE(variantsElement.GetChildrenCount() == 1);
|
||||
auto &variantPairElement = variantsElement.GetChild(0);
|
||||
REQUIRE(variantPairElement.GetStringAttribute("objectType") ==
|
||||
"MyEventsExtension::MyEventsBasedObject");
|
||||
REQUIRE(variantPairElement.HasChild("variant"));
|
||||
auto &variantElement = variantPairElement.GetChild("variant");
|
||||
REQUIRE(variantElement.GetStringAttribute("name") == "");
|
||||
REQUIRE(variantElement.HasChild("objects"));
|
||||
auto &objectsElement = variantElement.GetChild("objects");
|
||||
objectsElement.ConsiderAsArrayOf("object");
|
||||
REQUIRE(objectsElement.GetChildrenCount() == 1);
|
||||
auto &childElement = objectsElement.GetChild(0);
|
||||
|
||||
REQUIRE(childElement.HasChild("animations"));
|
||||
auto &animationsElement = childElement.GetChild("animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation");
|
||||
REQUIRE(animationsElement.GetChildrenCount() == 1);
|
||||
auto &animationElement = animationsElement.GetChild(0);
|
||||
|
||||
REQUIRE(animationElement.GetStringAttribute("name") == "Idle");
|
||||
auto &directionsElement = animationElement.GetChild("directions");
|
||||
directionsElement.ConsiderAsArrayOf("direction");
|
||||
REQUIRE(directionsElement.GetChildrenCount() == 1);
|
||||
auto &directionElement = directionsElement.GetChild(0);
|
||||
auto &spritesElement = directionElement.GetChild("sprites");
|
||||
spritesElement.ConsiderAsArrayOf("sprite");
|
||||
REQUIRE(spritesElement.GetChildrenCount() == 1);
|
||||
auto &spriteElement = spritesElement.GetChild(0);
|
||||
REQUIRE(spriteElement.GetStringAttribute("image") == "assets/Idle.png");
|
||||
|
||||
REQUIRE(objectAssetElement.HasChild("requiredExtensions"));
|
||||
auto &requiredExtensionsElement =
|
||||
objectAssetElement.GetChild("requiredExtensions");
|
||||
requiredExtensionsElement.ConsiderAsArrayOf("requiredExtension");
|
||||
REQUIRE(requiredExtensionsElement.GetChildrenCount() == 1);
|
||||
auto &requiredExtensionElement = requiredExtensionsElement.GetChild(0);
|
||||
REQUIRE(requiredExtensionElement.GetStringAttribute("extensionName") ==
|
||||
"MyEventsExtension");
|
||||
|
||||
// Resources are renamed according to asset script naming conventions.
|
||||
REQUIRE(objectAssetElement.HasChild("resources"));
|
||||
auto &resourcesElement = objectAssetElement.GetChild("resources");
|
||||
resourcesElement.ConsiderAsArrayOf("resource");
|
||||
REQUIRE(resourcesElement.GetChildrenCount() == 1);
|
||||
{
|
||||
auto &resourceElement = resourcesElement.GetChild(0);
|
||||
REQUIRE(resourceElement.GetStringAttribute("name") == "assets/Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("file") == "assets/Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("kind") == "image");
|
||||
REQUIRE(resourceElement.GetBoolAttribute("smoothed") == true);
|
||||
}
|
||||
|
||||
// Resources used in object configuration are updated.
|
||||
REQUIRE(objectAssetElement.HasChild("object"));
|
||||
auto &objectElement = objectAssetElement.GetChild("object");
|
||||
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
|
||||
REQUIRE(objectElement.GetStringAttribute("type") ==
|
||||
"MyEventsExtension::MyEventsBasedObject");
|
||||
}
|
||||
|
||||
SECTION("Can serialize custom objects as assets with children overriding") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
Reference in New Issue
Block a user