@@ -775,19 +775,27 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
775775 PyObject *obj;
776776 char *name;
777777 PyObject *property_class = nullptr ;
778- if (!PyArg_ParseTuple (args, " Os|O:add_property" , &obj, &name, &property_class)) {
778+ PyObject *property_class2 = nullptr ;
779+ if (!PyArg_ParseTuple (args, " Os|OO:add_property" , &obj, &name, &property_class, &property_class2)) {
779780 return NULL ;
780781 }
781782
782783 if (!self->ue_object ->IsA <UStruct>())
783784 return PyErr_Format (PyExc_Exception, " uobject is not a UStruct" );
784785
785786 UObject *scope = nullptr ;
787+
786788 UProperty *u_property = nullptr ;
787789 UClass *u_class = nullptr ;
790+ UProperty *u_property2 = nullptr ;
791+ UClass *u_class2 = nullptr ;
792+
788793 UClass *u_prop_class = nullptr ;
789794 UScriptStruct *u_script_struct = nullptr ;
795+ UClass *u_prop_class2 = nullptr ;
796+ UScriptStruct *u_script_struct2 = nullptr ;
790797 bool is_array = false ;
798+ bool is_map = false ;
791799
792800 if (property_class) {
793801 if (!ue_is_pyuobject (property_class)) {
@@ -805,6 +813,22 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
805813 }
806814 }
807815
816+ if (property_class2) {
817+ if (!ue_is_pyuobject (property_class2)) {
818+ return PyErr_Format (PyExc_Exception, " property class arg is not a uobject" );
819+ }
820+ ue_PyUObject *py_prop_class = (ue_PyUObject *)property_class2;
821+ if (py_prop_class->ue_object ->IsA <UClass>()) {
822+ u_prop_class2 = (UClass *)py_prop_class->ue_object ;
823+ }
824+ else if (py_prop_class->ue_object ->IsA <UScriptStruct>()) {
825+ u_script_struct2 = (UScriptStruct *)py_prop_class->ue_object ;
826+ }
827+ else {
828+ return PyErr_Format (PyExc_Exception, " property class arg is not a UClass or a UScriptStruct" );
829+ }
830+ }
831+
808832 EObjectFlags o_flags = RF_Public | RF_MarkAsNative;// | RF_Transient;
809833
810834 if (ue_is_pyuobject (obj)) {
@@ -840,6 +864,44 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
840864 }
841865 Py_DECREF (py_item);
842866 }
867+ #if ENGINE_MINOR_VERSION >= 15
868+ else if (PyList_Size (obj) == 2 ) {
869+ PyObject *py_key = PyList_GetItem (obj, 0 );
870+ PyObject *py_value = PyList_GetItem (obj, 1 );
871+ if (ue_is_pyuobject (py_key) && ue_is_pyuobject (py_value)) {
872+ // KEY
873+ ue_PyUObject *py_obj = (ue_PyUObject *)py_key;
874+ if (!py_obj->ue_object ->IsA <UClass>()) {
875+ return PyErr_Format (PyExc_Exception, " uobject is not a UClass" );
876+ }
877+ u_class = (UClass *)py_obj->ue_object ;
878+ if (!u_class->IsChildOf <UProperty>())
879+ return PyErr_Format (PyExc_Exception, " uobject is not a UProperty" );
880+ if (u_class == UArrayProperty::StaticClass ())
881+ return PyErr_Format (PyExc_Exception, " please use a two-items list of properties for maps" );
882+
883+ // VALUE
884+ ue_PyUObject *py_obj2 = (ue_PyUObject *)py_value;
885+ if (!py_obj2->ue_object ->IsA <UClass>()) {
886+ return PyErr_Format (PyExc_Exception, " uobject is not a UClass" );
887+ }
888+ u_class2 = (UClass *)py_obj2->ue_object ;
889+ if (!u_class2->IsChildOf <UProperty>())
890+ return PyErr_Format (PyExc_Exception, " uobject is not a UProperty" );
891+ if (u_class2 == UArrayProperty::StaticClass ())
892+ return PyErr_Format (PyExc_Exception, " please use a two-items list of properties for maps" );
893+
894+
895+ UMapProperty *u_map = NewObject<UMapProperty>(self->ue_object , UTF8_TO_TCHAR (name), o_flags);
896+ if (!u_map)
897+ return PyErr_Format (PyExc_Exception, " unable to allocate new UProperty" );
898+ scope = u_map;
899+ is_map = true ;
900+ }
901+ Py_DECREF (py_key);
902+ Py_DECREF (py_value);
903+ }
904+ #endif
843905 }
844906
845907
@@ -849,7 +911,7 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
849911
850912 u_property = NewObject<UProperty>(scope, u_class, UTF8_TO_TCHAR (name), o_flags);
851913 if (!u_property) {
852- if (is_array)
914+ if (is_array || is_map )
853915 scope->MarkPendingKill ();
854916 return PyErr_Format (PyExc_Exception, " unable to allocate new UProperty" );
855917 }
@@ -888,6 +950,53 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
888950 u_property = u_array;
889951 }
890952
953+ #if ENGINE_MINOR_VERSION >= 15
954+ if (is_map) {
955+ u_property2 = NewObject<UProperty>(scope, u_class2, NAME_None, o_flags);
956+ if (!u_property2) {
957+ if (is_array || is_map)
958+ scope->MarkPendingKill ();
959+ return PyErr_Format (PyExc_Exception, " unable to allocate new UProperty" );
960+ }
961+ UMapProperty *u_map = (UMapProperty *)scope;
962+
963+
964+ u_property->SetPropertyFlags (flags);
965+ u_property2->SetPropertyFlags (flags);
966+
967+ if (u_property->GetClass () == UObjectProperty::StaticClass ()) {
968+ UObjectProperty *obj_prop = (UObjectProperty *)u_property;
969+ if (u_prop_class) {
970+ obj_prop->SetPropertyClass (u_prop_class);
971+ }
972+ }
973+ if (u_property->GetClass () == UStructProperty::StaticClass ()) {
974+ UStructProperty *obj_prop = (UStructProperty *)u_property;
975+ if (u_script_struct) {
976+ obj_prop->Struct = u_script_struct;
977+ }
978+ }
979+
980+ if (u_property2->GetClass () == UObjectProperty::StaticClass ()) {
981+ UObjectProperty *obj_prop = (UObjectProperty *)u_property2;
982+ if (u_prop_class2) {
983+ obj_prop->SetPropertyClass (u_prop_class2);
984+ }
985+ }
986+ if (u_property2->GetClass () == UStructProperty::StaticClass ()) {
987+ UStructProperty *obj_prop = (UStructProperty *)u_property2;
988+ if (u_script_struct2) {
989+ obj_prop->Struct = u_script_struct2;
990+ }
991+ }
992+
993+ u_map->KeyProp = u_property;
994+ u_map->ValueProp = u_property2;
995+
996+ u_property = u_map;
997+ }
998+ #endif
999+
8911000 if (u_class == UMulticastDelegateProperty::StaticClass ()) {
8921001 UMulticastDelegateProperty *mcp = (UMulticastDelegateProperty *)u_property;
8931002 mcp->SignatureFunction = NewObject<UFunction>(self->ue_object , NAME_None, RF_Public | RF_Transient | RF_MarkAsNative);
@@ -906,7 +1015,7 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
9061015
9071016 else if (u_class == UObjectProperty::StaticClass ()) {
9081017 // ensure it is not an arry as we have already managed it !
909- if (!is_array) {
1018+ if (!is_array && !is_map ) {
9101019 UObjectProperty *obj_prop = (UObjectProperty *)u_property;
9111020 if (u_prop_class) {
9121021 obj_prop->SetPropertyClass (u_prop_class);
@@ -916,7 +1025,7 @@ PyObject *py_ue_add_property(ue_PyUObject * self, PyObject * args) {
9161025
9171026 else if (u_class == UStructProperty::StaticClass ()) {
9181027 // ensure it is not an arry as we have already managed it !
919- if (!is_array) {
1028+ if (!is_array && !is_map ) {
9201029 UStructProperty *obj_prop = (UStructProperty *)u_property;
9211030 if (u_script_struct) {
9221031 obj_prop->Struct = u_script_struct;
0 commit comments