// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace MyGame
{

using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;

public struct MonsterExtra : IFlatbufferObject
{
  private Table __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_1_4(); }
  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
  public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
  public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }
  public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
  public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public double D0 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
  public bool MutateD0(double d0) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d0); return true; } else { return false; } }
  public double D1 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
  public bool MutateD1(double d1) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d1); return true; } else { return false; } }
  public double D2 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
  public bool MutateD2(double d2) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d2); return true; } else { return false; } }
  public double D3 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
  public bool MutateD3(double d3) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d3); return true; } else { return false; } }
  public float F0 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
  public bool MutateF0(float f0) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f0); return true; } else { return false; } }
  public float F1 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
  public bool MutateF1(float f1) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f1); return true; } else { return false; } }
  public float F2 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
  public bool MutateF2(float f2) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f2); return true; } else { return false; } }
  public float F3 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
  public bool MutateF3(float f3) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f3); return true; } else { return false; } }
  public double Dvec(int j) { int o = __p.__offset(20); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
  public int DvecLength { get { int o = __p.__offset(20); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<double> GetDvecBytes() { return __p.__vector_as_span<double>(20, 8); }
#else
  public ArraySegment<byte>? GetDvecBytes() { return __p.__vector_as_arraysegment(20); }
#endif
  public double[] GetDvecArray() { return __p.__vector_as_array<double>(20); }
  public bool MutateDvec(int j, double dvec) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, dvec); return true; } else { return false; } }
  public float Fvec(int j) { int o = __p.__offset(22); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; }
  public int FvecLength { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
  public Span<float> GetFvecBytes() { return __p.__vector_as_span<float>(22, 4); }
#else
  public ArraySegment<byte>? GetFvecBytes() { return __p.__vector_as_arraysegment(22); }
#endif
  public float[] GetFvecArray() { return __p.__vector_as_array<float>(22); }
  public bool MutateFvec(int j, float fvec) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, fvec); return true; } else { return false; } }

  public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
      double d0 = Double.NaN,
      double d1 = Double.NaN,
      double d2 = Double.PositiveInfinity,
      double d3 = Double.NegativeInfinity,
      float f0 = Single.NaN,
      float f1 = Single.NaN,
      float f2 = Single.PositiveInfinity,
      float f3 = Single.NegativeInfinity,
      VectorOffset dvecOffset = default(VectorOffset),
      VectorOffset fvecOffset = default(VectorOffset)) {
    builder.StartTable(11);
    MonsterExtra.AddD3(builder, d3);
    MonsterExtra.AddD2(builder, d2);
    MonsterExtra.AddD1(builder, d1);
    MonsterExtra.AddD0(builder, d0);
    MonsterExtra.AddFvec(builder, fvecOffset);
    MonsterExtra.AddDvec(builder, dvecOffset);
    MonsterExtra.AddF3(builder, f3);
    MonsterExtra.AddF2(builder, f2);
    MonsterExtra.AddF1(builder, f1);
    MonsterExtra.AddF0(builder, f0);
    return MonsterExtra.EndMonsterExtra(builder);
  }

  public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(11); }
  public static void AddD0(FlatBufferBuilder builder, double d0) { builder.AddDouble(0, d0, Double.NaN); }
  public static void AddD1(FlatBufferBuilder builder, double d1) { builder.AddDouble(1, d1, Double.NaN); }
  public static void AddD2(FlatBufferBuilder builder, double d2) { builder.AddDouble(2, d2, Double.PositiveInfinity); }
  public static void AddD3(FlatBufferBuilder builder, double d3) { builder.AddDouble(3, d3, Double.NegativeInfinity); }
  public static void AddF0(FlatBufferBuilder builder, float f0) { builder.AddFloat(4, f0, Single.NaN); }
  public static void AddF1(FlatBufferBuilder builder, float f1) { builder.AddFloat(5, f1, Single.NaN); }
  public static void AddF2(FlatBufferBuilder builder, float f2) { builder.AddFloat(6, f2, Single.PositiveInfinity); }
  public static void AddF3(FlatBufferBuilder builder, float f3) { builder.AddFloat(7, f3, Single.NegativeInfinity); }
  public static void AddDvec(FlatBufferBuilder builder, VectorOffset dvecOffset) { builder.AddOffset(8, dvecOffset.Value, 0); }
  public static VectorOffset CreateDvecVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, ArraySegment<double> data) { builder.StartVector(8, data.Count, 8); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<double>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartDvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
  public static void AddFvec(FlatBufferBuilder builder, VectorOffset fvecOffset) { builder.AddOffset(9, fvecOffset.Value, 0); }
  public static VectorOffset CreateFvecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); }
  public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, ArraySegment<float> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
  public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<float>(dataPtr, sizeInBytes); return builder.EndVector(); }
  public static void StartFvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
  public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
    int o = builder.EndTable();
    return new Offset<MyGame.MonsterExtra>(o);
  }
  public static void FinishMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.Finish(offset.Value, "MONE"); }
  public static void FinishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.FinishSizePrefixed(offset.Value, "MONE"); }
  public MonsterExtraT UnPack() {
    var _o = new MonsterExtraT();
    this.UnPackTo(_o);
    return _o;
  }
  public void UnPackTo(MonsterExtraT _o) {
    _o.D0 = this.D0;
    _o.D1 = this.D1;
    _o.D2 = this.D2;
    _o.D3 = this.D3;
    _o.F0 = this.F0;
    _o.F1 = this.F1;
    _o.F2 = this.F2;
    _o.F3 = this.F3;
    _o.Dvec = new List<double>();
    for (var _j = 0; _j < this.DvecLength; ++_j) {_o.Dvec.Add(this.Dvec(_j));}
    _o.Fvec = new List<float>();
    for (var _j = 0; _j < this.FvecLength; ++_j) {_o.Fvec.Add(this.Fvec(_j));}
  }
  public static Offset<MyGame.MonsterExtra> Pack(FlatBufferBuilder builder, MonsterExtraT _o) {
    if (_o == null) return default(Offset<MyGame.MonsterExtra>);
    var _dvec = default(VectorOffset);
    if (_o.Dvec != null) {
      var __dvec = _o.Dvec.ToArray();
      _dvec = CreateDvecVector(builder, __dvec);
    }
    var _fvec = default(VectorOffset);
    if (_o.Fvec != null) {
      var __fvec = _o.Fvec.ToArray();
      _fvec = CreateFvecVector(builder, __fvec);
    }
    return CreateMonsterExtra(
      builder,
      _o.D0,
      _o.D1,
      _o.D2,
      _o.D3,
      _o.F0,
      _o.F1,
      _o.F2,
      _o.F3,
      _dvec,
      _fvec);
  }
}

