Skip to content

HarryBlueJay/PolytoriaDOM

Repository files navigation

PolytoriaDOM

A C++ library for manipulating .poly and .ptmd files.

Why C++?

It's fast. But it definitely wasn't the right language choice. C# would have been better, but I don't know how to code in it.

Files

  • PolytoriaEnums.h - Contains a list of all enums.
  • PolytoriaTypes.h - Contains all custom Polytoria types.
  • PolytoriaClasses.h - Required for all operations with Instances.
  • PolytoriaPlace.h - Required for serialization/deserialization of places, alongside creating the default place structure.

Example

Here is an example of most of the usages of this library:

#include "PolytoriaTypes.h"
#include "PolytoriaClasses.h"
#include "PolytoriaPlace.h"
#include <iostream>

using namespace Polytoria;
int main() {
	Game& game = Place::FromFile("examples\\officeTemplate.poly");

	// Both Instance::New constructors can take in an optional parent.
	// If it is not specified, it will be parented to nothing.
	// In addition, the name will be set to the ClassName when calling all Instance::New methods.
	Part& spawnOne = Instance::New<Part>(game["Environment"]);
	std::cout << spawnOne.Name << std::endl; // "Part"

	// You can also define instances like this. It, however, may return a null pointer.
	Instance* spawnTwo = Instance::New("Part", game["Environment"]);

	// There's a third way you can make instances, but the default name will be Instance unless set.
	// In addition, it will be on the stack, and will cause problems if you leave the function it was defined in.
	Part spawnThree = Part();
	std::cout << spawnThree.Name << std::endl; // "Instance"

	// You can get the parent and set the parent with the SetParent() and GetParent() methods.
	// Do note that these functions take in or output pointers.
	std::cout << spawnOne.GetParent()->Name << std::endl; // "Environment"

	// You can also use template bracketing as a sort of type annotation.
	// It will be nothing if the Instance isn't derived from that type.
	Environment* environment = spawnOne.GetParent<Environment>();
	
	// The ClassName property is special.
	// It's actually a function. If it wasn't, you could edit it, and cause shenanigans.
	// A couple of other read-only properties are like this for Polytoria types.
	std::cout << game["Environment"].ClassName() << std::endl; // "Environment"

	// Setting and getting properties can be done just like in Lua.
	spawnOne.Position = Vector3::New(0, 1, 0); // Polytoria types can be constructed with ::New
	spawnOne.IsSpawn = true;
	spawnOne.Name = "Spawn1";
	spawnTwo->Name = "Spawn2";
	spawnThree.Position = Vector3(34.5, 1, 4); // You can do T() and it's probably fine, minus the constructors that only exist under ::New
	spawnThree.IsSpawn = true;
	spawnThree.Name = "Spawn3";
	spawnThree.SetParent(&game["Environment"]);

	// You can also set properties this way.
	// This is useful if you're trying to set a DynamicInstance property on an Instance.
	spawnTwo->SetProperty("Position", Vector3::New(-38.5, 1, -48.5));
	spawnTwo->SetProperty("IsSpawn", true);

	// It will not throw any errors if the property name doesn't exist.
	// It, however, will throw errors if you specify the type wrongly.
	spawnTwo->SetProperty("AAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAA");

	// Properties can also be gotten this way.
	// This version will never throw, but will return an empty std::any if the property doesn't exist.
	std::any nameAny = spawnTwo->GetProperty("Name");

	// You can also cast it to a normal type with template brackets.
	// Do note that this will throw if you specify the name or the type wrong.
	std::string name = spawnTwo->GetProperty<std::string>("Name");

	// You can iterate through all properties of an object like this.
	for (Property property : game.GetProperties()) {
		std::cout << property.type << " " << property.name << std::endl; // String Name

		// Since there is no property.value, if you wish to get or set a property, you must do this:
		if (property.type == "String") {
			game.SetProperty<std::string>(property.name, "AAAA");
			std::cout << game.GetProperty<std::string>(property.name) << std::endl; // AAAA
		}
	}

	// You can also get the type of an individual property.
	std::cout << convertTypeName(nameAny.type()) << std::endl; // String

	// You can also just feed in an std::any value directly.
	std::cout << convertTypeName(nameAny) << std::endl; // String

	// Accessing children can also be done just like in Lua, but with two major caveats.
	// - It will throw if an Instance doesn't exist with that name.
	// - The type will ALWAYS be Instance. If you wish to access properties with the . operator, that's not great.
	Instance& backpack = game["PlayerDefaults"]["Backpack"];

	// FindChild is similar, but can be used to solve these problems.
	// - It will return a null pointer if an Instance doesn't exist with that name.
	// - Type can be specified with templates.
	Instance* backpackPointer = game["PlayerDefaults"].FindChild("Backpack"); // This is fine, it will automatically assume Instance.

	// This templated hybrid of FindChild and FindChildOfClass solves that issue.
	// However, it will only return anything if any children with that name derive from the specified class.
	Backpack* backpackBackpack = game["PlayerDefaults"].FindChild<Backpack>("Backpack");

	// This issue does't exist with FindChildOfClass, which has to be templated.
	// This will return anything that derives from the specified type.
	backpackBackpack = game["PlayerDefaults"].FindChildByClass<Backpack>();

	// All templated class type checks are based on inheritance, unlike in Polytoria.
	std::cout << (backpack.IsA<Instance>() ? "true" : "false") << std::endl; // true

	// Looping through children can be done similarly to Lua.
	for (Instance& child : game["Lighting"].GetChildren()) {
		std::cout << child.Name << std::endl;
	}
	
	// Unlike in Polytoria, this checks with inheritance, instead of just checking if the ClassName is equal to a specific string.
	for (DynamicInstance& child : game["Lighting"].GetChildrenOfClass<DynamicInstance>()) {
		std::cout << child.Name << std::endl; // "SunLight"
	}

	// You can destroy objects. This frees up their memory and deparents them.
	// If you want to temporarily deparent an object, use SetParent(nullptr). Don't reparent these objects.
	backpack.Delete();
	backpack.Destroy(); // This does the same thing. I have no idea what the Polytoria distinction is.

	// When you're done making changes, you can save the place like so.
	Place::SaveFile(game, "examples\\officeTemplateModifed.poly");

	// You can also save instances as a model file. (Note, the file type distinction is arbitrary, the actual Polytoria Creator doesn't care.)
	Place::SaveFile(game["Environment"]["Spawn1"], "examples\\spawn1.ptmd");
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors