# automatically generated by the FlatBuffers compiler, do not modify

# namespace: Example

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

# an example documentation comment: "monster object"
class Monster(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Monster()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsMonster(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Monster
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Monster
    def Pos(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            x = o + self._tab.Pos
            from MyGame.Example.Vec3 import Vec3
            obj = Vec3()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Mana(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 150

    # Monster
    def Hp(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 100

    # Monster
    def Name(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.String(o + self._tab.Pos)
        return None

    # Monster
    def Inventory(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def InventoryAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def InventoryLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def InventoryIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        return o == 0

    # Monster
    def Color(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 8

    # Monster
    def TestType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Test(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def Test4(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test4Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test4IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        return o == 0

    # Monster
    def Testarrayofstring(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def TestarrayofstringLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofstringIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        return o == 0

    # an example documentation comment: this will end up in the generated code
    # multiline too
    # Monster
    def Testarrayoftables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Monster import Monster
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayoftablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayoftablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        return o == 0

    # Monster
    def Enemy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.Example.Monster import Monster
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testnestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestnestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestnestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestnestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestnestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        return o == 0

    # Monster
    def Testempty(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.Example.Stat import Stat
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testbool(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
        if o != 0:
            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
        return False

    # Monster
    def Testhashs32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(40))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(44))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(48))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(50))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testarrayofbools(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.BoolFlags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestarrayofboolsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.BoolFlags, o)
        return 0

    # Monster
    def TestarrayofboolsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofboolsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        return o == 0

    # Monster
    def Testf(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.14159

    # Monster
    def Testf2(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(56))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.0

    # Monster
    def Testf3(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(58))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 0.0

    # Monster
    def Testarrayofstring2(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def Testarrayofstring2Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Testarrayofstring2IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        return o == 0

    # Monster
    def Testarrayofsortedstruct(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
            from MyGame.Example.Ability import Ability
            obj = Ability()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayofsortedstructLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofsortedstructIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        return o == 0

    # Monster
    def Flex(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def FlexAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def FlexLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def FlexIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        return o == 0

    # Monster
    def Test5(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test5Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test5IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        return o == 0

    # Monster
    def VectorOfLongs(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfLongsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int64Flags, o)
        return 0

    # Monster
    def VectorOfLongsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfLongsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        return o == 0

    # Monster
    def VectorOfDoubles(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfDoublesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
        return 0

    # Monster
    def VectorOfDoublesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfDoublesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        return o == 0

    # Monster
    def ParentNamespaceTest(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            from MyGame.InParentNamespace import InParentNamespace
            obj = InParentNamespace()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Referrable import Referrable
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        return o == 0

    # Monster
    def SingleWeakReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfWeakReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfWeakReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfWeakReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfWeakReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        return o == 0

    # Monster
    def VectorOfStrongReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Referrable import Referrable
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfStrongReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfStrongReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        return o == 0

    # Monster
    def CoOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfCoOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfCoOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        return o == 0

    # Monster
    def NonOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfNonOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfNonOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        return o == 0

    # Monster
    def AnyUniqueType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyUnique(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(92))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def AnyAmbiguousType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(94))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyAmbiguous(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(96))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def VectorOfEnums(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def VectorOfEnumsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def VectorOfEnumsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfEnumsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        return o == 0

    # Monster
    def SignedEnum(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(100))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
        return -1

    # Monster
    def Testrequirednestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestrequirednestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestrequirednestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestrequirednestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestrequirednestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        return o == 0

    # Monster
    def ScalarKeySortedTables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            from MyGame.Example.Stat import Stat
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def ScalarKeySortedTablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def ScalarKeySortedTablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        return o == 0

    # Monster
    def NativeInline(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(106))
        if o != 0:
            x = o + self._tab.Pos
            from MyGame.Example.Test import Test
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def LongEnumNonEnumDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(108))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def LongEnumNormalDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(110))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 2

    # Monster
    def NanDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(112))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('nan')

    # Monster
    def InfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(114))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(116))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def InfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(118))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(120))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def NegativeInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(122))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def NegativeInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(124))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def DoubleInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(126))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('inf')

def MonsterStart(builder):
    builder.StartObject(62)

def Start(builder):
    MonsterStart(builder)

def MonsterAddPos(builder, pos):
    builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)

def AddPos(builder, pos):
    MonsterAddPos(builder, pos)

def MonsterAddMana(builder, mana):
    builder.PrependInt16Slot(1, mana, 150)

def AddMana(builder, mana):
    MonsterAddMana(builder, mana)

def MonsterAddHp(builder, hp):
    builder.PrependInt16Slot(2, hp, 100)

def AddHp(builder, hp):
    MonsterAddHp(builder, hp)

def MonsterAddName(builder, name):
    builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)

def AddName(builder, name):
    MonsterAddName(builder, name)

def MonsterAddInventory(builder, inventory):
    builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)

def AddInventory(builder, inventory):
    MonsterAddInventory(builder, inventory)

def MonsterStartInventoryVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartInventoryVector(builder, numElems):
    return MonsterStartInventoryVector(builder, numElems)

def MonsterAddColor(builder, color):
    builder.PrependUint8Slot(6, color, 8)

def AddColor(builder, color):
    MonsterAddColor(builder, color)

def MonsterAddTestType(builder, testType):
    builder.PrependUint8Slot(7, testType, 0)

def AddTestType(builder, testType):
    MonsterAddTestType(builder, testType)

def MonsterAddTest(builder, test):
    builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)

def AddTest(builder, test):
    MonsterAddTest(builder, test)

def MonsterAddTest4(builder, test4):
    builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)

def AddTest4(builder, test4):
    MonsterAddTest4(builder, test4)

def MonsterStartTest4Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def StartTest4Vector(builder, numElems):
    return MonsterStartTest4Vector(builder, numElems)

def MonsterAddTestarrayofstring(builder, testarrayofstring):
    builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring), 0)

def AddTestarrayofstring(builder, testarrayofstring):
    MonsterAddTestarrayofstring(builder, testarrayofstring)

def MonsterStartTestarrayofstringVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayofstringVector(builder, numElems):
    return MonsterStartTestarrayofstringVector(builder, numElems)

def MonsterAddTestarrayoftables(builder, testarrayoftables):
    builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayoftables), 0)

def AddTestarrayoftables(builder, testarrayoftables):
    MonsterAddTestarrayoftables(builder, testarrayoftables)

def MonsterStartTestarrayoftablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayoftablesVector(builder, numElems):
    return MonsterStartTestarrayoftablesVector(builder, numElems)

def MonsterAddEnemy(builder, enemy):
    builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)

