namespace Holo.Virtual.Rooms.Bots { using Holo; using Holo.Virtual.Rooms; using Holo.Virtual.Rooms.Pathfinding; using Holo.Virtual.Users; using Ion.Storage; using System; using System.Collections; using System.Data; using System.Runtime.CompilerServices; using System.Threading; internal class virtualBot { private Thread aiHandler; private chatTrigger[] chatTriggers; private Coord[] Coords; private virtualRoomUser Customer; private chatTrigger customerTrigger; internal string Figure; internal bool freeRoam; internal int goalX; internal int goalY; internal double H; internal string Mission; internal string Name; internal string noShoutingMessage; internal virtualRoom Room; internal int roomUID; private string[] Sayings; private string[] Shouts; private Hashtable Statuses; internal int X; internal int Y; internal byte Z1; internal byte Z2; internal virtualBot(int botID, int roomUID, virtualRoom Room) { DataRow dRow; DatabaseClient dbClient; DataColumn dCol; DataTable dTable; this.roomUID = roomUID; this.Room = Room; using (dbClient = Eucalypt.dbManager.GetClient()) { dRow = dbClient.getRow("SELECT name,mission,figure,x,y,z,freeroam,message_noshouting FROM roombots WHERE id = '" + botID + "'"); } this.Name = Convert.ToString(dRow[0]); this.Mission = Convert.ToString(dRow[1]); this.Figure = Convert.ToString(dRow[2]); this.X = Convert.ToInt32(dRow[3]); this.Y = Convert.ToInt32(dRow[4]); this.Z1 = Convert.ToByte(dRow[5]); this.Z2 = this.Z1; this.goalX = -1; this.freeRoam = Convert.ToString(dRow[6]) == "1"; this.noShoutingMessage = Convert.ToString(dRow[7]); using (dbClient = Eucalypt.dbManager.GetClient()) { dCol = dbClient.getColumn("SELECT text FROM roombots_texts WHERE id = '" + botID + "' AND type = 'say'"); } this.Sayings = dataHandling.dColToArray(dCol); using (dbClient = Eucalypt.dbManager.GetClient()) { dCol = dbClient.getColumn("SELECT text FROM roombots_texts WHERE id = '" + botID + "' AND type = 'shout'"); } this.Shouts = dataHandling.dColToArray(dCol); using (dbClient = Eucalypt.dbManager.GetClient()) { dTable = dbClient.getTable("SELECT words, replies, serve_replies, serve_item FROM roombots_texts_triggers WHERE id = '" + botID + "'"); } this.chatTriggers = new chatTrigger[dTable.Rows.Count]; int i = 0; foreach (DataRow dbRow in dTable.Rows) { this.chatTriggers[i] = new chatTrigger(Convert.ToString(dbRow["words"]).ToLower().Split(new char[] { '}' }), Convert.ToString(dbRow["replies"]).Split(new char[] { '}' }), Convert.ToString(dbRow["serve_replies"]).Split(new char[] { '}' }), Convert.ToString(dbRow["serve_item"])); i++; } using (dbClient = Eucalypt.dbManager.GetClient()) { dTable = dbClient.getTable("SELECT x,y FROM roombots_coords WHERE id = '" + botID + "'"); } this.Coords = new Coord[dTable.Rows.Count]; i = 0; foreach (DataRow dbRow in dTable.Rows) { this.Coords[i] = new Coord(Convert.ToInt32(dbRow["x"]), Convert.ToInt32(dbRow["y"])); i++; } this.Statuses = new Hashtable(); this.aiHandler = new Thread(new ThreadStart(this.AI)); this.aiHandler.Priority = ThreadPriority.BelowNormal; this.aiHandler.Start(); } internal void addStatus(string Key, string Value) { if (this.Statuses.ContainsKey(Key)) { this.Statuses.Remove(Key); } this.Statuses.Add(Key, Value); } private void AI() { int messageID; int lastMessageID = -1; Random RND = new Random(this.roomUID * DateTime.Now.Millisecond); goto Label_02E5; Label_02CE: Thread.Sleep(0xbb8); Out.WriteTrace("Bot AI loop"); Label_02E5: do { } while (this.Customer != null); switch (RND.Next(0, 15)) { case 1: { Coord Next = new Coord(); if (!this.freeRoam) { Next = this.Coords[RND.Next(0, this.Coords.Length)]; } else { int[] Borders = this.Room.getMapBorders(); Next = new Coord(RND.Next(0, Borders[0]), RND.Next(0, Borders[1])); } if ((Next.X == this.X) && (Next.Y == this.Y)) { this.Z1 = (byte) RND.Next(0, 10); this.Z2 = this.Z1; this.Refresh(); } else { this.goalX = Next.X; this.goalY = Next.Y; } goto Label_02CE; } case 2: { byte R = (byte) RND.Next(0, 10); while (R == this.Z2) { R = (byte) RND.Next(0, 10); } this.Rotate(R); goto Label_02CE; } case 3: if (this.Shouts.Length > 0) { messageID = RND.Next(0, this.Shouts.Length); if (this.Shouts.Length > 1) { while (messageID == lastMessageID) { messageID = RND.Next(0, this.Shouts.Length); } lastMessageID = messageID; } this.Room.sendShout(this, this.Shouts[messageID]); } goto Label_02CE; case 4: if (this.Sayings.Length > 0) { messageID = RND.Next(0, this.Sayings.Length); if (this.Sayings.Length > 1) { while (messageID == lastMessageID) { messageID = RND.Next(0, this.Sayings.Length); } lastMessageID = messageID; } this.Room.sendSaying(this, this.Sayings[messageID]); } goto Label_02CE; case 5: if (RND.Next(0, 2) != 0) { this.addStatus("dance", "3"); this.Refresh(); } else { this.Statuses.Remove("dance"); this.handleStatus("wave", "", Config.Statuses_Wave_waveDuration); } goto Label_02CE; case 6: goto Label_02CE; } goto Label_02CE; } internal void checkOrders() { if (this.Customer != null) { this.goalX = -1; this.Rotate(this.Customer.X, this.Customer.Y); this.removeStatus("carryd"); this.Room.sendSaying(this, this.customerTrigger.serveReply); if (!this.Customer.statusManager.containsStatus("sit")) { this.Customer.Z1 = Rotation.Calculate(this.Customer.X, this.Customer.Y, this.X, this.Y); this.Customer.Z2 = this.Customer.Z1; } this.Customer.statusManager.carryItem(this.customerTrigger.serveItem); this.Customer = null; this.customerTrigger = null; } } internal bool containsStatus(string Key) { return this.Statuses.ContainsKey(Key); } internal Coord getClosestWalkCoordTo(int X, int Y) { int minDistance = 6; Coord Closest = new Coord(-1, 0); foreach (Coord Coord in this.Coords) { int curDistance = Math.Abs((int) (X - Coord.X)) + Math.Abs((int) (Y - Coord.Y)); if (curDistance < minDistance) { minDistance = curDistance; Closest = Coord; } } return Closest; } internal void handleStatus(string Key, string Value, int Length) { if (this.Statuses.ContainsKey(Key)) { this.Statuses.Remove(Key); } new statusVoid(this.HANDLESTATUS).BeginInvoke(Key, Value, Length, null, null); } private void HANDLESTATUS(string Key, string Value, int Length) { try { this.Statuses.Add(Key, Value); this.Refresh(); Thread.Sleep(Length); this.Statuses.Remove(Key); this.Refresh(); } catch { } } internal void Interact(virtualRoomUser roomUser, string Message) { Message = Message.ToLower(); string[] messageWords = Message.Split(new char[] { ' ' }); if (this.chatTriggers != null) { foreach (chatTrigger Trigger in this.chatTriggers) { for (int i = 0; i < messageWords.Length; i++) { if (Trigger.containsWord(messageWords[i])) { if (Trigger.serveItem != "") { if (this.Customer == null) { Coord Closest = this.getClosestWalkCoordTo(roomUser.X, roomUser.Y); if (Closest.X != -1) { this.Room.sendSaying(this, Trigger.Reply); this.removeStatus("dance"); this.addStatus("carryd", Trigger.serveItem); this.goalX = Closest.X; this.goalY = Closest.Y; this.Customer = roomUser; this.customerTrigger = Trigger; } } } else { this.Z1 = Rotation.Calculate(this.X, this.Y, roomUser.X, roomUser.Y); this.Z2 = this.Z1; this.Room.sendSaying(this, Trigger.Reply); } return; } } } } } internal void Kill() { try { this.aiHandler.Abort(); } catch { } this.aiHandler = null; this.Room = null; this.Statuses = null; this.Coords = null; this.Sayings = null; this.Shouts = null; this.chatTriggers = null; this.Customer = null; this.customerTrigger = null; } internal void Refresh() { this.Room.Refresh(this); } internal void removeStatus(string Key) { try { if (this.Statuses.ContainsKey(Key)) { this.Statuses.Remove(Key); } } catch { } } internal void Rotate(byte R) { if (!((R == this.Z1) || this.Statuses.ContainsKey("sit"))) { this.Z1 = R; this.Z2 = R; this.Refresh(); } } internal void Rotate(int toX, int toY) { this.Rotate(Rotation.Calculate(this.X, this.Y, toX, toY)); } internal string detailsString { get { string s = string.Concat(new object[] { "i:", this.roomUID, Convert.ToChar(13), "a:-1", Convert.ToChar(13), "n:", this.Name, Convert.ToChar(13), "f:", this.Figure, Convert.ToChar(13), "l:", this.X, " ", this.Y, " ", this.H, Convert.ToChar(13) }); if (this.Mission != "") { object inconnu2 = s; s = string.Concat(new object[] { inconnu2, "c:", this.Mission, Convert.ToChar(13) }); } else { s = s + "c: Holo rulez!" + Convert.ToChar(13); } return (s + "[bot]" + Convert.ToChar(13)); } } internal string statusString { get { string s = string.Concat(new object[] { this.roomUID, " ", this.X, ",", this.Y, ",", this.H.ToString().Replace(",", "."), ",", this.Z1, ",", this.Z2, "/" }); foreach (string Key in this.Statuses.Keys) { s = s + Key; string Value = (string) this.Statuses[Key]; if (Value != "") { s = s + " " + Value; } s = s + "/"; } return s; } } private class chatTrigger { private string[] Replies; internal string serveItem; private string[] serveReplies; private string[] Words; internal chatTrigger(string[] Words, string[] Replies, string[] serveReplies, string serveItem) { this.Words = Words; this.Replies = Replies; this.serveReplies = serveReplies; this.serveItem = serveItem; } internal bool containsWord(string Word) { if (Word.Substring(Word.Length - 1, 1) == "?") { Word = Word.Substring(0, Word.Length - 1); } for (int i = 0; i < this.Words.Length; i++) { if (this.Words[i] == Word) { return true; } } return false; } internal string Reply { get { return this.Replies[new Random(DateTime.Now.Millisecond).Next(0, this.Replies.Length)]; } } internal string serveReply { get { return this.serveReplies[new Random(DateTime.Now.Millisecond).Next(0, this.serveReplies.Length)]; } } } private delegate void statusVoid(string Key, string Value, int Length); } }