private void PrintInfo(ConvertError overallError, ConvertResult source, ConvertResult destination) { string prefix = "ERROR"; if (overallError == ConvertError.Warning) { prefix = "WARNING"; } Console.WriteLine($"{prefix}: \"{source.File}\" to\"{destination.File}\""); if (!string.IsNullOrWhiteSpace(source.Message)) { Console.WriteLine($"Source Msg: {source.Message}"); } if (!string.IsNullOrWhiteSpace(destination.Message)) { Console.WriteLine($"Destination Msg: {destination.Message}"); } }
//用Socket方式发送给UR一个字符串,该字符串已经是一个六维向量,UR可以直接拿来用,就是走这个坐标值就行了,在UR上面不需要做任何设置 //采用socket纯主机的方式优点是代码都藏在上位机中,方便调试和实现复杂应用,而且别人不好抄袭或者模仿,因为UR的程序是很好破解的 private void btn_TriggerSocket_Click(object sender, EventArgs e) { try { //1 把当前的特征的XY像素坐标计算出相对于O点的差值(注意这里对我填到文本框里的结果要*2,因为实际确实是他的两倍 double PixelDiff_X = (Convert.ToDouble(label_X.Text) - (Convert.ToDouble(txt_O_X.Text) * 2)); double PixelDiff_Y = (Convert.ToDouble(label_Y.Text) - (Convert.ToDouble(txt_O_Y.Text) * 2)); //2 把这个差值转换为实际的mm差值(我们在前面已经得到了像素精度),最后再转换成M做向量合成 double RealDiff_X = Convert.ToDouble(label_Accurary.Text) * PixelDiff_X / 1000; double RealDiff_Y = Convert.ToDouble(label_Accurary.Text) * PixelDiff_Y / 1000; //角度值和弧度值都取出来,想用哪个用哪个 double PixelDiff_R_Angle = Convert.ToDouble(label_R_Angle.Text); double PixelDiff_R_Radius = Convert.ToDouble(label_R_Radius.Text); //3 把得到的两个差值放射到OA和OB两个方向向量中(只关心XYZ,不关心UVW) ObjectVectorOA[0] = CurrentActiveOA[0] * RealDiff_X; ObjectVectorOA[1] = CurrentActiveOA[1] * RealDiff_X; ObjectVectorOA[2] = CurrentActiveOA[2] * RealDiff_X; ObjectVectorOA[3] = 0; ObjectVectorOA[4] = 0; ObjectVectorOA[5] = 0; ObjectVectorOB[0] = CurrentActiveOB[0] * RealDiff_Y; ObjectVectorOB[1] = CurrentActiveOB[1] * RealDiff_Y; ObjectVectorOB[2] = CurrentActiveOB[2] * RealDiff_Y; ObjectVectorOB[3] = 0; ObjectVectorOB[4] = 0; ObjectVectorOB[5] = 0; //4 得到最终的向量 ObjectVectorTotal[0] = ObjectVectorOA[0] + ObjectVectorOB[0]; ObjectVectorTotal[1] = ObjectVectorOA[1] + ObjectVectorOB[1]; ObjectVectorTotal[2] = ObjectVectorOA[2] + ObjectVectorOB[2]; ObjectVectorTotal[3] = 0; ObjectVectorTotal[4] = 0; ObjectVectorTotal[5] = 0; //5 向目标UR发送指定向量(注意UR从拍照位置SnapPos就不需要再去这个O点,再用get_forward_kin()获取一遍数值,这样反而麻烦,所以直接和实际的O点坐标合成即可) ObjectVectorFinal[0] = ObjectVectorTotal[0] + PosInt1[0]; ObjectVectorFinal[1] = ObjectVectorTotal[1] + PosInt1[1]; ObjectVectorFinal[2] = ObjectVectorTotal[2] + PosInt1[2]; ObjectVectorFinal[3] = PosInt1[3]; ObjectVectorFinal[4] = PosInt1[4]; ObjectVectorFinal[5] = PosInt1[5]; //string OriginalPos = GetPoseString(PosInt1); string NewPos = GetPoseString(ObjectVectorFinal); //注意这里就通过纯上位机控制了,UR上不写任何程序了 if (ifConnected) { //注意虽然发送的只是一个movel指令,里面有一个表示UR位置的六维向量,我们仍然无法把角度值直接传递过去 //比如movel(p[x,y,z,u,v,w])跟movel(p[x,y,z,u,v,w+3.14])的区别,并不是最后一个轴旋转180度的效果 //movej[A,B,C,D,E,F,G]跟movej[A,B,C,D,E,F,G+3.14]倒是真的这个关系,可惜我们已然要求movel方式移动了 //其实解决方法就是直接发送一串函数,让UR自己去用pose_add翻译出到底我要最后一个关节旋转指定角度如何分配到最后三个关节值上 /* * //下面的代码如果是单纯的移动,不需要转换关节角度值可以这么干 * string CMD = "movel(" + NewPos + ",v = 0.1)"; * URController.Send_command(CMD); */ string Embed_head = "def VisionCatch_test():\r\n"; string Embed_NewPos = "NewPos = " + NewPos + "\r\n"; string Embed_RotatePos = "RotatePos = p[0,0,0,0,0," + -PixelDiff_R_Radius + "]\r\n"; string Embed_TotalPos = "TotalPos = pose_add(NewPos,RotatePos)\r\n"; string Embed_CMD = "movel(TotalPos,v = 0.1)\r\n"; string Embed_Bottom = "end\r\n"; string Embed_Run = "VisionCatch_test()\r\n"; textBoxCommand.Text = ""; textBoxCommand.Text = Embed_head + Embed_NewPos + Embed_RotatePos + Embed_TotalPos + Embed_CMD + Embed_Bottom + Embed_Run; string CMD = textBoxCommand.Text; URController.Send_command(CMD); } else { MessageBox.Show("请确认目标UR已连接"); } //把每次比对的差值放到listBox中方便查看 this.listBox_Debug.Items.Clear(); this.listBox_Debug.Items.Add("特征像素差(px):X" + PixelDiff_X.ToString("0.0")); this.listBox_Debug.Items.Add("特征像素差(px):Y" + PixelDiff_Y.ToString("0.0")); this.listBox_Debug.Items.Add("特征实际差(mm):X" + RealDiff_X.ToString("0.0000")); this.listBox_Debug.Items.Add("特征实际差(mm):Y" + RealDiff_Y.ToString("0.0000")); this.listBox_Debug.Items.Add("基准向量OA:" + GetPoseString(CurrentActiveOA)); this.listBox_Debug.Items.Add("基准向量OB:" + GetPoseString(CurrentActiveOB)); this.listBox_Debug.Items.Add("差异向量OA:" + GetPoseString(ObjectVectorOA)); this.listBox_Debug.Items.Add("差异向量OB:" + GetPoseString(ObjectVectorOB)); this.listBox_Debug.Items.Add("参考基准向量:" + GetPoseString(PosInt1)); this.listBox_Debug.Items.Add("差异向量整体:" + GetPoseString(ObjectVectorTotal)); this.listBox_Debug.Items.Add("合成向量整体:" + GetPoseString(ObjectVectorFinal)); } catch (Exception ConvertError) { MessageBox.Show("数据转换出错" + ConvertError.ToString()); } }
/// <summary> /// Converts an ability from a generic format to TFS rev script system spell format /// </summary> /// <param name="spell"></param> /// <returns>ConvertError, attack in string format OR error message</returns> public Tuple <ConvertError, string> GenericToTfsRevScriptSysSpells(ref Spell spell) { ConvertError error = ConvertError.Success; string attack = ""; if (spell.DefinitionStyle == SpellDefinition.TfsLuaScript) { attack = $" {{script =\"{spell.Name}\", interval = {spell.Interval}, chance = {spell.Chance * 100:0}"; if ((spell.MinDamage != null) && (spell.MaxDamage != null)) { attack += $", minDamage = {spell.MinDamage}, maxDamage = {spell.MaxDamage}"; } else if (spell.MaxDamage != null) { attack += $", maxDamage = {spell.MaxDamage}"; } if (spell.OnTarget != null) { attack += $", target = { spell.OnTarget.ToString().ToLower()}"; } if (spell.IsDirectional != null) { attack += $", direction = { spell.IsDirectional.ToString().ToLower()}"; } attack += "}"; } else if (spell.DefinitionStyle == SpellDefinition.Raw) { attack = $" {{name =\"{spell.Name}\", interval = {spell.Interval}, chance = {spell.Chance * 100:0}"; if (spell.Name == "melee") { if ((spell.MinDamage != null) && (spell.MaxDamage != null)) { attack += $", minDamage = {spell.MinDamage}, maxDamage = {spell.MaxDamage}"; } else if (spell.MaxDamage != null) { attack += $", maxDamage = {spell.MaxDamage}"; } else if ((spell.AttackValue != null) && (spell.Skill != null)) { attack += $", skill = {spell.Skill}, attack = {spell.AttackValue}"; } //else continue which we should never hit? attack += $", effect = {magicEffectNames[Effect.DrawBlood]}"; if (spell.Condition != ConditionType.None) { attack += $", condition = {{type = {ConditionToTfsConstant[spell.Condition]}, startDamage = {spell.StartDamage}, interval = {spell.Tick}}}"; } } else { if (spell.Name == "speed") { attack += $", speed = {{min = {spell.MinSpeedChange}, max = {spell.MaxSpeedChange}}}"; } else if (spell.Name == "condition") { attack += $", type = {ConditionToTfsConstant[spell.Condition]}, startDamage = {spell.StartDamage}, tick = {spell.Tick}"; } else if (spell.Name == "outfit") { if (!string.IsNullOrEmpty(spell.MonsterName)) { attack += $", monster = \"{spell.MonsterName}\""; } else if (spell.ItemId != null) { attack += $", item = {spell.ItemId}"; } } else if ((spell.Name == "combat") && (spell.DamageElement != null)) { attack += $", type = {CombatDamageNames[(CombatDamage)spell.DamageElement]}"; } else if (spell.Name == "drunk") { attack += $", drunkenness = {spell.Drunkenness * 100:0}"; } if ((spell.MinDamage != null) && (spell.MaxDamage != null)) { attack += $", minDamage = {spell.MinDamage}, maxDamage = {spell.MaxDamage}"; } else if (spell.MaxDamage != null) { attack += $", minDamage = {spell.MinDamage}"; } if (spell.Duration != null) { attack += $", duration = {spell.Duration}"; } if (spell.Range != null) { attack += $", range = {spell.Range}"; } if (spell.Radius != null) { attack += $", radius = {spell.Radius}, target = {spell.OnTarget.ToString().ToLower()}"; } if (spell.Length != null) { attack += $", length = {spell.Length}"; } if (spell.Spread != null) { attack += $", spread = {spell.Spread}"; } if (spell.ShootEffect != Animation.None) { attack += $", ShootEffect = {shootTypeNames[spell.ShootEffect]}"; } if (spell.AreaEffect != Effect.None) { attack += $", effect = {magicEffectNames[spell.AreaEffect]}"; } } attack += "}"; } else { error = ConvertError.Warning; attack = $"Can't convert abilitiy name {spell.Name} with DefinitionStyles {spell.DefinitionStyle}"; } return(new(error, attack)); }
public override ConvertResult WriteMonster(string directory, ref Monster monster) { ConvertError code = ConvertError.Success; string message = ""; string fileName = Path.Combine(directory, monster.FileName + "." + FileExt); using (var fstream = File.OpenWrite(fileName)) using (var dest = new StreamWriter(fstream)) { fstream.SetLength(0); dest.WriteLine($"local mType = Game.createMonsterType(\"{monster.RegisteredName}\")"); dest.WriteLine("local monster = {}"); dest.WriteLine(""); dest.WriteLine($"monster.name = \"{monster.Name}\""); dest.WriteLine($"monster.description = \"{monster.Description}\""); dest.WriteLine($"monster.experience = {monster.Experience}"); dest.WriteLine("monster.outfit = {"); if (monster.ItemIdLookType != 0) { dest.WriteLine($" lookTypeEx = {monster.ItemIdLookType}"); } else { dest.WriteLine($" lookType = {monster.OutfitIdLookType},"); dest.WriteLine($" lookHead = {monster.LookTypeDetails.Head},"); dest.WriteLine($" lookBody = {monster.LookTypeDetails.Body},"); dest.WriteLine($" lookLegs = {monster.LookTypeDetails.Legs},"); dest.WriteLine($" lookFeet = {monster.LookTypeDetails.Feet},"); dest.WriteLine($" lookAddons = {monster.LookTypeDetails.Addons},"); dest.WriteLine($" lookMount = {monster.LookTypeDetails.Mount}"); } dest.WriteLine("}"); dest.WriteLine(""); dest.WriteLine($"monster.health = {monster.Health}"); dest.WriteLine($"monster.maxHealth = {monster.Health}"); dest.WriteLine($"monster.runHealth = {monster.RunOnHealth}"); dest.WriteLine($"monster.race = \"{monster.Race}\""); // TODO check if mapping is neeeded dest.WriteLine($"monster.corpse = {monster.CorpseId}"); dest.WriteLine($"monster.speed = {monster.Speed}"); dest.WriteLine($"monster.summonCost = {monster.SummonCost}"); dest.WriteLine($"monster.maxSummons = {monster.MaxSummons}"); dest.WriteLine(""); dest.WriteLine("monster.changeTarget = {"); dest.WriteLine($" interval = {monster.RetargetInterval},"); dest.WriteLine($" chance = {monster.RetargetChance * 100:0}"); dest.WriteLine("}"); dest.WriteLine(""); // Flags dest.WriteLine("monster.flags = {"); dest.WriteLine($" summonable = {(monster.SummonCost > 0).ToString().ToLower()},"); dest.WriteLine($" attackable = {monster.Attackable.ToString().ToLower()},"); dest.WriteLine($" hostile = {monster.Hostile.ToString().ToLower()},"); dest.WriteLine($" convinceable = {(monster.ConvinceCost > 0).ToString().ToLower()},"); dest.WriteLine($" pushable = {monster.Pushable.ToString().ToLower()},"); dest.WriteLine($" boss = {monster.IsBoss.ToString().ToLower()},"); dest.WriteLine($" illusionable = {monster.Illusionable.ToString().ToLower()},"); dest.WriteLine($" canPushItems = {monster.PushItems.ToString().ToLower()},"); dest.WriteLine($" canPushCreatures = {monster.PushCreatures.ToString().ToLower()},"); dest.WriteLine($" staticAttackChance = {monster.StaticAttack},"); dest.WriteLine($" targetDistance = {monster.TargetDistance},"); dest.WriteLine($" healthHidden = {monster.HideHealth.ToString().ToLower()},"); dest.WriteLine($" canWalkOnEnergy = {(!monster.AvoidEnergy).ToString().ToLower()},"); dest.WriteLine($" canWalkOnFire = {(!monster.AvoidFire).ToString().ToLower()},"); dest.WriteLine($" canWalkOnPoison = {(!monster.AvoidPoison).ToString().ToLower()}"); dest.WriteLine("}"); dest.WriteLine(""); // Light dest.WriteLine("monster.light = {"); dest.WriteLine($" level = {monster.LightLevel},"); dest.WriteLine($" color = {monster.LightColor}"); dest.WriteLine("}"); dest.WriteLine(""); // Voices dest.WriteLine("monster.voices = {"); dest.WriteLine(" interval = 5000,"); dest.WriteLine(" chance = 10,"); string voice; for (int i = 0; i < monster.Voices.Count; i++) { bool yell = false; if (monster.Voices[i].SoundLevel == SoundLevel.Yell) { yell = true; } voice = $" {{text = \"{monster.Voices[i].Sound}\", yell = {yell.ToString().ToLower()}}},"; if (i == monster.Voices.Count - 1) { voice = voice.TrimEnd(','); } dest.WriteLine(voice); } dest.WriteLine("}"); dest.WriteLine(""); dest.WriteLine("monster.immunities = {"); dest.WriteLine($" {{type = \"paralyze\", condition = {monster.IgnoreParalyze.ToString().ToLower()}}},"); dest.WriteLine($" {{type = \"outfit\", condition = {monster.IgnoreOutfit.ToString().ToLower()}}},"); dest.WriteLine($" {{type = \"invisible\", condition = {monster.IgnoreInvisible.ToString().ToLower()}}},"); dest.WriteLine($" {{type = \"bleed\", condition = {monster.IgnoreBleed.ToString().ToLower()}}}"); dest.WriteLine("}"); dest.WriteLine(""); dest.WriteLine("monster.elements = {"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Physical]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Physical)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Energy]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Energy)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Earth]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Earth)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Fire]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Fire)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.LifeDrain]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.LifeDrain)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.ManaDrain]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.ManaDrain)}}},"); //dest.WriteLine($" {{type = { CombatDamageNames[CombatDamage.Healing]}, percent = {GenericToTfsElemementPercent(monster.XXXX)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Drown]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Drown)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Ice]}, percent = {GenericToTfsRevScriptSysElemementPercent(monster.Ice)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Holy]} , percent = {GenericToTfsRevScriptSysElemementPercent(monster.Holy)}}},"); dest.WriteLine($" {{type = {CombatDamageNames[CombatDamage.Death]} , percent = {GenericToTfsRevScriptSysElemementPercent(monster.Death)}}}"); dest.WriteLine("}"); dest.WriteLine(""); // Offensive abilities if (monster.Attacks.Count > 0) { IList <string> attacks = new List <string>(); foreach (var spell in monster.Attacks) { if (spell.SpellCategory == SpellCategory.Offensive) { Spell s = spell; var result = GenericToTfsRevScriptSysSpells(ref s); if (result.Item1 != ConvertError.Success) { if (code != ConvertError.Error) { code = ConvertError.Warning; message += result.Item2; } continue; } attacks.Add(result.Item2); } } dest.WriteLine("monster.attacks = {"); for (int i = 0; i < attacks.Count; i++) { if (i == attacks.Count - 1) { dest.WriteLine($"{attacks[i]}"); } else { dest.WriteLine($"{attacks[i]},"); } } dest.WriteLine("}"); dest.WriteLine(""); } // Defensive abilities IList <string> defenses = new List <string>(); foreach (var spell in monster.Attacks) { if (spell.SpellCategory == SpellCategory.Defensive) { Spell s = spell; var result = GenericToTfsRevScriptSysSpells(ref s); if (result.Item1 != ConvertError.Success) { if (code != ConvertError.Error) { code = ConvertError.Warning; message += result.Item2; } continue; } defenses.Add(result.Item2); } } dest.WriteLine("monster.defenses = {"); dest.WriteLine($" defense = {monster.Shielding},"); if (defenses.Count > 0) { dest.WriteLine($" armor = {monster.TotalArmor},"); } else { dest.WriteLine($" armor = {monster.TotalArmor}"); } for (int i = 0; i < defenses.Count; i++) { if (i == defenses.Count - 1) { dest.WriteLine($"{defenses[i]}"); } else { dest.WriteLine($"{defenses[i]},"); } } dest.WriteLine("}"); dest.WriteLine(""); // Summons if (monster.Summons.Count > 0) { dest.WriteLine("monster.summons = {"); string summon; for (int i = 0; i < monster.Summons.Count; i++) { summon = $" {{name = \"{monster.Summons[i].Name}\", chance = {monster.Summons[i].Chance * 100:0}, interval = {monster.Summons[i].Rate}"; if (monster.Summons[i].Max > 0) { summon += $", max = {monster.Summons[i].Max}"; } if (monster.Summons[i].Force) { summon += $", force = {monster.Summons[i].Force.ToString().ToLower()}"; } summon += "}"; if (i == monster.Summons.Count - 1) { summon = summon.TrimEnd(','); } else { summon += ","; } dest.WriteLine(summon); } dest.WriteLine("}"); dest.WriteLine(""); } if (monster.Scripts.Count(s => s.Type != ScriptType.OnDeath) > 0) { code = ConvertError.Warning; message += "Unable to convert scripts."; } var writableEvents = monster.Scripts.Where(s => s.Type == ScriptType.OnDeath).ToList(); if (writableEvents.Count > 0) { dest.WriteLine("monster.events = {"); for (int i = 0; i < writableEvents.Count; i++) { if (i == writableEvents.Count - 1) { dest.WriteLine($" \"{writableEvents[i].Name}\""); } else { dest.WriteLine($" \"{writableEvents[i].Name}\","); } } dest.WriteLine("}"); dest.WriteLine(""); } // Loot dest.WriteLine("monster.loot = {"); string loot; for (int i = 0; i < monster.Items.Count; i++) { string item; if (int.TryParse(monster.Items[i].Item, out int itemid)) { item = itemid.ToString(); } else { item = $"\"{monster.Items[i].Item}\""; } decimal chance = monster.Items[i].Chance * MAX_LOOTCHANCE; loot = $" {{id = {item}, chance = {chance:0}"; if (monster.Items[i].Count > 1) { loot += $", maxCount = {monster.Items[i].Count}"; } if (monster.Items[i].SubType > 0) { loot += $", subType = {monster.Items[i].SubType}"; } if (monster.Items[i].ActionId > 0) { loot += $", actionId = {monster.Items[i].ActionId}"; } if (!string.IsNullOrWhiteSpace(monster.Items[i].Text)) { loot += $", text = {monster.Items[i].Text}"; } loot += "},"; if (i == monster.Items.Count - 1) { loot = loot.TrimEnd(','); } dest.WriteLine(loot); } dest.WriteLine("}"); dest.WriteLine(""); dest.WriteLine("mType:register(monster)"); } return(new ConvertResult(fileName, code, message)); }