private void OnMoving(Model.Creature creature) { if (State == StateType.FLEE && creature == Master) { Api.MoveToAsync(Master.IsMoving ? Master.Destination : Master.Position); } }
private void OnCreatureUpdate(Model.Creature creature) { if (creature == Api.Me) { if (Api.Me.MaxHp * HP_EMERGENCY_THRESHOLD >= Api.Me.Hp) { Flee(); } else if (State == StateType.ATTACK) { var target = Api.World[Api.Me.TargetId] as Model.Npc; if (target != null && !target.IsAlikeDead) { if (!target.IsSpoiled && Spoil.IsReady) { Api.UseSkillAsync(Spoil); } else if (IsAllowWildSweep && WildSweep.IsReady) { Api.UseSkillAsync(WildSweep); } } } else if (State == StateType.REST && Api.Me.Hp == Api.Me.MaxHp && Api.Me.Mp == Api.Me.MaxMp) { State = StateType.NOTHING; if (Api.Me.IsSitting) { Api.UseUserCommandAsync(Lineage.UserCommand.Stand); } } } }
private void OnDie(Model.Creature creature, Lineage.ReturnPoint?points = null) { if (creature == Enemy) { State = StateType.NOTHING; var npc = Enemy as Model.Npc; if (npc != null && npc.IsSpoiled) { Api.UseSkillAsync(Sweep, true); } } else if (creature == Master) { Api.Cancel(); Api.Logout(); } }
private void OnChatMessage(Lineage.Channel channel, string message, string name, Model.Creature author = null) { Console.WriteLine(string.Format("[{0}] {1}: {2}", channel, name, message)); if (message == "Serve!" && author is Model.Character) { Api.Target(Master = author as Model.Character); Api.UseSocialActionAsync(Lineage.SocialAction.Bow); } else if (message == "Leave!" && author == Master) { Master = null; Api.UseSocialActionAsync(Lineage.SocialAction.Dance); } else if (Master != null && Master.Name == name && message.Trim().EndsWith("!")) { switch (message.Trim().TrimEnd('!').ToLower()) { case "attack": Attack(); break; case "return": Return(); break; case "rest": Rest(); break; case "quit": Api.Logout(); break; } } }
private static void Command(string command, string name, Model.Creature author) { string[] args = command.Split(" ".ToCharArray()); command = args.First(); args = args.Skip(1).ToArray(); var world = gsApi.World; var me = gsApi.World.Me; switch (command) { case "hello": Reply("Hello", name); break; /*case "login": * if (args.Length == 1) * if (Access.LogIn(name, args.First())) * Reply("Accept", name); * else * Reply("Reject", name); * break;*/ case "quit": gsApi.Logout(); break; case "to": case "moveto": { Library.Point?point = null; if (args.Length == 0) { var target = world[me.TargetId] as Model.Creature; if (target != null) { point = target.Position; } } if (args.Length == 1 && author != null) { if (args.First() == "me") { point = author.Position; } else if (args.First() == "my") { point = author.Destination; } } if (point.HasValue) { Manager.Free(MOVE_PROGRAM); gsApi.MoveTo(point.Value); } break; } case "get": case "target": if (args.Length == 1) { switch (args[0]) { case "self": gsApi.Target(me); break; case "me": if (author != null) { gsApi.Target(author); } else { Reply("Can't find", name); } break; case "my": if (author != null) { var target = world[author.TargetId] as Model.Creature; if (target != null) { gsApi.Target(target); break; } } Reply("Can't find", name); break; case "npc": //Живой, для мёртвого можно ввести команду target corpse { Model.Npc nearest = null; var min = double.MaxValue; lock (world) foreach (var obj in world) { var npc = obj as Model.Npc; if (npc != null && !npc.IsAlikeDead) { var distance = me.Distance(npc); if (distance < min) { min = distance; nearest = npc; } } } if (nearest != null) { gsApi.Target(nearest); } break; } default: Model.Character character = world.Find(args[0]); if (character != null) { gsApi.Target(character); } else { Reply("Can't find", name); } break; } } break; case "attack": gsApi.Interact(me.TargetId, null, true); break; case "cancel": gsApi.Cancel(); break; case "up": case "pickup": { /*int count = 0; * * if(args.Length == 1) * int.TryParse(args[0], out count); * * ... * * if (items.Count > 0) * gsApi.Interact(items.First());*/ /* Централизованный подбор предметов: * var items = world * .Where(obj => obj is Model.Item && !((Model.Item)obj).InInventory) * .OrderBy(obj => me.Distance((Model.Item)obj)).ToList();*/ /* Децентрализованный подбор предметов: * Сохраняем count и выполняем подбор ближайшего предмета с count-- пока count > 0 */ Model.Item nearest = null; var min = double.MaxValue; lock (world) foreach (var obj in world) { var item = obj as Model.Item; if (item != null && !item.InInventory) { var distance = me.Distance(item); if (distance < min) { min = distance; nearest = item; } } } if (nearest != null) { gsApi.Interact(nearest); } break; } case "skill": case "useskill": int skillId = 0; if (args.Length == 1 && int.TryParse(args[0], out skillId)) { gsApi.UseSkill(skillId, true); } break; case "item": case "useitem": { int itemId = 0; if (args.Length == 1 && int.TryParse(args[0], out itemId)) { lock (world) foreach (var obj in world) { var item = obj as Model.Item; if (item != null && item.ItemId == itemId && item.InInventory) { gsApi.UseItem(item); break; } } } break; } case "items": case "itemlist": lock (world) foreach (var obj in world) { var item = obj as Model.Item; if (item != null && item.InInventory) { Reply(string.Format("[{0}] {1}", item.ItemId, item.Count), name); } } break; case "drop": case "dropitem": { int itemId = 0; int count = 0; if (args.Length > 0) { int.TryParse(args[0], out itemId); } if (args.Length > 1) { int.TryParse(args[1], out count); } if (itemId != 0) { lock (world) foreach (var obj in world) { var item = obj as Model.Item; if (item != null && item.ItemId == itemId && item.InInventory) { gsApi.Drop(item, count); break; } } } break; } case "return": { var point = Lineage.ReturnPoint.Town; if (args.Length == 1) { Enum.TryParse <Lineage.ReturnPoint>(args[0], out point); } gsApi.Return(point); break; } case "info": new Command.Info(gsApi, args, name).Run(); break; case "travel": { if (args.Length == 0) { var program = Manager.Get(MOVE_PROGRAM) as Program.Move.Travel; var distance = program != null ? new Library.Interval(me.Position, program.Model.Waypoints.Last()).Length : 0; Reply(string.Format("{0}", (int)distance), name); } else if (args.Length == 3) { double x, y, z; if (double.TryParse(args[0], out x) && double.TryParse(args[1], out y) && double.TryParse(args[2], out z)) { var program = new Program.Move.Travel(gsApi); program.Start(new Library.Point(x, y, z)); Manager.Load(program, MOVE_PROGRAM); } } break; } case "follow": { var target = world[me.TargetId] as Model.Creature; if (args.Length >= 1 && target != null) { switch (args[0]) { case "fast": { var program = new Program.Move.FastFollow(gsApi); program.Bind(target); Manager.Load(program, MOVE_PROGRAM); break; } case "full": { var program = new Program.Move.FullFollow(gsApi); program.Bind(target); Manager.Load(program, MOVE_PROGRAM); break; } } } break; } case "cross": { int size = 0; if (args.Length == 1 && int.TryParse(args[0], out size)) { var center = me.Position; var program = new Program.Move.SimpleRoute(gsApi); program.Load(new Library.Point[] { new Library.Point(center.X + size, center.Y, center.Z), new Library.Point(center.X, center.Y + size, center.Z), new Library.Point(center.X - size, center.Y, center.Z), new Library.Point(center.X, center.Y - size, center.Z), new Library.Point(center.X + size, center.Y, center.Z), center }); Manager.Load(program, MOVE_PROGRAM); } break; } case "action": { if (args.Length > 0) { switch (args[0]) { case "sit": gsApi.UseUserCommand(Lineage.UserCommand.Sit); break; case "stand": gsApi.UseUserCommand(Lineage.UserCommand.Stand); break; } } break; } case "moving": { if (args.Length > 0 && System.IO.File.Exists(args[0])) { var parts = new List <List <Library.Point> >(); var reader = new System.IO.BinaryReader( System.IO.File.OpenRead(args[0])); while (reader.PeekChar() != -1) { var points = new List <Library.Point>(); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { points.Add(new Library.Point( reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32())); } parts.Add(points); } var graph = new Model.Graph(parts); var program = new Program.Move.OnGraph(gsApi); program.Play(graph); Manager.Load(program, MOVE_PROGRAM); } break; } case "autospoil": { throw new NotImplementedException(); break; } case "autosweep": // ToDo: Нуждается в тестировании и отладке { if (args.Length > 0) { var program = new Program.AutoSweep(gsApi); switch (args[0]) { case "my": program.Start(true); break; case "all": program.Start(false); break; } if (program.Enabled) { Manager.Load(program, typeof(Program.AutoSweep).Name); } } else { var program = Manager.Get(typeof(Program.AutoSweep).Name) as Program.AutoSweep; if (program != null) { Reply(string.Format("Enabled ({0})", program.OnlyMy ? "My" : "All"), name); } else { Reply("Disabled", name); } } break; } case "autopickup": { if (args.Length > 0) { var program = new Program.AutoPickup(gsApi); switch (args[0]) { case "my": program.Start(true); break; case "all": program.Start(false); break; } if (program.Enabled) { Manager.Load(program, typeof(Program.AutoPickup).Name); } } else { var program = Manager.Get(typeof(Program.AutoPickup).Name) as Program.AutoPickup; if (program != null) { Reply(string.Format("Enabled ({0})", program.OnlyMy ? "My" : "All"), name); } else { Reply("Disabled", name); } } break; } case "route": { if (args.Length > 0) { switch (args[0]) { case "record": if (args.Length > 1) { switch (args[1]) { case "add": if (RouteRecord != null && author != null) { RouteRecord.Add(author.Position); RouteRecord.Save(); } break; case "del": if (RouteRecord != null) { RouteRecord.Del(); RouteRecord.Save(); } break; case "auto": int period = 1; if (args.Length == 3) { int.TryParse(args[2], out period); } if (RecordTimer != null) { RecordTimer.Close(); } RecordTimer = new System.Timers.Timer(period * 1000); RecordTimer.Elapsed += (object timer, System.Timers.ElapsedEventArgs ea) => { if (RecordLastPos != author.Position) { RecordLastPos = author.Position; RouteRecord.Add(author.Position); RouteRecord.Save(); } }; RecordTimer.Enabled = true; break; case "stop": if (RecordTimer != null) { RecordTimer.Close(); } break; default: //ToDo ../ fix RouteRecord = new FileRoute(new System.IO.FileInfo(string.Format("{0}.route", args[1]))); break; } } break; default: if (args.Length == 1 && !string.IsNullOrEmpty(name = args[0])) //ToDo ../ fix { bool reverse = name.StartsWith("-"); name = (name[0] == '-' || name[0] == '+' ? name.Substring(1) : name); var route = new FileRoute(new System.IO.FileInfo(string.Format("{0}.route", name))); route.Load(); if (route.Count > 0) { var points = !reverse ? route.Points : route.Points.Reverse(); var program = new Program.Move.SimpleRoute(gsApi); program.Load(points); Manager.Load(program, MOVE_PROGRAM); } } break; } } else if (RouteRecord != null) { Reply(string.Format("Count: {0}, Length: {1}", RouteRecord.Count, RouteRecord.Length), name); } break; } default: Reply("Don’t understand", name); break; } }