def AddEnemy(builder, enemy):
    MonsterAddEnemy(builder, enemy)

def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)

def AddTestnestedflatbuffer(builder, testnestedflatbuffer):
    MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)

def MonsterStartTestnestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestnestedflatbufferVector(builder, numElems):
    return MonsterStartTestnestedflatbufferVector(builder, numElems)

def MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MakeTestnestedflatbufferVectorFromBytes(builder, bytes):
    return MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes)
def MonsterAddTestempty(builder, testempty):
    builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)

def AddTestempty(builder, testempty):
    MonsterAddTestempty(builder, testempty)

def MonsterAddTestbool(builder, testbool):
    builder.PrependBoolSlot(15, testbool, 0)

def AddTestbool(builder, testbool):
    MonsterAddTestbool(builder, testbool)

def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1):
    builder.PrependInt32Slot(16, testhashs32Fnv1, 0)

def AddTesthashs32Fnv1(builder, testhashs32Fnv1):
    MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1)

def MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1):
    builder.PrependUint32Slot(17, testhashu32Fnv1, 0)

def AddTesthashu32Fnv1(builder, testhashu32Fnv1):
    MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1)

def MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1):
    builder.PrependInt64Slot(18, testhashs64Fnv1, 0)

def AddTesthashs64Fnv1(builder, testhashs64Fnv1):
    MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1)

def MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1):
    builder.PrependUint64Slot(19, testhashu64Fnv1, 0)

def AddTesthashu64Fnv1(builder, testhashu64Fnv1):
    MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1)

def MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a):
    builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)

def AddTesthashs32Fnv1a(builder, testhashs32Fnv1a):
    MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a)

def MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a):
    builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)

def AddTesthashu32Fnv1a(builder, testhashu32Fnv1a):
    MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a)

def MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a):
    builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)

def AddTesthashs64Fnv1a(builder, testhashs64Fnv1a):
    MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a)

def MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a):
    builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)

def AddTesthashu64Fnv1a(builder, testhashu64Fnv1a):
    MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a)

def MonsterAddTestarrayofbools(builder, testarrayofbools):
    builder.PrependUOffsetTRelativeSlot(24, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofbools), 0)

def AddTestarrayofbools(builder, testarrayofbools):
    MonsterAddTestarrayofbools(builder, testarrayofbools)

def MonsterStartTestarrayofboolsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestarrayofboolsVector(builder, numElems):
    return MonsterStartTestarrayofboolsVector(builder, numElems)

def MonsterAddTestf(builder, testf):
    builder.PrependFloat32Slot(25, testf, 3.14159)

def AddTestf(builder, testf):
    MonsterAddTestf(builder, testf)

def MonsterAddTestf2(builder, testf2):
    builder.PrependFloat32Slot(26, testf2, 3.0)

def AddTestf2(builder, testf2):
    MonsterAddTestf2(builder, testf2)

def MonsterAddTestf3(builder, testf3):
    builder.PrependFloat32Slot(27, testf3, 0.0)

def AddTestf3(builder, testf3):
    MonsterAddTestf3(builder, testf3)

def MonsterAddTestarrayofstring2(builder, testarrayofstring2):
    builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0)

def AddTestarrayofstring2(builder, testarrayofstring2):
    MonsterAddTestarrayofstring2(builder, testarrayofstring2)

def MonsterStartTestarrayofstring2Vector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartTestarrayofstring2Vector(builder, numElems):
    return MonsterStartTestarrayofstring2Vector(builder, numElems)

def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct):
    builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)

def AddTestarrayofsortedstruct(builder, testarrayofsortedstruct):
    MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)

def MonsterStartTestarrayofsortedstructVector(builder, numElems):
    return builder.StartVector(8, numElems, 4)

def StartTestarrayofsortedstructVector(builder, numElems):
    return MonsterStartTestarrayofsortedstructVector(builder, numElems)

def MonsterAddFlex(builder, flex):
    builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)

def AddFlex(builder, flex):
    MonsterAddFlex(builder, flex)

def MonsterStartFlexVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartFlexVector(builder, numElems):
    return MonsterStartFlexVector(builder, numElems)

def MonsterAddTest5(builder, test5):
    builder.PrependUOffsetTRelativeSlot(31, flatbuffers.number_types.UOffsetTFlags.py_type(test5), 0)

def AddTest5(builder, test5):
    MonsterAddTest5(builder, test5)

def MonsterStartTest5Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def StartTest5Vector(builder, numElems):
    return MonsterStartTest5Vector(builder, numElems)

def MonsterAddVectorOfLongs(builder, vectorOfLongs):
    builder.PrependUOffsetTRelativeSlot(32, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfLongs), 0)

def AddVectorOfLongs(builder, vectorOfLongs):
    MonsterAddVectorOfLongs(builder, vectorOfLongs)

def MonsterStartVectorOfLongsVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfLongsVector(builder, numElems):
    return MonsterStartVectorOfLongsVector(builder, numElems)

def MonsterAddVectorOfDoubles(builder, vectorOfDoubles):
    builder.PrependUOffsetTRelativeSlot(33, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfDoubles), 0)

def AddVectorOfDoubles(builder, vectorOfDoubles):
    MonsterAddVectorOfDoubles(builder, vectorOfDoubles)

def MonsterStartVectorOfDoublesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfDoublesVector(builder, numElems):
    return MonsterStartVectorOfDoublesVector(builder, numElems)

def MonsterAddParentNamespaceTest(builder, parentNamespaceTest):
    builder.PrependUOffsetTRelativeSlot(34, flatbuffers.number_types.UOffsetTFlags.py_type(parentNamespaceTest), 0)

def AddParentNamespaceTest(builder, parentNamespaceTest):
    MonsterAddParentNamespaceTest(builder, parentNamespaceTest)

def MonsterAddVectorOfReferrables(builder, vectorOfReferrables):
    builder.PrependUOffsetTRelativeSlot(35, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfReferrables), 0)

def AddVectorOfReferrables(builder, vectorOfReferrables):
    MonsterAddVectorOfReferrables(builder, vectorOfReferrables)

def MonsterStartVectorOfReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartVectorOfReferrablesVector(builder, numElems):
    return MonsterStartVectorOfReferrablesVector(builder, numElems)

def MonsterAddSingleWeakReference(builder, singleWeakReference):
    builder.PrependUint64Slot(36, singleWeakReference, 0)

def AddSingleWeakReference(builder, singleWeakReference):
    MonsterAddSingleWeakReference(builder, singleWeakReference)

def MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences):
    builder.PrependUOffsetTRelativeSlot(37, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfWeakReferences), 0)

