# automatically generated by the FlatBuffers compiler, do not modify

# namespace: MyGame

import flatbuffers
from flatbuffers.compat import import_numpy
from typing import Any
from typing import Iterable
np = import_numpy()

class MonsterExtra(object):
    __slots__ = ['_tab']

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

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

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

    # MonsterExtra
    def D0(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('nan')

    # MonsterExtra
    def D1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('nan')

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

    # MonsterExtra
    def D3(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('-inf')

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

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

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

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

    # MonsterExtra
    def Dvec(self, j: int):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        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

    # MonsterExtra
    def DvecAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
        return 0

    # MonsterExtra
    def DvecLength(self) -> int:
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # MonsterExtra
    def DvecIsNone(self) -> bool:
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        return o == 0

    # MonsterExtra
    def Fvec(self, j: int):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return 0

    # MonsterExtra
    def FvecAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
        return 0

    # MonsterExtra
    def FvecLength(self) -> int:
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # MonsterExtra
    def FvecIsNone(self) -> bool:
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        return o == 0

def MonsterExtraStart(builder: flatbuffers.Builder):
    builder.StartObject(11)

def Start(builder: flatbuffers.Builder):
    MonsterExtraStart(builder)

def MonsterExtraAddD0(builder: flatbuffers.Builder, d0: float):
    builder.PrependFloat64Slot(0, d0, float('nan'))

def AddD0(builder: flatbuffers.Builder, d0: float):
    MonsterExtraAddD0(builder, d0)

def MonsterExtraAddD1(builder: flatbuffers.Builder, d1: float):
    builder.PrependFloat64Slot(1, d1, float('nan'))

def AddD1(builder: flatbuffers.Builder, d1: float):
    MonsterExtraAddD1(builder, d1)

def MonsterExtraAddD2(builder: flatbuffers.Builder, d2: float):
    builder.PrependFloat64Slot(2, d2, float('inf'))

def AddD2(builder: flatbuffers.Builder, d2: float):
    MonsterExtraAddD2(builder, d2)

def MonsterExtraAddD3(builder: flatbuffers.Builder, d3: float):
    builder.PrependFloat64Slot(3, d3, float('-inf'))

def AddD3(builder: flatbuffers.Builder, d3: float):
    MonsterExtraAddD3(builder, d3)

def MonsterExtraAddF0(builder: flatbuffers.Builder, f0: float):
    builder.PrependFloat32Slot(4, f0, float('nan'))

def AddF0(builder: flatbuffers.Builder, f0: float):
    MonsterExtraAddF0(builder, f0)

def MonsterExtraAddF1(builder: flatbuffers.Builder, f1: float):
    builder.PrependFloat32Slot(5, f1, float('nan'))

def AddF1(builder: flatbuffers.Builder, f1: float):
    MonsterExtraAddF1(builder, f1)

def MonsterExtraAddF2(builder: flatbuffers.Builder, f2: float):
    builder.PrependFloat32Slot(6, f2, float('inf'))

def AddF2(builder: flatbuffers.Builder, f2: float):
    MonsterExtraAddF2(builder, f2)

def MonsterExtraAddF3(builder: flatbuffers.Builder, f3: float):
    builder.PrependFloat32Slot(7, f3, float('-inf'))

def AddF3(builder: flatbuffers.Builder, f3: float):
    MonsterExtraAddF3(builder, f3)

def MonsterExtraAddDvec(builder: flatbuffers.Builder, dvec: int):
    builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(dvec), 0)

def AddDvec(builder: flatbuffers.Builder, dvec: int):
    MonsterExtraAddDvec(builder, dvec)

def MonsterExtraStartDvecVector(builder, numElems: int) -> int:
    return builder.StartVector(8, numElems, 8)

def StartDvecVector(builder, numElems: int) -> int:
    return MonsterExtraStartDvecVector(builder, numElems)

def MonsterExtraCreateDvecVector(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependFloat64(item)
    return builder.EndVector()

def CreateDvecVector(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:
    MonsterExtraCreateDvecVector(builder, data)

def MonsterExtraAddFvec(builder: flatbuffers.Builder, fvec: int):
    builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)

def AddFvec(builder: flatbuffers.Builder, fvec: int):
    MonsterExtraAddFvec(builder, fvec)

def MonsterExtraStartFvecVector(builder, numElems: int) -> int:
    return builder.StartVector(4, numElems, 4)

def StartFvecVector(builder, numElems: int) -> int:
    return MonsterExtraStartFvecVector(builder, numElems)

def MonsterExtraCreateFvecVector(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:
    data = list(data)
    builder.StartVector(4, len(data), 4)
    for item in reversed(data):
        builder.PrependFloat32(item)
    return builder.EndVector()

def CreateFvecVector(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:
    MonsterExtraCreateFvecVector(builder, data)

def MonsterExtraEnd(builder: flatbuffers.Builder) -> int:
    return builder.EndObject()

def End(builder: flatbuffers.Builder) -> int:
    return MonsterExtraEnd(builder)

try:
    from typing import List
except:
    pass

class MonsterExtraT(object):

    # MonsterExtraT
    def __init__(
        self,
        d0 = float('nan'),
        d1 = float('nan'),
        d2 = float('inf'),
        d3 = float('-inf'),
        f0 = float('nan'),
        f1 = float('nan'),
        f2 = float('inf'),
        f3 = float('-inf'),
        dvec = None,
        fvec = None,
    ):
        self.d0 = d0  # type: float
        self.d1 = d1  # type: float
        self.d2 = d2  # type: float
        self.d3 = d3  # type: float
        self.f0 = f0  # type: float
        self.f1 = f1  # type: float
        self.f2 = f2  # type: float
        self.f3 = f3  # type: float
        self.dvec = dvec  # type: Optional[List[float]]
        self.fvec = fvec  # type: Optional[List[float]]

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

    @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, monsterExtra):
        x = MonsterExtraT()
        x._UnPack(monsterExtra)
        return x

    def __eq__(self, other):
        return type(self) == type(other) and \
            self.d0 == other.d0 and \
            self.d1 == other.d1 and \
            self.d2 == other.d2 and \
            self.d3 == other.d3 and \
            self.f0 == other.f0 and \
            self.f1 == other.f1 and \
            self.f2 == other.f2 and \
            self.f3 == other.f3 and \
            np.array_equal(self.dvec, other.dvec) and \
            np.array_equal(self.fvec, other.fvec)

    # MonsterExtraT
    def _UnPack(self, monsterExtra):
        if monsterExtra is None:
            return
        self.d0 = monsterExtra.D0()
        self.d1 = monsterExtra.D1()
        self.d2 = monsterExtra.D2()
        self.d3 = monsterExtra.D3()
        self.f0 = monsterExtra.F0()
        self.f1 = monsterExtra.F1()
        self.f2 = monsterExtra.F2()
        self.f3 = monsterExtra.F3()
        if not monsterExtra.DvecIsNone():
            if np is None:
                self.dvec = []
                for i in range(monsterExtra.DvecLength()):
                    self.dvec.append(monsterExtra.Dvec(i))
            else:
                self.dvec = monsterExtra.DvecAsNumpy()
        if not monsterExtra.FvecIsNone():
            if np is None:
                self.fvec = []
                for i in range(monsterExtra.FvecLength()):
                    self.fvec.append(monsterExtra.Fvec(i))
            else:
                self.fvec = monsterExtra.FvecAsNumpy()

    # MonsterExtraT
    def Pack(self, builder):
        if self.dvec is not None:
            if np is not None and type(self.dvec) is np.ndarray:
                dvec = builder.CreateNumpyVector(self.dvec)
            else:
                MonsterExtraStartDvecVector(builder, len(self.dvec))
                for i in reversed(range(len(self.dvec))):
                    builder.PrependFloat64(self.dvec[i])
                dvec = builder.EndVector()
        if self.fvec is not None:
            if np is not None and type(self.fvec) is np.ndarray:
                fvec = builder.CreateNumpyVector(self.fvec)
            else:
                MonsterExtraStartFvecVector(builder, len(self.fvec))
                for i in reversed(range(len(self.fvec))):
                    builder.PrependFloat32(self.fvec[i])
                fvec = builder.EndVector()
        MonsterExtraStart(builder)
        MonsterExtraAddD0(builder, self.d0)
        MonsterExtraAddD1(builder, self.d1)
        MonsterExtraAddD2(builder, self.d2)
        MonsterExtraAddD3(builder, self.d3)
        MonsterExtraAddF0(builder, self.f0)
        MonsterExtraAddF1(builder, self.f1)
        MonsterExtraAddF2(builder, self.f2)
        MonsterExtraAddF3(builder, self.f3)
        if self.dvec is not None:
            MonsterExtraAddDvec(builder, dvec)
        if self.fvec is not None:
            MonsterExtraAddFvec(builder, fvec)
        monsterExtra = MonsterExtraEnd(builder)
        return monsterExtra
