// automatically generated by the FlatBuffers compiler, do not modify

package MyGame.Example;

import com.google.flatbuffers.BaseVector;
import com.google.flatbuffers.BooleanVector;
import com.google.flatbuffers.ByteVector;
import com.google.flatbuffers.Constants;
import com.google.flatbuffers.DoubleVector;
import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.FloatVector;
import com.google.flatbuffers.IntVector;
import com.google.flatbuffers.LongVector;
import com.google.flatbuffers.ShortVector;
import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.Struct;
import com.google.flatbuffers.UnionVector;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@SuppressWarnings("unused")
public final class Ability extends Struct {
  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
  public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public long id() { return (long)bb.getInt(bb_pos + 0) & 0xFFFFFFFFL; }
  public void mutateId(long id) { bb.putInt(bb_pos + 0, (int) id); }
  public long distance() { return (long)bb.getInt(bb_pos + 4) & 0xFFFFFFFFL; }
  public void mutateDistance(long distance) { bb.putInt(bb_pos + 4, (int) distance); }

  public static int createAbility(FlatBufferBuilder builder, long id, long distance) {
    builder.prep(4, 8);
    builder.putInt((int) distance);
    builder.putInt((int) id);
    return builder.offset();
  }

  public static final class Vector extends BaseVector {
    public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }

    public Ability get(int j) { return get(new Ability(), j); }
    public Ability get(Ability obj, int j) {  return obj.__assign(__element(j), bb); }
  }
  public AbilityT unpack() {
    AbilityT _o = new AbilityT();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(AbilityT _o) {
    long _oId = id();
    _o.setId(_oId);
    long _oDistance = distance();
    _o.setDistance(_oDistance);
  }
  public static int pack(FlatBufferBuilder builder, AbilityT _o) {
    if (_o == null) return 0;
    return createAbility(
      builder,
      _o.getId(),
      _o.getDistance());
  }
}

