//public override void IkClear(Maid tgt, List<string> listHand, XtMasterSlave.MsLinkConfig mscfg, AIKCtrl.IKAttachType IkType = (AIKCtrl.IKAttachType)(-1))
        public override void IkClear(Maid tgt, List <string> listHand, XtMasterSlave.MsLinkConfig mscfg, int IkType = (-1))
        {
            List <AIKCtrl.IKAttachType> listTypes = new List <AIKCtrl.IKAttachType>
            {
                AIKCtrl.IKAttachType.NewPoint, AIKCtrl.IKAttachType.Rotate
            };

            listHand.ToList().ForEach(h =>
            {
                var ctrl = tgt.body0.fullBodyIK.GetIKCtrl(h);
                listTypes.ForEach(t =>
                {
                    var iks = ctrl.GetIKSettingData(t);

                    if (IkXT.IsIkCtrlO117)
                    {
                        IKAttachParam ikAttachParam = new IKAttachParam(null, tgt);
                        ikAttachParam.attachType    = t;
                        ikAttachParam.execTiming    = AIKCtrl.IKExecTiming.Normal;
                        ikAttachParam.offset        = Vector3.zero;


                        ctrl.SetIKSetting(ikAttachParam);
                        //ctrl.SetIKSetting(t, AIKCtrl.IKExecTiming.Normal, null, string.Empty, null, Vector3.zero);
                        ctrl.Detach();
                        //ctrl.SetIKSetting(t, false, null, -1, string.Empty, null, null, Vector3.zero, false, 0f);
                        //iks.SetIKSetting(null, -1, string.Empty, null, null, Vector3.zero, false, 0f);
                        //ctrl.Detach(t, 0f);
                    }
                    else
                    {
                        //iks.TgtMaid = null;
                        //iks.Tgt_AttachSlot = -1;
                        //iks.Tgt_AttachName = string.Empty;
                        //iks.Target = null;
                        //iks.AxisTgt = null;
                        //iks.TgtOffset = Vector3.zero;
                        //iks.IsTgtAxis
                    }

                    if (iks.attachType != AIKCtrl.IKAttachType.Rotate)
                    {
                        if (IkType >= 0 && IkType != (int)AIKCtrl.IKAttachType.Rotate &&
                            Enum.IsDefined(typeof(AIKCtrl.IKAttachType), IkType))
                        {
                            iks.attachType = ((AIKCtrl.IKAttachType)IkType);
                        }
                        else
                        {
                            if (mscfg != null)
                            {
                                iks.attachType = (GetDefType(mscfg));/*fix v5.0
                                                                      * else
                                                                      * iks.ChangePointType(AIKCtrl.IKAttachType.NewPoint);*/
                            }
                        }
                    }
                });
            });
        }
        public override void SetHandIKRotate(string handName, Maid master, Maid slave, string boneTgtname, Vector3 v3HandLOffsetRot)
        {
            IKAttachParam ikAttachParam = new IKAttachParam(master, null);

            ikAttachParam.targetBoneName = boneTgtname;
            ikAttachParam.offset         = v3HandLOffsetRot;
            ikAttachParam.attachType     = AIKCtrl.IKAttachType.Rotate;
            ikAttachParam.doAnimation    = boAnime;
            ikAttachParam.execTiming     = AIKCtrl.IKExecTiming.Normal;

            slave.body0.fullBodyIK.IKAttach(handName, ikAttachParam);

            // befor

            /*
             * slave.IKTargetToBone(
             *    handName
             *  , master
             *  , boneTgtname
             *  , v3HandLOffsetRot
             *  , AIKCtrl.IKAttachType.Rotate
             *  , false
             *  , boAnime
             *  , AIKCtrl.IKExecTiming.Normal);
             */
            /**/
            //slave.IKTargetToBone(handName, master, boneTgtname, v3HandLOffsetRot, AIKCtrl.IKAttachType.Rotate, false, 0f, boAnime, false);
        }

        public override void SetHandIKTarget(XtMasterSlave.MsLinkConfig mscfg, string handName, Maid master, Maid slave, int slot_no, string attach_name, Transform target, Vector3 v3HandLOffset)
        {
            /*if (needInit)
             * {
             *  needInit = false;
             *  if (mscfg.doIK159NewPointToDef)
             *      IKInit(slave, mscfg);
             #if DEBUG
             *  else
             *      IKInit4OldPoint(slave);
             #endif
             * }*/
            IKAttachParam ikAttachParam = new IKAttachParam(slave, master);

            ikAttachParam.attachType   = GetDefType(mscfg);
            ikAttachParam.execTiming   = AIKCtrl.IKExecTiming.Normal;
            ikAttachParam.attachIKName = attach_name;
            ikAttachParam.attachTarget = target;
            ikAttachParam.offset       = v3HandLOffset;
            ikAttachParam.doAnimation  = boAnime;

            slave.fullBodyIK.GetIKCtrl(handName).SetIKSetting(ikAttachParam);
            //slave.fullBodyIK.GetIKCtrl(handName).SetIKSetting(GetDefType(mscfg), AIKCtrl.IKExecTiming.Normal, master, slot_no, attach_name, null, target, v3HandLOffset, boAnime);

            HandFootIKCtrl ikdata = slave.fullBodyIK.GetIKCtrl <HandFootIKCtrl>(handName);

            ikdata.correctType = HandFootIKCtrl.BorderCorrectType.Bone;
        }
 //[HarmonyPrefix, HarmonyPatch(typeof(FullBodyIKMgr), "IKAttach", typeof(string), typeof(IKAttachParam))]
 // public void IKAttach(FullBodyIKMgr.IKEffectorType effector_type, IKAttachParam param)
 // public void IKAttach(string ik_name, IKAttachParam param)
 public static void IKAttach(string ik_name, IKAttachParam param)
 {
     MyLog.Log("IKAttach"
               + ik_name
               , param.targetChara.status.fullNameJpStyle
               , param.slotName
               , param.targetBoneName
               , param.attachIKName
               , param.attachPointName
               , param.attachType
               , param.axisBoneName
               , param.odoguName
               , param.odoguTgtName
               );
 }
        public override void CopyHandIK(Maid master, Maid slave, XtMasterSlave.v3Offsets[] v3ofs, int num_)
        {
            List <string> listHand = new List <string> {
                "右手", "左手"
            };
            List <AIKCtrl.IKAttachType> listTypes = new List <AIKCtrl.IKAttachType>
            {
                AIKCtrl.IKAttachType.NewPoint, AIKCtrl.IKAttachType.Rotate
            };

            listHand.ToList().ForEach(h =>
            {
                var ikcm = master.body0.fullBodyIK.GetIKCtrl(h);
                var ikcs = slave.body0.fullBodyIK.GetIKCtrl(h);
                listTypes.ForEach(t =>
                {
                    var ikm = ikcm.GetIKSettingData(t);
                    var iks = ikcs.GetIKSettingData(t);

                    if (!(string.IsNullOrEmpty(ikm.curTargetData.tgtAttachName) && ikm.curTargetData.target == null))
                    {
                        //Console.WriteLine("{0} {1} -> {2} {3} {4}", h, t, ikm.attachType, ikm.Tgt_AttachName, ikm.Target);

                        if (iks.attachType != AIKCtrl.IKAttachType.Rotate)
                        {
                            if (ikm.attachType != AIKCtrl.IKAttachType.Rotate)
                            {
                                iks.attachType = (ikm.attachType);
                            }
                        }

                        float fixAngle(float angle)
                        {
                            while (Mathf.Abs(angle) > 360f)
                            {
                                angle = ((!(angle < 0f)) ? (angle - 360f) : (angle + 360f));
                            }
                            return(angle);
                        }

                        if (IkXT.IsIkCtrlO117)
                        {
                            // befor

                            /*
                             * ikcs.SetIKSetting(t
                             *  , AIKCtrl.IKExecTiming.Normal
                             *  , ikm.curTargetData.targetChara
                             *  , ikm.curTargetData.tgtAttachSlot
                             *  , ikm.curTargetData.tgtAttachName
                             *  , ikm.curTargetData.axisTarget
                             *  , ikm.curTargetData.target
                             *  , ikm.curTargetData.tgtOffset
                             *  , ikm.doAnimation);
                             */

                            // after
                            IKAttachParam ikAttachParam = new IKAttachParam(null, master);
                            ikAttachParam.attachType    = t;
                            ikAttachParam.execTiming    = AIKCtrl.IKExecTiming.Normal;
                            ikAttachParam.targetChara   = ikm.curTargetData.targetChara;
                            ikAttachParam.slotName      = ikm.curTargetData.tgtAttachName;
                            ikAttachParam.axisBone      = ikm.curTargetData.axisTarget;
                            ikAttachParam.attachTarget  = ikm.curTargetData.target;
                            ikAttachParam.offset        = ikm.curTargetData.tgtOffset;
                            ikAttachParam.doAnimation   = ikm.doAnimation;

                            ikcs.SetIKSetting(ikAttachParam);

                            //ikcs.SetIKSetting(t, AIKCtrl.IKExecTiming.Normal, ikm.curTargetData.targetChara, ikm.curTargetData.tgtAttachSlot, ikm.curTargetData.Tgt_AttachName, ikm.curTargetData.AxisTgt, ikm.curTargetData.Target, ikm.curTargetData.TgtOffset, ikm.DoAnimation);
                            //ikcs.SetIKSetting(t, false, ikm.TgtMaid, ikm.Tgt_AttachSlot, ikm.Tgt_AttachName, ikm.AxisTgt, ikm.Target, ikm.TgtOffset, ikm.DoAnimation, ikm.BlendTime);
                            //iks.SetIKSetting(ikm.TgtMaid, ikm.Tgt_AttachSlot, ikm.Tgt_AttachName, ikm.AxisTgt, ikm.Target, ikm.TgtOffset, ikm.DoAnimation, ikm.BlendTime);
                        }
                        else
                        {
                            //iks.TgtMaid = ikm.TgtMaid;
                            //iks.Tgt_AttachSlot = ikm.Tgt_AttachSlot;
                            //iks.Tgt_AttachName = ikm.Tgt_AttachName;
                            //iks.Target = ikm.Target;
                            //iks.AxisTgt = ikm.AxisTgt;
                        }

                        if (iks.isPointAttach)
                        {
                            iks.curTargetData.tgtOffset = ikm.curTargetData.tgtOffset;
                            if (h == "右手")
                            {
                                iks.curTargetData.tgtOffset += v3ofs[num_].v3HandROffset;
                            }
                            else
                            {
                                iks.curTargetData.tgtOffset += v3ofs[num_].v3HandLOffset;
                            }
                        }
                        else
                        {
                            Vector3 v3rot = Vector3.zero;
                            if (h == "右手")
                            {
                                v3rot = v3ofs[num_].v3HandROffsetRot;
                            }
                            else
                            {
                                v3rot = v3ofs[num_].v3HandLOffsetRot;
                            }

                            iks.curTargetData.tgtOffset.x = fixAngle(ikm.curTargetData.tgtOffset.x + v3rot.x);
                            iks.curTargetData.tgtOffset.y = fixAngle(ikm.curTargetData.tgtOffset.y + v3rot.y);
                            iks.curTargetData.tgtOffset.z = fixAngle(ikm.curTargetData.tgtOffset.z + v3rot.z);
                        }
                    }
                });
            });

            //needInit = true;
        }