def AddVectorOfWeakReferences(builder, vectorOfWeakReferences):
    MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)

def MonsterStartVectorOfWeakReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfWeakReferencesVector(builder, numElems):
    return MonsterStartVectorOfWeakReferencesVector(builder, numElems)

def MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables):
    builder.PrependUOffsetTRelativeSlot(38, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfStrongReferrables), 0)

def AddVectorOfStrongReferrables(builder, vectorOfStrongReferrables):
    MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)

def MonsterStartVectorOfStrongReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartVectorOfStrongReferrablesVector(builder, numElems):
    return MonsterStartVectorOfStrongReferrablesVector(builder, numElems)

def MonsterAddCoOwningReference(builder, coOwningReference):
    builder.PrependUint64Slot(39, coOwningReference, 0)

def AddCoOwningReference(builder, coOwningReference):
    MonsterAddCoOwningReference(builder, coOwningReference)

def MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences):
    builder.PrependUOffsetTRelativeSlot(40, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfCoOwningReferences), 0)

def AddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences):
    MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)

def MonsterStartVectorOfCoOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfCoOwningReferencesVector(builder, numElems):
    return MonsterStartVectorOfCoOwningReferencesVector(builder, numElems)

def MonsterAddNonOwningReference(builder, nonOwningReference):
    builder.PrependUint64Slot(41, nonOwningReference, 0)

def AddNonOwningReference(builder, nonOwningReference):
    MonsterAddNonOwningReference(builder, nonOwningReference)

def MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences):
    builder.PrependUOffsetTRelativeSlot(42, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfNonOwningReferences), 0)

def AddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences):
    MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)

def MonsterStartVectorOfNonOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def StartVectorOfNonOwningReferencesVector(builder, numElems):
    return MonsterStartVectorOfNonOwningReferencesVector(builder, numElems)

def MonsterAddAnyUniqueType(builder, anyUniqueType):
    builder.PrependUint8Slot(43, anyUniqueType, 0)

def AddAnyUniqueType(builder, anyUniqueType):
    MonsterAddAnyUniqueType(builder, anyUniqueType)

def MonsterAddAnyUnique(builder, anyUnique):
    builder.PrependUOffsetTRelativeSlot(44, flatbuffers.number_types.UOffsetTFlags.py_type(anyUnique), 0)

def AddAnyUnique(builder, anyUnique):
    MonsterAddAnyUnique(builder, anyUnique)

def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType):
    builder.PrependUint8Slot(45, anyAmbiguousType, 0)

def AddAnyAmbiguousType(builder, anyAmbiguousType):
    MonsterAddAnyAmbiguousType(builder, anyAmbiguousType)

def MonsterAddAnyAmbiguous(builder, anyAmbiguous):
    builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)

def AddAnyAmbiguous(builder, anyAmbiguous):
    MonsterAddAnyAmbiguous(builder, anyAmbiguous)

def MonsterAddVectorOfEnums(builder, vectorOfEnums):
    builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)

def AddVectorOfEnums(builder, vectorOfEnums):
    MonsterAddVectorOfEnums(builder, vectorOfEnums)

def MonsterStartVectorOfEnumsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartVectorOfEnumsVector(builder, numElems):
    return MonsterStartVectorOfEnumsVector(builder, numElems)

def MonsterAddSignedEnum(builder, signedEnum):
    builder.PrependInt8Slot(48, signedEnum, -1)

def AddSignedEnum(builder, signedEnum):
    MonsterAddSignedEnum(builder, signedEnum)

def MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(49, flatbuffers.number_types.UOffsetTFlags.py_type(testrequirednestedflatbuffer), 0)

def AddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer):
    MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer)

def MonsterStartTestrequirednestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartTestrequirednestedflatbufferVector(builder, numElems):
    return MonsterStartTestrequirednestedflatbufferVector(builder, numElems)

def MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
    return MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes)
def MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables):
    builder.PrependUOffsetTRelativeSlot(50, flatbuffers.number_types.UOffsetTFlags.py_type(scalarKeySortedTables), 0)

def AddScalarKeySortedTables(builder, scalarKeySortedTables):
    MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables)

def MonsterStartScalarKeySortedTablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def StartScalarKeySortedTablesVector(builder, numElems):
    return MonsterStartScalarKeySortedTablesVector(builder, numElems)

def MonsterAddNativeInline(builder, nativeInline):
    builder.PrependStructSlot(51, flatbuffers.number_types.UOffsetTFlags.py_type(nativeInline), 0)

def AddNativeInline(builder, nativeInline):
    MonsterAddNativeInline(builder, nativeInline)

def MonsterAddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault):
    builder.PrependUint64Slot(52, longEnumNonEnumDefault, 0)

def AddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault):
    MonsterAddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault)

def MonsterAddLongEnumNormalDefault(builder, longEnumNormalDefault):
    builder.PrependUint64Slot(53, longEnumNormalDefault, 2)

def AddLongEnumNormalDefault(builder, longEnumNormalDefault):
    MonsterAddLongEnumNormalDefault(builder, longEnumNormalDefault)

def MonsterAddNanDefault(builder, nanDefault):
    builder.PrependFloat32Slot(54, nanDefault, float('nan'))

def AddNanDefault(builder, nanDefault):
    MonsterAddNanDefault(builder, nanDefault)

def MonsterAddInfDefault(builder, infDefault):
    builder.PrependFloat32Slot(55, infDefault, float('inf'))

def AddInfDefault(builder, infDefault):
    MonsterAddInfDefault(builder, infDefault)

def MonsterAddPositiveInfDefault(builder, positiveInfDefault):
    builder.PrependFloat32Slot(56, positiveInfDefault, float('inf'))

def AddPositiveInfDefault(builder, positiveInfDefault):
    MonsterAddPositiveInfDefault(builder, positiveInfDefault)

def MonsterAddInfinityDefault(builder, infinityDefault):
    builder.PrependFloat32Slot(57, infinityDefault, float('inf'))

def AddInfinityDefault(builder, infinityDefault):
    MonsterAddInfinityDefault(builder, infinityDefault)

def MonsterAddPositiveInfinityDefault(builder, positiveInfinityDefault):
    builder.PrependFloat32Slot(58, positiveInfinityDefault, float('inf'))

def AddPositiveInfinityDefault(builder, positiveInfinityDefault):
    MonsterAddPositiveInfinityDefault(builder, positiveInfinityDefault)

def MonsterAddNegativeInfDefault(builder, negativeInfDefault):
    builder.PrependFloat32Slot(59, negativeInfDefault, float('-inf'))

def AddNegativeInfDefault(builder, negativeInfDefault):
    MonsterAddNegativeInfDefault(builder, negativeInfDefault)