public class MonsterExtraT
{
  [Newtonsoft.Json.JsonProperty("d0")]
  public double D0 { get; set; }
  [Newtonsoft.Json.JsonProperty("d1")]
  public double D1 { get; set; }
  [Newtonsoft.Json.JsonProperty("d2")]
  public double D2 { get; set; }
  [Newtonsoft.Json.JsonProperty("d3")]
  public double D3 { get; set; }
  [Newtonsoft.Json.JsonProperty("f0")]
  public float F0 { get; set; }
  [Newtonsoft.Json.JsonProperty("f1")]
  public float F1 { get; set; }
  [Newtonsoft.Json.JsonProperty("f2")]
  public float F2 { get; set; }
  [Newtonsoft.Json.JsonProperty("f3")]
  public float F3 { get; set; }
  [Newtonsoft.Json.JsonProperty("dvec")]
  public List<double> Dvec { get; set; }
  [Newtonsoft.Json.JsonProperty("fvec")]
  public List<float> Fvec { get; set; }

  public MonsterExtraT() {
    this.D0 = Double.NaN;
    this.D1 = Double.NaN;
    this.D2 = Double.PositiveInfinity;
    this.D3 = Double.NegativeInfinity;
    this.F0 = Single.NaN;
    this.F1 = Single.NaN;
    this.F2 = Single.PositiveInfinity;
    this.F3 = Single.NegativeInfinity;
    this.Dvec = null;
    this.Fvec = null;
  }

  public static MonsterExtraT DeserializeFromJson(string jsonText) {
    return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterExtraT>(jsonText);
  }
  public string SerializeToJson() {
    return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
  }
  public static MonsterExtraT DeserializeFromBinary(byte[] fbBuffer) {
    return MonsterExtra.GetRootAsMonsterExtra(new ByteBuffer(fbBuffer)).UnPack();
  }
  public byte[] SerializeToBinary() {
    var fbb = new FlatBufferBuilder(0x10000);
    MonsterExtra.FinishMonsterExtraBuffer(fbb, MonsterExtra.Pack(fbb, this));
    return fbb.DataBuffer.ToSizedArray();
  }
}


}