def MonsterAddNegativeInfinityDefault(builder, negativeInfinityDefault):
    builder.PrependFloat32Slot(60, negativeInfinityDefault, float('-inf'))

def AddNegativeInfinityDefault(builder, negativeInfinityDefault):
    MonsterAddNegativeInfinityDefault(builder, negativeInfinityDefault)

def MonsterAddDoubleInfDefault(builder, doubleInfDefault):
    builder.PrependFloat64Slot(61, doubleInfDefault, float('inf'))

def AddDoubleInfDefault(builder, doubleInfDefault):
    MonsterAddDoubleInfDefault(builder, doubleInfDefault)

def MonsterEnd(builder):
    return builder.EndObject()

def End(builder):
    return MonsterEnd(builder)

import MyGame.Example.Ability
import MyGame.Example.Any
import MyGame.Example.AnyAmbiguousAliases
import MyGame.Example.AnyUniqueAliases
import MyGame.Example.Referrable
import MyGame.Example.Stat
import MyGame.Example.Test
import MyGame.Example.TestSimpleTableWithEnum
import MyGame.Example.Vec3
import MyGame.Example2.Monster
import MyGame.InParentNamespace
try:
    from typing import List, Optional, Union
except:
    pass

class MonsterT(object):

    # MonsterT
    def __init__(
        self,
        pos = None,
        mana = 150,
        hp = 100,
        name = None,
        inventory = None,
        color = 8,
        testType = 0,
        test = None,
        test4 = None,
        testarrayofstring = None,
        testarrayoftables = None,
        enemy = None,
        testnestedflatbuffer = None,
        testempty = None,
        testbool = False,
        testhashs32Fnv1 = 0,
        testhashu32Fnv1 = 0,
        testhashs64Fnv1 = 0,
        testhashu64Fnv1 = 0,
        testhashs32Fnv1a = 0,
        testhashu32Fnv1a = 0,
        testhashs64Fnv1a = 0,
        testhashu64Fnv1a = 0,
        testarrayofbools = None,
        testf = 3.14159,
        testf2 = 3.0,
        testf3 = 0.0,
        testarrayofstring2 = None,
        testarrayofsortedstruct = None,
        flex = None,
        test5 = None,
        vectorOfLongs = None,
        vectorOfDoubles = None,
        parentNamespaceTest = None,
        vectorOfReferrables = None,
        singleWeakReference = 0,
        vectorOfWeakReferences = None,
        vectorOfStrongReferrables = None,
        coOwningReference = 0,
        vectorOfCoOwningReferences = None,
        nonOwningReference = 0,
        vectorOfNonOwningReferences = None,
        anyUniqueType = 0,
        anyUnique = None,
        anyAmbiguousType = 0,
        anyAmbiguous = None,
        vectorOfEnums = None,
        signedEnum = -1,
        testrequirednestedflatbuffer = None,
        scalarKeySortedTables = None,
        nativeInline = None,
        longEnumNonEnumDefault = 0,
        longEnumNormalDefault = 2,
        nanDefault = float('nan'),
        infDefault = float('inf'),
        positiveInfDefault = float('inf'),
        infinityDefault = float('inf'),
        positiveInfinityDefault = float('inf'),
        negativeInfDefault = float('-inf'),
        negativeInfinityDefault = float('-inf'),
        doubleInfDefault = float('inf'),
    ):
        self.pos = pos  # type: Optional[MyGame.Example.Vec3.Vec3T]
        self.mana = mana  # type: int
        self.hp = hp  # type: int
        self.name = name  # type: Optional[str]
        self.inventory = inventory  # type: Optional[List[int]]
        self.color = color  # type: int
        self.testType = testType  # type: int
        self.test = test  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT', 'MyGame.Example2.Monster.MonsterT']
        self.test4 = test4  # type: Optional[List[MyGame.Example.Test.TestT]]
        self.testarrayofstring = testarrayofstring  # type: Optional[List[Optional[str]]]
        self.testarrayoftables = testarrayoftables  # type: Optional[List[MyGame.Example.Monster.MonsterT]]
        self.enemy = enemy  # type: Optional[MyGame.Example.Monster.MonsterT]
        self.testnestedflatbuffer = testnestedflatbuffer  # type: Optional[List[int]]
        self.testempty = testempty  # type: Optional[MyGame.Example.Stat.StatT]
        self.testbool = testbool  # type: bool
        self.testhashs32Fnv1 = testhashs32Fnv1  # type: int
        self.testhashu32Fnv1 = testhashu32Fnv1  # type: int
        self.testhashs64Fnv1 = testhashs64Fnv1  # type: int
        self.testhashu64Fnv1 = testhashu64Fnv1  # type: int
        self.testhashs32Fnv1a = testhashs32Fnv1a  # type: int
        self.testhashu32Fnv1a = testhashu32Fnv1a  # type: int
        self.testhashs64Fnv1a = testhashs64Fnv1a  # type: int
        self.testhashu64Fnv1a = testhashu64Fnv1a  # type: int
        self.testarrayofbools = testarrayofbools  # type: Optional[List[bool]]
        self.testf = testf  # type: float
        self.testf2 = testf2  # type: float
        self.testf3 = testf3  # type: float
        self.testarrayofstring2 = testarrayofstring2  # type: Optional[List[Optional[str]]]
        self.testarrayofsortedstruct = testarrayofsortedstruct  # type: Optional[List[MyGame.Example.Ability.AbilityT]]
        self.flex = flex  # type: Optional[List[int]]
        self.test5 = test5  # type: Optional[List[MyGame.Example.Test.TestT]]
        self.vectorOfLongs = vectorOfLongs  # type: Optional[List[int]]
        self.vectorOfDoubles = vectorOfDoubles  # type: Optional[List[float]]
        self.parentNamespaceTest = parentNamespaceTest  # type: Optional[MyGame.InParentNamespace.InParentNamespaceT]
        self.vectorOfReferrables = vectorOfReferrables  # type: Optional[List[MyGame.Example.Referrable.ReferrableT]]
        self.singleWeakReference = singleWeakReference  # type: int
        self.vectorOfWeakReferences = vectorOfWeakReferences  # type: Optional[List[int]]
        self.vectorOfStrongReferrables = vectorOfStrongReferrables  # type: Optional[List[MyGame.Example.Referrable.ReferrableT]]
        self.coOwningReference = coOwningReference  # type: int
        self.vectorOfCoOwningReferences = vectorOfCoOwningReferences  # type: Optional[List[int]]
        self.nonOwningReference = nonOwningReference  # type: int
        self.vectorOfNonOwningReferences = vectorOfNonOwningReferences  # type: Optional[List[int]]
        self.anyUniqueType = anyUniqueType  # type: int
        self.anyUnique = anyUnique  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT', 'MyGame.Example2.Monster.MonsterT']
        self.anyAmbiguousType = anyAmbiguousType  # type: int
        self.anyAmbiguous = anyAmbiguous  # type: Union[None, 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.Monster.MonsterT', 'MyGame.Example.Monster.MonsterT']
        self.vectorOfEnums = vectorOfEnums  # type: Optional[List[int]]
        self.signedEnum = signedEnum  # type: int
        self.testrequirednestedflatbuffer = testrequirednestedflatbuffer  # type: Optional[List[int]]
        self.scalarKeySortedTables = scalarKeySortedTables  # type: Optional[List[MyGame.Example.Stat.StatT]]
        self.nativeInline = nativeInline  # type: Optional[MyGame.Example.Test.TestT]
        self.longEnumNonEnumDefault = longEnumNonEnumDefault  # type: int
        self.longEnumNormalDefault = longEnumNormalDefault  # type: int
        self.nanDefault = nanDefault  # type: float
        self.infDefault = infDefault  # type: float
        self.positiveInfDefault = positiveInfDefault  # type: float
        self.infinityDefault = infinityDefault  # type: float
        self.positiveInfinityDefault = positiveInfinityDefault  # type: float
        self.negativeInfDefault = negativeInfDefault  # type: float
        self.negativeInfinityDefault = negativeInfinityDefault  # type: float
        self.doubleInfDefault = doubleInfDefault  # type: float

    @classmethod
    def InitFromBuf(cls, buf, pos):
        monster = Monster()
        monster.Init(buf, pos)
        return cls.InitFromObj(monster)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, monster):
        x = MonsterT()
        x._UnPack(monster)
        return x

    # MonsterT
    def _UnPack(self, monster):
        if monster is None:
            return
        if monster.Pos() is not None:
            self.pos = MyGame.Example.Vec3.Vec3T.InitFromObj(monster.Pos())
        self.mana = monster.Mana()
        self.hp = monster.Hp()
        self.name = monster.Name()
        if not monster.InventoryIsNone():
            if np is None:
                self.inventory = []
                for i in range(monster.InventoryLength()):
                    self.inventory.append(monster.Inventory(i))
            else:
                self.inventory = monster.InventoryAsNumpy()
        self.color = monster.Color()
        self.testType = monster.TestType()
        self.test = MyGame.Example.Any.AnyCreator(self.testType, monster.Test())
        if not monster.Test4IsNone():
            self.test4 = []
            for i in range(monster.Test4Length()):
                if monster.Test4(i) is None:
                    self.test4.append(None)
                else:
                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test4(i))
                    self.test4.append(test_)
        if not monster.TestarrayofstringIsNone():
            self.testarrayofstring = []
            for i in range(monster.TestarrayofstringLength()):
                self.testarrayofstring.append(monster.Testarrayofstring(i))
        if not monster.TestarrayoftablesIsNone():
            self.testarrayoftables = []
            for i in range(monster.TestarrayoftablesLength()):
                if monster.Testarrayoftables(i) is None:
                    self.testarrayoftables.append(None)
                else:
                    monster_ = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Testarrayoftables(i))
                    self.testarrayoftables.append(monster_)
        if monster.Enemy() is not None:
            self.enemy = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Enemy())
        if not monster.TestnestedflatbufferIsNone():
            if np is None:
                self.testnestedflatbuffer = []
                for i in range(monster.TestnestedflatbufferLength()):
                    self.testnestedflatbuffer.append(monster.Testnestedflatbuffer(i))
            else:
                self.testnestedflatbuffer = monster.TestnestedflatbufferAsNumpy()
        if monster.Testempty() is not None:
            self.testempty = MyGame.Example.Stat.StatT.InitFromObj(monster.Testempty())
        self.testbool = monster.Testbool()
        self.testhashs32Fnv1 = monster.Testhashs32Fnv1()
        self.testhashu32Fnv1 = monster.Testhashu32Fnv1()
        self.testhashs64Fnv1 = monster.Testhashs64Fnv1()
        self.testhashu64Fnv1 = monster.Testhashu64Fnv1()
        self.testhashs32Fnv1a = monster.Testhashs32Fnv1a()
        self.testhashu32Fnv1a = monster.Testhashu32Fnv1a()
        self.testhashs64Fnv1a = monster.Testhashs64Fnv1a()
        self.testhashu64Fnv1a = monster.Testhashu64Fnv1a()
        if not monster.TestarrayofboolsIsNone():
            if np is None:
                self.testarrayofbools = []
                for i in range(monster.TestarrayofboolsLength()):
                    self.testarrayofbools.append(monster.Testarrayofbools(i))
            else:
                self.testarrayofbools = monster.TestarrayofboolsAsNumpy()
        self.testf = monster.Testf()
        self.testf2 = monster.Testf2()
        self.testf3 = monster.Testf3()
        if not monster.Testarrayofstring2IsNone():
            self.testarrayofstring2 = []
            for i in range(monster.Testarrayofstring2Length()):
                self.testarrayofstring2.append(monster.Testarrayofstring2(i))
        if not monster.TestarrayofsortedstructIsNone():
            self.testarrayofsortedstruct = []
            for i in range(monster.TestarrayofsortedstructLength()):
                if monster.Testarrayofsortedstruct(i) is None:
                    self.testarrayofsortedstruct.append(None)
                else:
                    ability_ = MyGame.Example.Ability.AbilityT.InitFromObj(monster.Testarrayofsortedstruct(i))
                    self.testarrayofsortedstruct.append(ability_)
        if not monster.FlexIsNone():
            if np is None:
                self.flex = []
                for i in range(monster.FlexLength()):
                    self.flex.append(monster.Flex(i))
            else:
                self.flex = monster.FlexAsNumpy()
        if not monster.Test5IsNone():
            self.test5 = []
            for i in range(monster.Test5Length()):
                if monster.Test5(i) is None:
                    self.test5.append(None)
                else:
                    test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test5(i))
                    self.test5.append(test_)
        if not monster.VectorOfLongsIsNone():
            if np is None:
                self.vectorOfLongs = []
                for i in range(monster.VectorOfLongsLength()):
                    self.vectorOfLongs.append(monster.VectorOfLongs(i))
            else:
                self.vectorOfLongs = monster.VectorOfLongsAsNumpy()
        if not monster.VectorOfDoublesIsNone():
            if np is None:
                self.vectorOfDoubles = []
                for i in range(monster.VectorOfDoublesLength()):
                    self.vectorOfDoubles.append(monster.VectorOfDoubles(i))
            else:
                self.vectorOfDoubles = monster.VectorOfDoublesAsNumpy()
        if monster.ParentNamespaceTest() is not None:
            self.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT.InitFromObj(monster.ParentNamespaceTest())
        if not monster.VectorOfReferrablesIsNone():
            self.vectorOfReferrables = []
            for i in range(monster.VectorOfReferrablesLength()):
                if monster.VectorOfReferrables(i) is None:
                    self.vectorOfReferrables.append(None)
                else:
                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfReferrables(i))
                    self.vectorOfReferrables.append(referrable_)
        self.singleWeakReference = monster.SingleWeakReference()
        if not monster.VectorOfWeakReferencesIsNone():
            if np is None:
                self.vectorOfWeakReferences = []
                for i in range(monster.VectorOfWeakReferencesLength()):
                    self.vectorOfWeakReferences.append(monster.VectorOfWeakReferences(i))
            else:
                self.vectorOfWeakReferences = monster.VectorOfWeakReferencesAsNumpy()
        if not monster.VectorOfStrongReferrablesIsNone():
            self.vectorOfStrongReferrables = []
            for i in range(monster.VectorOfStrongReferrablesLength()):
                if monster.VectorOfStrongReferrables(i) is None:
                    self.vectorOfStrongReferrables.append(None)
                else:
                    referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfStrongReferrables(i))
                    self.vectorOfStrongReferrables.append(referrable_)
        self.coOwningReference = monster.CoOwningReference()
        if not monster.VectorOfCoOwningReferencesIsNone():
            if np is None:
                self.vectorOfCoOwningReferences = []
                for i in range(monster.VectorOfCoOwningReferencesLength()):
                    self.vectorOfCoOwningReferences.append(monster.VectorOfCoOwningReferences(i))
            else:
                self.vectorOfCoOwningReferences = monster.VectorOfCoOwningReferencesAsNumpy()
        self.nonOwningReference = monster.NonOwningReference()
        if not monster.VectorOfNonOwningReferencesIsNone():
            if np is None:
                self.vectorOfNonOwningReferences = []
                for i in range(monster.VectorOfNonOwningReferencesLength()):
                    self.vectorOfNonOwningReferences.append(monster.VectorOfNonOwningReferences(i))
            else:
                self.vectorOfNonOwningReferences = monster.VectorOfNonOwningReferencesAsNumpy()
        self.anyUniqueType = monster.AnyUniqueType()
        self.anyUnique = MyGame.Example.AnyUniqueAliases.AnyUniqueAliasesCreator(self.anyUniqueType, monster.AnyUnique())
        self.anyAmbiguousType = monster.AnyAmbiguousType()
        self.anyAmbiguous = MyGame.Example.AnyAmbiguousAliases.AnyAmbiguousAliasesCreator(self.anyAmbiguousType, monster.AnyAmbiguous())
        if not monster.VectorOfEnumsIsNone():
            if np is None:
                self.vectorOfEnums = []
                for i in range(monster.VectorOfEnumsLength()):
                    self.vectorOfEnums.append(monster.VectorOfEnums(i))
            else:
                self.vectorOfEnums = monster.VectorOfEnumsAsNumpy()
        self.signedEnum = monster.SignedEnum()
        if not monster.TestrequirednestedflatbufferIsNone():
            if np is None:
                self.testrequirednestedflatbuffer = []
                for i in range(monster.TestrequirednestedflatbufferLength()):
                    self.testrequirednestedflatbuffer.append(monster.Testrequirednestedflatbuffer(i))
            else:
                self.testrequirednestedflatbuffer = monster.TestrequirednestedflatbufferAsNumpy()
        if not monster.ScalarKeySortedTablesIsNone():
            self.scalarKeySortedTables = []
            for i in range(monster.ScalarKeySortedTablesLength()):
                if monster.ScalarKeySortedTables(i) is None:
                    self.scalarKeySortedTables.append(None)
                else:
                    stat_ = MyGame.Example.Stat.StatT.InitFromObj(monster.ScalarKeySortedTables(i))
                    self.scalarKeySortedTables.append(stat_)
        if monster.NativeInline() is not None:
            self.nativeInline = MyGame.Example.Test.TestT.InitFromObj(monster.NativeInline())
        self.longEnumNonEnumDefault = monster.LongEnumNonEnumDefault()
        self.longEnumNormalDefault = monster.LongEnumNormalDefault()
        self.nanDefault = monster.NanDefault()
        self.infDefault = monster.InfDefault()
        self.positiveInfDefault = monster.PositiveInfDefault()
        self.infinityDefault = monster.InfinityDefault()
        self.positiveInfinityDefault = monster.PositiveInfinityDefault()
        self.negativeInfDefault = monster.NegativeInfDefault()
        self.negativeInfinityDefault = monster.NegativeInfinityDefault()
        self.doubleInfDefault = monster.DoubleInfDefault()

    # MonsterT
    def Pack(self, builder):
        if self.name is not None:
            name = builder.CreateString(self.name)
        if self.inventory is not None:
            if np is not None and type(self.inventory) is np.ndarray:
                inventory = builder.CreateNumpyVector(self.inventory)
            else:
                MonsterStartInventoryVector(builder, len(self.inventory))
                for i in reversed(range(len(self.inventory))):
                    builder.PrependUint8(self.inventory[i])
                inventory = builder.EndVector()
        if self.test is not None:
            test = self.test.Pack(builder)
        if self.test4 is not None:
            MonsterStartTest4Vector(builder, len(self.test4))
            for i in reversed(range(len(self.test4))):
                self.test4[i].Pack(builder)
            test4 = builder.EndVector()
        if self.testarrayofstring is not None:
            testarrayofstringlist = []
            for i in range(len(self.testarrayofstring)):
                testarrayofstringlist.append(builder.CreateString(self.testarrayofstring[i]))
            MonsterStartTestarrayofstringVector(builder, len(self.testarrayofstring))
            for i in reversed(range(len(self.testarrayofstring))):
                builder.PrependUOffsetTRelative(testarrayofstringlist[i])
            testarrayofstring = builder.EndVector()
        if self.testarrayoftables is not None:
            testarrayoftableslist = []
            for i in range(len(self.testarrayoftables)):
                testarrayoftableslist.append(self.testarrayoftables[i].Pack(builder))
            MonsterStartTestarrayoftablesVector(builder, len(self.testarrayoftables))
            for i in reversed(range(len(self.testarrayoftables))):
                builder.PrependUOffsetTRelative(testarrayoftableslist[i])
            testarrayoftables = builder.EndVector()
        if self.enemy is not None:
            enemy = self.enemy.Pack(builder)
        if self.testnestedflatbuffer is not None:
            if np is not None and type(self.testnestedflatbuffer) is np.ndarray:
                testnestedflatbuffer = builder.CreateNumpyVector(self.testnestedflatbuffer)
            else:
                MonsterStartTestnestedflatbufferVector(builder, len(self.testnestedflatbuffer))
                for i in reversed(range(len(self.testnestedflatbuffer))):
                    builder.PrependUint8(self.testnestedflatbuffer[i])
                testnestedflatbuffer = builder.EndVector()
        if self.testempty is not None:
            testempty = self.testempty.Pack(builder)
        if self.testarrayofbools is not None:
            if np is not None and type(self.testarrayofbools) is np.ndarray:
                testarrayofbools = builder.CreateNumpyVector(self.testarrayofbools)
            else:
                MonsterStartTestarrayofboolsVector(builder, len(self.testarrayofbools))
                for i in reversed(range(len(self.testarrayofbools))):
                    builder.PrependBool(self.testarrayofbools[i])
                testarrayofbools = builder.EndVector()
        if self.testarrayofstring2 is not None:
            testarrayofstring2list = []
            for i in range(len(self.testarrayofstring2)):
                testarrayofstring2list.append(builder.CreateString(self.testarrayofstring2[i]))
            MonsterStartTestarrayofstring2Vector(builder, len(self.testarrayofstring2))
            for i in reversed(range(len(self.testarrayofstring2))):
                builder.PrependUOffsetTRelative(testarrayofstring2list[i])
            testarrayofstring2 = builder.EndVector()
        if self.testarrayofsortedstruct is not None:
            MonsterStartTestarrayofsortedstructVector(builder, len(self.testarrayofsortedstruct))
            for i in reversed(range(len(self.testarrayofsortedstruct))):
                self.testarrayofsortedstruct[i].Pack(builder)
            testarrayofsortedstruct = builder.EndVector()
        if self.flex is not None:
            if np is not None and type(self.flex) is np.ndarray:
                flex = builder.CreateNumpyVector(self.flex)
            else:
                MonsterStartFlexVector(builder, len(self.flex))
                for i in reversed(range(len(self.flex))):
                    builder.PrependUint8(self.flex[i])
                flex = builder.EndVector()
        if self.test5 is not None:
            MonsterStartTest5Vector(builder, len(self.test5))
            for i in reversed(range(len(self.test5))):
                self.test5[i].Pack(builder)
            test5 = builder.EndVector()
        if self.vectorOfLongs is not None:
            if np is not None and type(self.vectorOfLongs) is np.ndarray:
                vectorOfLongs = builder.CreateNumpyVector(self.vectorOfLongs)
            else:
                MonsterStartVectorOfLongsVector(builder, len(self.vectorOfLongs))
                for i in reversed(range(len(self.vectorOfLongs))):
                    builder.PrependInt64(self.vectorOfLongs[i])
                vectorOfLongs = builder.EndVector()
        if self.vectorOfDoubles is not None:
            if np is not None and type(self.vectorOfDoubles) is np.ndarray:
                vectorOfDoubles = builder.CreateNumpyVector(self.vectorOfDoubles)
            else:
                MonsterStartVectorOfDoublesVector(builder, len(self.vectorOfDoubles))
                for i in reversed(range(len(self.vectorOfDoubles))):
                    builder.PrependFloat64(self.vectorOfDoubles[i])
                vectorOfDoubles = builder.EndVector()
        if self.parentNamespaceTest is not None:
            parentNamespaceTest = self.parentNamespaceTest.Pack(builder)
        if self.vectorOfReferrables is not None:
            vectorOfReferrableslist = []
            for i in range(len(self.vectorOfReferrables)):
                vectorOfReferrableslist.append(self.vectorOfReferrables[i].Pack(builder))
            MonsterStartVectorOfReferrablesVector(builder, len(self.vectorOfReferrables))
            for i in reversed(range(len(self.vectorOfReferrables))):
                builder.PrependUOffsetTRelative(vectorOfReferrableslist[i])
            vectorOfReferrables = builder.EndVector()
        if self.vectorOfWeakReferences is not None:
            if np is not None and type(self.vectorOfWeakReferences) is np.ndarray:
                vectorOfWeakReferences = builder.CreateNumpyVector(self.vectorOfWeakReferences)
            else:
                MonsterStartVectorOfWeakReferencesVector(builder, len(self.vectorOfWeakReferences))
                for i in reversed(range(len(self.vectorOfWeakReferences))):
                    builder.PrependUint64(self.vectorOfWeakReferences[i])
                vectorOfWeakReferences = builder.EndVector()
        if self.vectorOfStrongReferrables is not None:
            vectorOfStrongReferrableslist = []
            for i in range(len(self.vectorOfStrongReferrables)):
                vectorOfStrongReferrableslist.append(self.vectorOfStrongReferrables[i].Pack(builder))
            MonsterStartVectorOfStrongReferrablesVector(builder, len(self.vectorOfStrongReferrables))
            for i in reversed(range(len(self.vectorOfStrongReferrables))):
                builder.PrependUOffsetTRelative(vectorOfStrongReferrableslist[i])
            vectorOfStrongReferrables = builder.EndVector()
        if self.vectorOfCoOwningReferences is not None:
            if np is not None and type(self.vectorOfCoOwningReferences) is np.ndarray:
                vectorOfCoOwningReferences = builder.CreateNumpyVector(self.vectorOfCoOwningReferences)
            else:
                MonsterStartVectorOfCoOwningReferencesVector(builder, len(self.vectorOfCoOwningReferences))
                for i in reversed(range(len(self.vectorOfCoOwningReferences))):
                    builder.PrependUint64(self.vectorOfCoOwningReferences[i])
                vectorOfCoOwningReferences = builder.EndVector()
        if self.vectorOfNonOwningReferences is not None:
            if np is not None and type(self.vectorOfNonOwningReferences) is np.ndarray:
                vectorOfNonOwningReferences = builder.CreateNumpyVector(self.vectorOfNonOwningReferences)
            else:
                MonsterStartVectorOfNonOwningReferencesVector(builder, len(self.vectorOfNonOwningReferences))
                for i in reversed(range(len(self.vectorOfNonOwningReferences))):
                    builder.PrependUint64(self.vectorOfNonOwningReferences[i])
                vectorOfNonOwningReferences = builder.EndVector()
        if self.anyUnique is not None:
            anyUnique = self.anyUnique.Pack(builder)
        if self.anyAmbiguous is not None:
            anyAmbiguous = self.anyAmbiguous.Pack(builder)
        if self.vectorOfEnums is not None:
            if np is not None and type(self.vectorOfEnums) is np.ndarray:
                vectorOfEnums = builder.CreateNumpyVector(self.vectorOfEnums)
            else:
                MonsterStartVectorOfEnumsVector(builder, len(self.vectorOfEnums))
                for i in reversed(range(len(self.vectorOfEnums))):
                    builder.PrependUint8(self.vectorOfEnums[i])
                vectorOfEnums = builder.EndVector()
        if self.testrequirednestedflatbuffer is not None:
            if np is not None and type(self.testrequirednestedflatbuffer) is np.ndarray:
                testrequirednestedflatbuffer = builder.CreateNumpyVector(self.testrequirednestedflatbuffer)
            else:
                MonsterStartTestrequirednestedflatbufferVector(builder, len(self.testrequirednestedflatbuffer))
                for i in reversed(range(len(self.testrequirednestedflatbuffer))):
                    builder.PrependUint8(self.testrequirednestedflatbuffer[i])
                testrequirednestedflatbuffer = builder.EndVector()
        if self.scalarKeySortedTables is not None:
            scalarKeySortedTableslist = []
            for i in range(len(self.scalarKeySortedTables)):
                scalarKeySortedTableslist.append(self.scalarKeySortedTables[i].Pack(builder))
            MonsterStartScalarKeySortedTablesVector(builder, len(self.scalarKeySortedTables))
            for i in reversed(range(len(self.scalarKeySortedTables))):
                builder.PrependUOffsetTRelative(scalarKeySortedTableslist[i])
            scalarKeySortedTables = builder.EndVector()
        MonsterStart(builder)
        if self.pos is not None:
            pos = self.pos.Pack(builder)
            MonsterAddPos(builder, pos)
        MonsterAddMana(builder, self.mana)
        MonsterAddHp(builder, self.hp)
        if self.name is not None:
            MonsterAddName(builder, name)
        if self.inventory is not None:
            MonsterAddInventory(builder, inventory)
        MonsterAddColor(builder, self.color)
        MonsterAddTestType(builder, self.testType)
        if self.test is not None:
            MonsterAddTest(builder, test)
        if self.test4 is not None:
            MonsterAddTest4(builder, test4)
        if self.testarrayofstring is not None:
            MonsterAddTestarrayofstring(builder, testarrayofstring)
        if self.testarrayoftables is not None:
            MonsterAddTestarrayoftables(builder, testarrayoftables)
        if self.enemy is not None:
            MonsterAddEnemy(builder, enemy)
        if self.testnestedflatbuffer is not None:
            MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)
        if self.testempty is not None:
            MonsterAddTestempty(builder, testempty)
        MonsterAddTestbool(builder, self.testbool)
        MonsterAddTesthashs32Fnv1(builder, self.testhashs32Fnv1)
        MonsterAddTesthashu32Fnv1(builder, self.testhashu32Fnv1)
        MonsterAddTesthashs64Fnv1(builder, self.testhashs64Fnv1)
        MonsterAddTesthashu64Fnv1(builder, self.testhashu64Fnv1)
        MonsterAddTesthashs32Fnv1a(builder, self.testhashs32Fnv1a)
        MonsterAddTesthashu32Fnv1a(builder, self.testhashu32Fnv1a)
        MonsterAddTesthashs64Fnv1a(builder, self.testhashs64Fnv1a)
        MonsterAddTesthashu64Fnv1a(builder, self.testhashu64Fnv1a)
        if self.testarrayofbools is not None:
            MonsterAddTestarrayofbools(builder, testarrayofbools)
        MonsterAddTestf(builder, self.testf)
        MonsterAddTestf2(builder, self.testf2)
        MonsterAddTestf3(builder, self.testf3)
        if self.testarrayofstring2 is not None:
            MonsterAddTestarrayofstring2(builder, testarrayofstring2)
        if self.testarrayofsortedstruct is not None:
            MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)
        if self.flex is not None:
            MonsterAddFlex(builder, flex)
        if self.test5 is not None:
            MonsterAddTest5(builder, test5)
        if self.vectorOfLongs is not None:
            MonsterAddVectorOfLongs(builder, vectorOfLongs)
        if self.vectorOfDoubles is not None:
            MonsterAddVectorOfDoubles(builder, vectorOfDoubles)
        if self.parentNamespaceTest is not None:
            MonsterAddParentNamespaceTest(builder, parentNamespaceTest)
        if self.vectorOfReferrables is not None:
            MonsterAddVectorOfReferrables(builder, vectorOfReferrables)
        MonsterAddSingleWeakReference(builder, self.singleWeakReference)
        if self.vectorOfWeakReferences is not None:
            MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)
        if self.vectorOfStrongReferrables is not None:
            MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)
        MonsterAddCoOwningReference(builder, self.coOwningReference)
        if self.vectorOfCoOwningReferences is not None:
            MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)
        MonsterAddNonOwningReference(builder, self.nonOwningReference)
        if self.vectorOfNonOwningReferences is not None:
            MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)
        MonsterAddAnyUniqueType(builder, self.anyUniqueType)
        if self.anyUnique is not None:
            MonsterAddAnyUnique(builder, anyUnique)
        MonsterAddAnyAmbiguousType(builder, self.anyAmbiguousType)
        if self.anyAmbiguous is not None:
            MonsterAddAnyAmbiguous(builder, anyAmbiguous)
        if self.vectorOfEnums is not None:
            MonsterAddVectorOfEnums(builder, vectorOfEnums)
        MonsterAddSignedEnum(builder, self.signedEnum)
        if self.testrequirednestedflatbuffer is not None:
            MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer)
        if self.scalarKeySortedTables is not None:
            MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables)
        if self.nativeInline is not None:
            nativeInline = self.nativeInline.Pack(builder)
            MonsterAddNativeInline(builder, nativeInline)
        MonsterAddLongEnumNonEnumDefault(builder, self.longEnumNonEnumDefault)
        MonsterAddLongEnumNormalDefault(builder, self.longEnumNormalDefault)
        MonsterAddNanDefault(builder, self.nanDefault)
        MonsterAddInfDefault(builder, self.infDefault)
        MonsterAddPositiveInfDefault(builder, self.positiveInfDefault)
        MonsterAddInfinityDefault(builder, self.infinityDefault)
        MonsterAddPositiveInfinityDefault(builder, self.positiveInfinityDefault)
        MonsterAddNegativeInfDefault(builder, self.negativeInfDefault)
        MonsterAddNegativeInfinityDefault(builder, self.negativeInfinityDefault)
        MonsterAddDoubleInfDefault(builder, self.doubleInfDefault)
        monster = MonsterEnd(builder)
        return monster
