/// <summary> /// Lets a player turn ANSI color on and off. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void ColorCommand(CharData ch, string[] str) { if( ch == null ) return; if (!ch.HasActionBit(PC.PLAYER_COLOR)) { ch.SetActionBit(PC.PLAYER_COLOR); ch.SendText("&+LThe world becomes more &n&+mco&+Ml&+Wor&+Cf&n&+cul&+L.&n\r\n"); } else { SocketConnection.SendToCharBW("The color drains.\r\n", ch); ch.RemoveActionBit(PC.PLAYER_COLOR); } return; }
/// <summary> /// The camp function now simply creates a camp event. /// The Command.Quit function handles quitters and campers, based /// on the camping bit. The only goofy side effect of this is /// that an immortal who is camping can quit and get the /// "you roll up in your bedroll" message. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Camp(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (ch.CurrentPosition == Position.fighting || ch.Fighting) { ch.SendText("You're not gifted enough to make camp and fight at the same time.\r\n"); ch.RemoveActionBit(PC.PLAYER_CAMPING); return; } if (ch.FlightLevel != 0) { ch.SendText("Perhaps it would be more comfortable on the ground.\r\n"); return; } if (ch.HasActionBit(PC.PLAYER_CAMPING)) { ch.SendText("Your preparations are not quite complete.\r\n"); return; } if (ch.CurrentPosition < Position.stunned) { ch.SendText("Just lie still and finish &+RBle&+reding&n!\r\n"); return; } SocketConnection.Act("$n&n starts to set up camp.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You start to set up camp.\r\n"); ch.SetActionBit(PC.PLAYER_CAMPING); // Pass the character, the room they started camping in, and the // number of cycles to camp for // Pulse camp is 5 seconds, so make them wait for 1.5 minutes Event.CreateEvent(Event.EventType.camp, Event.TICK_CAMP, ch, ch.InRoom, 18); return; }
/// <summary> /// Sets and gets player configuration options. /// </summary> /// <param name="ch"></param> /// <param name="argument"></param> public static void Toggle(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (str.Length == 0) { ch.SendText("&+L+------------+------------------------------------------------------------+&n\r\n"); ch.SendText("&+L|&n&+m Option&+L |&n&+r Description&n &+L|&n\r\n"); ch.SendText("&+L+------------+------------------------------------------------------------+&n\r\n"); ch.SendText(ch.HasActionBit(PC.PLAYER_AUTOWRAP) ? "&+L[&+WX&+L]&n Autowrap &+L|&n &+cThe MUD automatically wraps long lines of text. &+L|&n\r\n" : "&+L[ ]&n Autowrap &+L|&n &+cThe MUD does not automatically wrap long text. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_BLANK) ? "&+L[&+WX&+L]&n Blank &+L|&n &+cYou have a blank line before your prompt. &+L|&n\r\n" : "&+L[ ]&n Blank &+L|&n &+cYou have no blank line before your prompt. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_BRIEF) ? "&+L[&+WX&+L]&n Brief &+L|&n &+cYou see brief descriptions. &+L|&n\r\n" : "&+L[ ]&n Brief &+L|&n &+cYou see long descriptions. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_CAST_TICK) ? "&+L[&+WX&+L]&n Casttick &+L|&n &+cYou see your casting ticks. &+L|&n\r\n" : "&+L[ ]&n Casttick &+L|&n &+cFor spam's sake, no casting ticks! &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_COMBINE) ? "&+L[&+WX&+L]&n Combine &+L|&n &+cYou see object lists in combined format. &+L|&n\r\n" : "&+L[ ]&n Combine &+L|&n &+cYou see object lists in single format. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_COLOR) ? "&+L[&+WX&+L]&n Color &+L|&n &+cYou see ANSI colors. &+L|&n\r\n" : "&+L[ ]&n Color &+L|&n &+cYou don't see ANSI colors. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_COLOR_CON) ? "&+L[&+WX&+L]&n Colorcon &+L|&n &+cYou see ANSI colors in consider messages. &+L|&n\r\n" : "&+L[ ]&n Colorcon &+L|&n &+cYou don't see ANSI colors in consider messages. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_MSP) ? "&+L[&+WX&+L]&n MSP &+L|&n &+cMUD Sound Protocol (MSP) support is on. &+L|&n\r\n" : "&+L[ ]&n MSP &+L|&n &+cMUD Sound Protocol (MSP) support is off. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_PAGER) ? "&+L[&+WX&+L]&n Pager &+L|&n &+cText is shown in separate pages. &+L|&n\r\n" : "&+L[ ]&n Pager &+L|&n &+cText is shown all-at-once with no paging. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_PROMPT) ? "&+L[&+WX&+L]&n Prompt &+L|&n &+cYou have a prompt. &+L|&n\r\n" : "&+L[ ]&n Prompt &+L|&n &+cYou don't have a prompt. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_SHOUT) ? "&+L[&+WX&+L]&n Shout &+L|&n &+cYou can hear shouts. &+L|&n\r\n" : "&+L[ ]&n Shout &+L|&n &+cYou cover your ears when someone is yelling. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_TELNET_GA) ? "&+L[&+WX&+L]&n TelnetGA &+L|&n &+cYou receive a telnet go-ahead sequence. &+L|&n\r\n" : "&+L[ ]&n TelnetGA &+L|&n &+cYou don't receive a telnet GA sequence. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_TELL) ? "&+L[&+WX&+L]&n Tell &+L|&n &+cYou can hear tells. &+L|&n\r\n" : "&+L[ ]&n Tell &+L|&n &+cYou are ignoring tells. &+L|&n\r\n" ); ch.SendText(ch.HasActionBit(PC.PLAYER_VICIOUS) ? "&+L[&+WX&+L]&n Vicious &+L|&n &+cYou are vicious and will kill mortally wounded foes. &+L|&n\r\n" : "&+L[ ]&n Vicious &+L|&n &+cYou aren't vicious and will spare a mortally wounded foe. &+L|&n\r\n"); ch.SendText(ch.HasActionBit(PC.PLAYER_MAP) ? "&+L[&+WX&+L]&n Map &+L|&n &+cYou see the maps. &+L|&n\r\n" : "&+L[ ]&n Map &+L|&n &+cYou do not see maps. &+L|&n\r\n"); if (ch.HasActionBit(PC.PLAYER_SILENCE)) { ch.SendText( "&+L[&+WX&+L]&n Silence &+L|&n &+cYou are silenced. &+L|&n\r\n"); } ch.SendText(!ch.HasActionBit(PC.PLAYER_NO_EMOTE) ? "&n" : "&+L[ ]&n emote | &+cYou can't emote. &+L|&n\r\n"); ch.SendText("&+L+------------+------------------------------------------------------------+&n\r\n"); string termStr = "&+L|&n &+cYour terminal type is " + ch.Socket.Terminal + " and MCCP is " + ch.Socket.MCCPEnabled + "."; while (termStr.Length < 82) termStr += " "; termStr += "&+L|&n\r\n"; ch.SendText(termStr); ch.SendText("&+L+-------------------------------------------------------------------------+&n\r\n"); } else { string word; Bitvector bit; int fSet; if (str[0][0] == '-') { fSet = 0; word = str[0].Substring(1); } else if (str[0][0] == '+') { fSet = 1; word = str[0].Substring(1); } else { fSet = 2; word = str[0]; } if (("blank".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_BLANK; else if (("autowrap".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_AUTOWRAP; else if (("brief".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_BRIEF; else if (("casttick".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_CAST_TICK; else if (("combine".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_COMBINE; else if (("color".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) { if (ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText("You cannot turn color off when using the enhanced client.\r\n"); return; } bit = PC.PLAYER_COLOR; } else if (("colorcon".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_COLOR_CON; else if (("msp".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_MSP; else if (("pager".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_PAGER; else if (("shout".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_SHOUT; else if (("prompt".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_PROMPT; else if (("telnetga".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_TELNET_GA; else if (("tell".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_TELL; else if (("vicious".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_VICIOUS; else if (("map".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_MAP; else if (("vicious".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_VICIOUS; else if (("compact".StartsWith(word, StringComparison.CurrentCultureIgnoreCase))) bit = PC.PLAYER_BLANK; else if (word.Contains("wimpy")) { CommandType.Interpret(ch, "wimpy " + word.Substring((word.IndexOf("wimpy") + 5))); return; } else if ("mccp".StartsWith(word, StringComparison.CurrentCultureIgnoreCase)) { ch.Socket.MCCPEnabled = !ch.Socket.MCCPEnabled; if (ch.Socket.MCCPEnabled) { ch.SendText("MCCP is now enabled."); } else { ch.SendText("MCCP is now disabled."); } return; } else { ch.SendText("&nConfig which option?\r\n"); return; } if (ch.IsClass(CharClass.Names.paladin) && bit == PC.PLAYER_VICIOUS) { ch.SendText("Paladins may not toggle vicious.\r\n"); /* Just to make sure they don't have it toggled on. */ ch.RemoveActionBit(bit); return; } if (fSet == 1) { if (bit != PC.PLAYER_NONE) { ch.SetActionBit(bit); } ch.SendText( (String.Format("&n{0} is now ON.\r\n", word.ToUpper()))); } else if (fSet == 0) { if (bit != PC.PLAYER_NONE) { ch.RemoveActionBit(bit); } ch.SendText((String.Format("&n{0} is now OFF.\r\n", word.ToUpper()))); } else if (fSet == 2) { if (bit != PC.PLAYER_NONE) { ch.ToggleActionBit(bit); } if (ch.HasActionBit(bit)) ch.SendText((String.Format("&n{0} is now ON.\r\n", word.ToUpper()))); else ch.SendText((String.Format("&n{0} is now OFF.\r\n", word.ToUpper()))); } } return; }
/// <summary> /// Command to fall asleep. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Sleep(CharData ch, string[] str) { if( ch == null ) return; switch (ch.CurrentPosition) { case Position.sleeping: ch.SendText("You are already sleeping.\r\n"); break; case Position.reclining: case Position.sitting: case Position.kneeling: case Position.resting: case Position.standing: if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { ch.RemoveActionBit(PC.PLAYER_MEMORIZING); ch.SendText("You abandon your studies.\r\n"); } ch.SendText("You sleep.\r\n"); SocketConnection.Act("$n&n sleeps.", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.sleeping; break; case Position.fighting: ch.SendText("Not while you're fighting!\r\n"); break; } return; }
/// <summary> /// Command to stand up. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Stand(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("You're paralyzed!\r\n"); return; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { ch.RemoveActionBit(PC.PLAYER_MEMORIZING); ch.SendText("You abandon your studies.\r\n"); } switch (ch.CurrentPosition) { case Position.sleeping: if (ch.IsAffected( Affect.AFFECT_SLEEP)) { ch.SendText("You can't wake up!\r\n"); return; } ch.SendText("You wake and stand up.\r\n"); SocketConnection.Act("$n&n wakes and stands up.", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.standing; break; case Position.sitting: case Position.kneeling: case Position.reclining: case Position.resting: ch.SendText("You stand up.\r\n"); SocketConnection.Act("$n&n stands up.", ch, null, null, SocketConnection.MessageTarget.room); if (ch.Fighting) { ch.CurrentPosition = Position.fighting; } else { ch.CurrentPosition = Position.standing; } break; case Position.fighting: case Position.standing: ch.SendText("You are already standing.\r\n"); break; } return; }
/// <summary> /// Immortal command to paralyze a player. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Freeze(CharData ch, string[] str) { if( ch == null ) return; CharData victim; CharData realChar = ch.GetChar(); if (!realChar.Authorized("freeze")) { return; } if (str.Length == 0) { ch.SendText("Freeze whom?\r\n"); return; } if (!(victim = ch.GetCharWorld(str[0]))) { ch.SendText("They aren't here.\r\n"); return; } if (ch == victim && ch.HasActionBit(PC.PLAYER_FREEZE)) { ch.RemoveActionBit(PC.PLAYER_FREEZE); } if (victim.IsNPC()) { ch.SendText("Not on NPC's.\r\n"); return; } if (victim.GetTrust() >= ch.GetTrust()) { ch.SendText("You failed.\r\n"); return; } if (victim.HasActionBit(PC.PLAYER_FREEZE)) { victim.RemoveActionBit(PC.PLAYER_FREEZE); ch.SendText("FREEZE bit removed.\r\n"); victim.SendText("You can play again.\r\n"); } else { victim.SetActionBit(PC.PLAYER_FREEZE); ch.SendText("FREEZE bit set.\r\n"); victim.SendText("You can't do anything!\r\n"); } CharData.SavePlayer(victim); return; }
/// <summary> /// The main entry point for executing commands. /// Can be recursively called from 'at', 'order', 'force'. /// </summary> /// <param name="ch"></param> /// <param name="argument"></param> public static void Interpret(CharData ch, string argument) { // Get rid of leading and trailing spaces. argument = argument.Trim(); // Strip leading spaces. argument.Trim(); if (argument.Length == 0) { return; } // Remove AFK if (!ch.IsNPC()) { ch.RemoveActionBit(PC.PLAYER_AFK); } // Implement freeze command. if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_FREEZE)) { ch.SendText("You're totally frozen!\r\n"); return; } // Grab the command word. Special parsing so ' can be a command, // also no spaces needed after punctuation. string command; Object obj; Room room; int cmd; string logline = argument; int argptr = 0; if (!Char.IsLetter(argument[0]) && !Char.IsDigit(argument[0])) { command = argument.Substring(0, 1); argptr++; while (argument.Length > argptr && Char.IsWhiteSpace(argument[argptr])) { argument = argument.Remove(0, 1); } } else { command = MUDString.OneArgument(argument, ref argument); argument.Trim(); // Clean up the remainder of the command. } // Nothing to do if command is empty. Just send them a newline and bail. if (string.IsNullOrEmpty(command) && string.IsNullOrEmpty(argument)) { ch.SendText("\r\n"); return; } // Look for an item with a teleport trigger in the room. // and check to see if the command is a teleport trigger if (ch.InRoom && (obj = ch.GetObjHere(argument))) { if (obj.ItemType == ObjTemplate.ObjectType.teleport) { if (CheckCommandTrigger(command, obj.Values[1]) && obj.Values[2] != 0) { if (obj.Values[2] != -1) { obj.Values[2]--; } room = Room.GetRoom(obj.Values[0]); if (room) { SocketConnection.Act("$n&n vanishes suddenly.", ch, null, null, SocketConnection.MessageTarget.room); string text = String.Format("You {0} $p&n.\r\n", command); SocketConnection.Act(text, ch, obj, null, SocketConnection.MessageTarget.character); Log.Trace(String.Format("{0} activated keyword and was teleported by object.", ch.Name)); ch.RemoveFromRoom(); ch.AddToRoom(room); Interpret(ch, "look auto"); SocketConnection.Act("$n&n arrives suddenly.", ch, null, null, SocketConnection.MessageTarget.room); } else { ch.SendText("BUG: The target room for this teleporter does not exist.\r\n"); Log.Error("Target room for object {0} does not exist.", obj.ObjIndexData.IndexNumber); } return; } } else if (obj.ItemType == ObjTemplate.ObjectType.switch_trigger) { Exit exit; string cbuf = String.Format("Checking {0} against command no. {1} for {2}.", command, obj.Values[0], obj.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, cbuf); if (CheckCommandTrigger(command, obj.Values[0])) { ch.SendText("Click.\r\n"); room = Room.GetRoom(obj.Values[1]); if (!room) { Log.Error("Target room for switch object {0} does not exist.", obj.ObjIndexData.IndexNumber); return; } exit = room.ExitData[obj.Values[2]]; if (exit == null) { Log.Error("Target exit for switch object {0} does not exist.", obj.ObjIndexData.IndexNumber); return; } if (exit.HasFlag(Exit.ExitFlag.blocked)) { exit.RemoveFlag(Exit.ExitFlag.blocked); } return; } } } // Look for command in command table. bool found = false; int trust = ch.GetTrust(); for (cmd = 0; cmd < CommandTable.Length; cmd++) { if (CommandTable[cmd].Name.StartsWith(command, StringComparison.CurrentCultureIgnoreCase) && (CommandTable[cmd].MinLevel <= trust)) { found = true; break; } } // Command was found, respond accordingly. if (found) { // Logging and snooping. if (CommandTable[cmd].LoggingType == LogType.never) { logline = "---- Nothing to see here ----"; } if ((!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_LOG)) || fLogAll || CommandTable[cmd].LoggingType == LogType.always) { string logBuf = String.Format("Log {0}: {1}", ch.Name, logline); Log.Trace(logBuf); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_SECURE, ch.GetTrust(), logBuf); } if (ch.Socket && ch.Socket.SnoopBy) { ch.Socket.SnoopBy.WriteToBuffer("% "); ch.Socket.SnoopBy.WriteToBuffer(logline); ch.Socket.SnoopBy.WriteToBuffer("\r\n"); } // Break meditate if (CommandTable[cmd].BreakMeditate) { if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEDITATING)) { ch.RemoveActionBit(PC.PLAYER_MEDITATING); ch.SendText("You stop meditating.\r\n"); } } // Break sneak, hide, and invis // Anything that will break hide OR invis will break concealment // This is DUMB! Breaks invis w/backstab on a target that's not // there: i.e. "backstab trolll"/"backstab humann" . vis and no // attack! - (Should be handled with make_vis function). if (CommandTable[cmd].BreakInvisibility) { if (ch.IsAffected(Affect.AFFECT_INVISIBLE)) { ch.RemoveAffect(Affect.AFFECT_INVISIBLE); ch.RemoveAffect(Affect.AFFECT_HIDE); ch.RemoveAffect(Affect.AFFECT_MINOR_INVIS); SocketConnection.Act("$n&n snaps into visibility.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You snap into visibility.\r\n"); } else if (ch.IsAffected(Affect.AFFECT_MINOR_INVIS)) { ch.RemoveAffect(Affect.AFFECT_INVISIBLE); ch.RemoveAffect(Affect.AFFECT_HIDE); ch.RemoveAffect(Affect.AFFECT_MINOR_INVIS); ch.SendText("You appear.\r\n"); } } if (CommandTable[cmd].BreakHide) { if (ch.IsAffected(Affect.AFFECT_MINOR_INVIS)) { ch.SendText("You appear.\r\n"); } ch.AffectStrip( Affect.AffectType.skill, "shadow form"); ch.RemoveAffect( Affect.AFFECT_HIDE ); ch.RemoveAffect(Affect.AFFECT_MINOR_INVIS); } } // Command was not found, respond accordingly. else { // Look for command in socials table. if (!Database.SocialList.CheckSocial(ch, command, argument)) { if (!ch.IsNPC() && !MUDString.IsPrefixOf(command, "petition")) { string logBuf = String.Format("Log {0}: {1}", ch.Name, logline); Log.Trace(logBuf); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_SECURE, ch.GetTrust(), logBuf); Command.Petition(ch, argument.Split(' ')); return; } Log.Trace("Failed to match command."); ch.SendText("Huh?\r\n"); } return; } // Character not in position for command? if (ch.CurrentPosition < CommandTable[cmd].MinPosition) { switch (ch.CurrentPosition) { case Position.dead: ch.SendText("Lie still; you are &+rDEAD&n!\r\n"); break; case Position.mortally_wounded: case Position.incapacitated: ch.SendText("You are hurt far too bad for that.\r\n"); break; case Position.stunned: ch.SendText("You are too stunned to do that.\r\n"); break; case Position.sleeping: ch.SendText("In your dreams, or what?\r\n"); break; case Position.reclining: ch.SendText("You can't do that while lying around.\r\n"); break; case Position.sitting: ch.SendText("You can't do this sitting!\r\n"); break; case Position.kneeling: ch.SendText("Get off your knees!\r\n"); break; case Position.resting: ch.SendText("Nah... You feel too relaxed...\r\n"); break; case Position.fighting: ch.SendText("No way! You are still fighting!\r\n"); break; } if (!ch.IsImmortal()) { return; } if (ch.CurrentPosition == Position.dead) ch.CurrentPosition = Position.sleeping; ch.SendText("You're not in the right position, but..\r\n"); } if (ch.IsAffected(Affect.AFFECT_MINOR_PARA) && CommandTable[cmd].Function != Command.LookCommand && CommandTable[cmd].Function != Command.Score && CommandTable[cmd].Function != Command.Attributes) { if (!ch.IsImmortal()) { ch.SendText("&+YYour mind moves, but your body doesn't.&n\r\n"); return; } ch.SendText("&+YYour immortality allows you to move!&n\r\n"); } string[] str = argument.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); // Dispatch the command. Catch any exceptions, since most exceptions will probably happen // based on user commands. try { (CommandTable[cmd].Function)(ch, str); } catch (Exception ex) { Log.Error("Exception in CommandType.Interpret: " + ex); } return; }
// This code is basically a hack, and I'm adding a boatload of log // messages until I am satisfied that this code works and is stable. // When messing with code like this, it is easy to have players that // don't enter or leave the game completely, causing ghost images, // player duplicates, weird dangling pointers, etc., so we have to // be especially careful. If anyone happens upon this and has a // suggestion for how to handle anything better than I have it will // be greatly appreciated. public static void Quit(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; // If they're not an immortal, assume they want to rent or camp and be smart // enough to try renting first. if (!ch.IsImmortal()) { if (ch.InRoom != null && ch.InRoom.HasFlag(RoomTemplate.ROOM_INN)) { Rent(ch, str); return; } Camp(ch, str); return; } if (ch.CurrentPosition == Position.fighting || ch.Fighting) { if (ch.HasActionBit(PC.PLAYER_CAMPING)) { ch.SendText("You're not gifted enough to make camp and fight at the same time.\r\n"); ch.RemoveActionBit(PC.PLAYER_CAMPING); return; } ch.SendText("No way! You are fighting.\r\n"); return; } if (ch.CurrentPosition < Position.stunned) { if (MUDMath.NumberRange(1, 2) == 1) { ch.SendText("You're not &+RD&n&+rE&+RA&n&+rD&n yet.\r\n"); return; } ch.SendText("Just lie still and finish &+RBle&+reding&n!\r\n"); return; } SocketConnection.Quit(ch); }
/// <summary> /// Command to recline. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Recline(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA)) { ch.SendText("You're paralyzed!\r\n"); return; } switch (ch.CurrentPosition) { case Position.sleeping: ch.SendText("You are sleeping.\r\n"); break; case Position.reclining: ch.SendText("You are already reclining.\r\n"); break; case Position.fighting: ch.SendText("Not while you're fighting!\r\n"); break; case Position.sitting: case Position.kneeling: case Position.resting: case Position.standing: if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { ch.RemoveActionBit(PC.PLAYER_MEMORIZING); ch.SendText("You abandon your studies.\r\n"); } ch.SendText("You recline.\r\n"); SocketConnection.Act("$n&n reclines.", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.reclining; break; } return; }
/// <summary> /// Meditate command. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Meditate(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (!ch.HasSkill("meditate")) { ch.SendText("You don't know how to meditate.\r\n"); return; } if (ch.HasActionBit(PC.PLAYER_MEDITATING)) { ch.RemoveActionBit(PC.PLAYER_MEDITATING); ch.SendText("You stop meditating.\r\n"); } if (ch.CurrentPosition != Position.resting) { ch.SendText("You must be resting in order to meditate.\r\n"); return; } if (ch.Fighting != null) { ch.SendText("Meditation during battle leads to permenant inner peace.\r\n"); return; } ch.SetActionBit(PC.PLAYER_MEDITATING); ch.WaitState(Skill.SkillList["meditate"].Delay); ch.PracticeSkill("meditate"); ch.SendText("You start meditating...\r\n"); return; }
/// <summary> /// Command to set yourself as being away from keyboard. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void AFK(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (ch.HasActionBit(PC.PLAYER_AFK)) { ch.RemoveActionBit(PC.PLAYER_AFK); ch.SendText("&nYou are back at your keyboard.\r\n"); SocketConnection.Act("$n&n has returned to $s keyboard.", ch, null, ch, SocketConnection.MessageTarget.room); } else { ch.SetActionBit(PC.PLAYER_AFK); ch.SendText("&nYou are away from keyboard.\r\n"); SocketConnection.Act("$n&n has left $s keyboard.", ch, null, ch, SocketConnection.MessageTarget.room); } return; }
/// <summary> /// Immortal invisibility command. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Invis(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (!ch.Authorized("wizinvis")) return; if (ch.HasActionBit(PC.PLAYER_WIZINVIS)) { ch.RemoveActionBit(PC.PLAYER_WIZINVIS); ch.SendText("You slowly fade back into existence.\r\n"); SocketConnection.Act("$n slowly fades into existence.", ch, null, null, SocketConnection.MessageTarget.room); } else { ch.SendText("You slowly vanish into thin air.\r\n"); SocketConnection.Act("$n slowly fades into thin air.", ch, null, null, SocketConnection.MessageTarget.room); ch.SetActionBit(PC.PLAYER_WIZINVIS); } return; }
/// <summary> /// Called when a player quits or when camping preparations are complete. /// </summary> public static void Quit(CharData ch) { if (ch == null) { Log.Error("Quit: Called with null character."); return; } try { if (ch.HasActionBit(PC.PLAYER_CAMPING)) { ch.RemoveActionBit(PC.PLAYER_CAMPING); Act("You climb into your bedroll and leave the realm.", ch, null, null, MessageTarget.character); if (ch.Gender == MobTemplate.Sex.male) Act("$n&n climbs into his bedroll and leaves the realm.", ch, null, null, MessageTarget.room); else if (ch.Gender == MobTemplate.Sex.female) Act("$n&n climbs into her bedroll and leaves the realm.", ch, null, null, MessageTarget.room); else Act("$n&n climbs into its bedroll and leaves the realm.", ch, null, null, MessageTarget.room); string text = String.Format("{0} has camped out.", ch.Name); Log.Trace(text); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOGINS, ch.GetTrust(), text); } else { ch.SendText("You leave the realm.\r\n\r\n"); Act("$n&n has left the realm.", ch, null, null, MessageTarget.room); Log.Trace(String.Format("{0} has camped out.", ch.Name)); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOGINS, ch.GetTrust(), String.Format("{0} has camped out.", ch.Name)); } // I know we checked for position fighting, but I'm paranoid... if (ch.Fighting) { Combat.StopFighting(ch, true); } ch.DieFollower(ch.Name); Room room = null; if (ch.InRoom) { room = ch.InRoom; } ch.RemoveFromRoom(); if (room != null) { ch.InRoom = room; ((PC)ch).LastRentLocation = ch.InRoom.IndexNumber; } // Put them in the correct body if (ch && ch.Socket && ch.Socket.Original) { CommandType.Interpret(ch, "return"); } CharData.SavePlayer(ch); Database.CharList.Remove(ch); if (ch && ch.Socket) { ch.Socket.ShowScreen(Screen.MainMenuScreen); ch.Socket.ConnectionStatus = ConnectionState.menu; } } catch (Exception ex) { Log.Error("Error in SocketConnection.Quit: " + ex.ToString()); } return; }
/// <summary> /// Camping timer ticking away. /// /// Uses a single event for each person that is actively camping. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> /// <returns></returns> static bool CampUpdate( CharData ch, Room room ) { if( !ch || !room || ch.CurrentPosition <= Position.incapacitated ) return false; if( !ch.HasActionBit(PC.PLAYER_CAMPING ) ) return false; if( ch.CurrentPosition == Position.fighting || ch.Fighting || ch.InRoom != room ) { ch.SendText( "So much for that camping effort.\r\n" ); ch.RemoveActionBit(PC.PLAYER_CAMPING); return false; } return true; }
/// <summary> /// Used for dragging corpses into another room. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Drag(CharData ch, string[] str) { if( ch == null ) return; Object obj; Object obj2; if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA)) { ch.SendText("You can't move!\r\n"); return; } if (str.Length == 0) { ch.SendText("Drag which what where?\r\n"); return; } if (str.Length == 0) { ch.SendText("You need to specify a direction.\r\n"); return; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { ch.RemoveActionBit(PC.PLAYER_MEMORIZING); ch.SendText("You abandon your studies.\r\n"); } if (!(obj = ch.GetObjHere(str[0]))) { ch.SendText("You do not see that here.\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.npc_corpse && obj.ItemType != ObjTemplate.ObjectType.pc_corpse) { ch.SendText("You can only drag corpses.\r\n"); return; } if (str.Length > 2 && str[1] == "enter") { if ((obj2 = ch.GetObjHere(str[3]))) { switch (obj2.ItemType) { case ObjTemplate.ObjectType.teleport: case ObjTemplate.ObjectType.portal: if (obj2.ItemType == ObjTemplate.ObjectType.teleport && !CommandType.CheckCommandTrigger("enter", obj2.Values[1])) { ch.SendText("Nothing happens.\r\n"); return; }; Room location; if (Macros.IsSet(obj2.Values[3], ObjTemplate.PORTAL_RANDOM)) { location = Movement.GetRandomRoom(); } else { location = Room.GetRoom(obj2.Values[0]); } if (!location) { ch.SendText("That portal doesn't seem to go anywhere.\r\n"); return; } SocketConnection.Act("You drag the $p&n into $P&n.", ch, obj, obj2, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n drags the $p&n into $P&n.", ch, obj, obj2, SocketConnection.MessageTarget.room); if (obj2.Values[2] >= 0) { obj2.Values[2] -= 2; if (obj2.Values[2] <= 0) { SocketConnection.Act("$p&n fades into nothingness.", ch, obj2, null, SocketConnection.MessageTarget.room); obj2.RemoveFromRoom(); } } obj.RemoveFromRoom(); ch.RemoveFromRoom(); ch.AddToRoom(location); obj.AddToRoom(location); if (obj2.ItemType == ObjTemplate.ObjectType.portal) { SocketConnection.Act("$n&n steps out of $P&n dragging the $p&n.", ch, obj, obj2, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n&n appears from elsewhere, dragging the $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); } CommandType.Interpret(ch, "look auto"); return; case ObjTemplate.ObjectType.vehicle: case ObjTemplate.ObjectType.ship: break; case ObjTemplate.ObjectType.other: break; default: ch.SendText("That cannot be entered.\r\n"); return; } } } Exit.Direction door = Movement.FindExit(ch, str[1]); if (door < 0) { ch.SendText("You can't drag anything that way.\r\n"); return; } if (ch.CurrentMoves < 5 && !ch.IsImmortal()) { ch.SendText("You are too exhausted to drag that anywhere.\r\n"); return; } string text = String.Format("You drag $p&n {0}.", door.ToString()); SocketConnection.Act(text, ch, obj, null, SocketConnection.MessageTarget.character); text = String.Format("$n&n drags $p&n {0}.", door.ToString()); SocketConnection.Act(text, ch, obj, null, SocketConnection.MessageTarget.room); obj.RemoveFromRoom(); ch.CurrentMoves -= 5; ch.Move(door); ch.WaitState(MUDMath.NumberRange(3, 12)); obj.AddToRoom(ch.InRoom); SocketConnection.Act("$n&n drags $p&n along behind $m.", ch, obj, null, SocketConnection.MessageTarget.room); }
/// <summary> /// Leave the game at an inn. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Rent(CharData ch, string[] str) { if( ch == null ) return; Room room = null; CharData worldChar; if (ch.IsNPC()) return; if (!ch.InRoom || !ch.InRoom.HasFlag(Room.ROOM_INN)) { ch.SendText("You must be within an inn to rent.\r\n"); return; } if (ch.CurrentPosition == Position.fighting || ch.Fighting) { ch.SendText("No way! You are fighting.\r\n"); return; } if (ch.CurrentPosition < Position.stunned) { ch.SendText("You're not &+RD&n&+rE&+RA&n&+rD&n yet.\r\n"); return; } ch.SendText("The innkeeper grabs a &+Lkey&n from the &n&+yrack&n, and shows you to your room.\r\n\r\n"); SocketConnection.Act("$n&n has left the realm.", ch, null, null, SocketConnection.MessageTarget.room); Log.Trace(String.Format("{0} has rented.", ch.Name)); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOGINS, ch.GetTrust(), String.Format("{0} has rented.", ch.Name)); /* * After CharData.ExtractChar the ch is no longer valid * that is why we aren't extracting the character but rather * sending them to our version of the "menu". */ // I know we checked for position fighting, but I'm paranoid... if (ch.Fighting != null) { Combat.StopFighting(ch, true); } ch.DieFollower(ch.Name); // I can't see any reason why ch would not have an .in_room, but that // may just be shortsighted of me - Xangis if (ch.InRoom) { room = ch.InRoom; } ch.RemoveFromRoom(); if (room) { ch.InRoom = room; } // Put them in the correct body if (ch.Socket && ch.Socket.Original) { CommandType.Interpret(ch, "return"); } foreach (CharData it in Database.CharList) { worldChar = it; if (worldChar.ReplyTo == ch) { worldChar.ReplyTo = null; } } ch.RemoveActionBit(PC.PLAYER_CAMPING); ((PC)ch).LastRentLocation = ch.InRoom.IndexNumber; CharData.SavePlayer(ch); // Remove them from the character list. for( int i = Database.CharList.Count -1; i >= 0; --i ) { if (Database.CharList[i] == ch) { Database.CharList.RemoveAt(i); } } // ConnectionState.menu is when they enter // the game... this shows menu // before they enter the game ch.Socket.ShowScreen(Screen.MainMenuScreen); ch.Socket.ConnectionStatus = SocketConnection.ConnectionState.menu; return; }
/// <summary> /// Flee: Attempt to run away from combat. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Flee(CharData ch, string[] str) { if( ch == null ) return; int attempt; int chances; if (ch.CurrentPosition < Position.reclining || ch.Wait > 0) { return; } // Remove memorization and meditation bits - Xangis if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEDITATING)) { SocketConnection.Act("$N&n is disrupted from meditation.", ch, null, null, SocketConnection.MessageTarget.room); SocketConnection.Act("Your meditation is disrupted.", ch, null, null, SocketConnection.MessageTarget.character); ch.RemoveActionBit(PC.PLAYER_MEDITATING); } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { SocketConnection.Act("$N&n abandons $S studies.", ch, null, null, SocketConnection.MessageTarget.room); SocketConnection.Act("You abandon your studies.", ch, null, null, SocketConnection.MessageTarget.character); ch.RemoveActionBit(PC.PLAYER_MEMORIZING); } if (ch.CurrentPosition < Position.fighting) { ch.SendText("You scramble madly to your feet!\r\n"); SocketConnection.Act("$n&n scrambles madly to $s feet!", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.standing; return; } if (!ch.InRoom) { ch.SendText("You give up when you realize there's nowhere to flee to.\r\n"); } // Panicked people can flee when not fighting. CharData victim = ch.Fighting; if (!victim) { if (ch.CurrentPosition == Position.fighting) { ch.CurrentPosition = Position.standing; } } if (ch.IsAffected(Affect.AFFECT_BERZERK)) { ch.SendText("You can't flee, you're in a &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n!!\r\n"); return; } if (ch.IsAffected( Affect.AFFECT_BOUND)) { ch.SendText("You are bound! You can't move!\r\n"); SocketConnection.Act("$n&n tries to flee, but is tied up!", ch, null, null, SocketConnection.MessageTarget.room); return; } if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("You can't move!\r\n"); SocketConnection.Act("$n&n tries to flee, but $e can't move!", ch, null, null, SocketConnection.MessageTarget.room); return; } // You should almost always be able to flee when not fighting. if (ch.CurrentPosition == Position.standing) { chances = 30; } else { chances = 6; } Room wasIn = ch.InRoom; for (attempt = 0; attempt < chances; attempt++) { Exit exit; Exit.Direction door = Database.RandomDoor(); if ((exit = wasIn.GetExit(door)) == null || !exit.TargetRoom || exit.TargetRoom == wasIn || exit.HasFlag(Exit.ExitFlag.closed) || (ch.IsNPC() && (Room.GetRoom(exit.IndexNumber).HasFlag(RoomTemplate.ROOM_NO_MOB) || (ch.HasActionBit(MobTemplate.ACT_STAY_AREA) && exit.TargetRoom.Area != ch.InRoom.Area)))) { continue; } if (ch.Riding && ch.Riding.Fighting) { Combat.StopFighting(ch.Riding, true); } // Just to keep the damned messages from being wacky... ch.SetAffectBit(Affect.AFFECT_IS_FLEEING); ch.Move(door); ch.RemoveAffect(Affect.AFFECT_IS_FLEEING); if (ch.InRoom == wasIn) { break; } Room nowIn = ch.InRoom; ch.InRoom = wasIn; SocketConnection.Act("$n&n panics and attempts to flee...", ch, null, null, SocketConnection.MessageTarget.room, true); string text; if (ch.CheckSneak()) { SocketConnection.Act("$n&n has fled!", ch, null, null, SocketConnection.MessageTarget.room); } else { text = String.Format("$n&n flees {0}ward.", door.ToString()); SocketConnection.Act(text, ch, null, null, SocketConnection.MessageTarget.room, true); } ch.InRoom = nowIn; text = String.Format("You flee {0}ward!\r\n", door.ToString()); ch.SendText(text); Combat.StopFighting(ch, true); return; } SocketConnection.Act("$n&n tries to flee but can't make it out of here!", ch, null, null, SocketConnection.MessageTarget.room, true); ch.SendText("&+WYour escape is blocked!\r\n"); return; }
/// <summary> /// Used to flag a player as running or not running a bot. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Bot(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (ch.HasActionBit(PC.PLAYER_BOTTING)) { ch.RemoveActionBit(PC.PLAYER_BOTTING); ch.SendText("&nYou are no longer running a bot.\r\n"); SocketConnection.Act("$n&n's soul has returned to $s body.", ch, null, ch, SocketConnection.MessageTarget.room); } else { ch.SetActionBit(PC.PLAYER_BOTTING); ch.SendText("&nYou are now running a bot.\r\n"); SocketConnection.Act("$n&n's soul has left $s body.", ch, null, ch, SocketConnection.MessageTarget.room); } return; }
public static void GodMode(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (!ch.Authorized("godmode")) return; if (ch.HasActionBit(PC.PLAYER_GODMODE)) { ch.RemoveActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode off.\r\n"); } else { ch.SetActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode on.\r\n"); } return; }
/// <summary> /// The main social action processing routine. Sends the social strings and any associated sounds. /// </summary> /// <param name="ch">Character acting out the social.</param> /// <param name="command">Command entered by the character.</param> /// <param name="argument">Additional modifiers to the command entered.</param> /// <returns></returns> public bool CheckSocial(CharData ch, string command, string argument) { string arg = String.Empty; Social soc = FindSocial(command); if (soc == null) { return false; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_NO_EMOTE)) { ch.SendText("You are anti-social!\r\n"); return true; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEDITATING)) { ch.RemoveActionBit(PC.PLAYER_MEDITATING); ch.SendText("You stop meditating.\r\n"); } // Performing a social action removes hide and conceal. if (ch.IsAffected(Affect.AFFECT_MINOR_INVIS)) { ch.SendText("You appear.\r\n"); } ch.AffectStrip(Affect.AffectType.skill, "shadow form"); ch.AffectStrip(Affect.AffectType.spell, "concealment"); ch.RemoveAffect(Affect.AFFECT_MINOR_INVIS); ch.RemoveAffect(Affect.AFFECT_HIDE); switch (ch.CurrentPosition) { case Position.dead: ch.SendText("Lie still; you are DEAD.\r\n"); return true; case Position.incapacitated: case Position.mortally_wounded: ch.SendText("You are hurt far too badly for that.\r\n"); return true; case Position.stunned: ch.SendText("You are too stunned to do that.\r\n"); return true; case Position.sleeping: // Special exception - only social when you're using when asleep is "snore". if (!"snore".StartsWith(soc.Name, StringComparison.CurrentCultureIgnoreCase)) { break; } ch.SendText("In your dreams, or what?\r\n"); return true; } MUDString.OneArgument(argument, ref arg); CharData victim = null; if (arg.Length == 0) { SocketConnection.Act(soc.CharNoArgument, ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act(soc.OthersNoArgument, ch, null, victim, SocketConnection.MessageTarget.room); if (!String.IsNullOrEmpty(soc.AudioFile) && ch.InRoom != null) { foreach (CharData cd in ch.InRoom.People) { cd.SendSound(soc.AudioFile); } } return true; } victim = ch.GetCharWorld(arg); if (!victim || (ch.IsRacewar(victim) && ch.InRoom != victim.InRoom)) { ch.SendText("They aren't here.\r\n"); } else if (victim == ch) { SocketConnection.Act(soc.CharSelf, ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act(soc.OthersSelf, ch, null, victim, SocketConnection.MessageTarget.room); if (!String.IsNullOrEmpty(soc.AudioFile) && ch.InRoom != null) { foreach (CharData cd in ch.InRoom.People) { cd.SendSound(soc.AudioFile); } } } else if (!ch.GetCharRoom(arg) && CharData.CanSee(ch, victim) && soc.CharFound.Length > 0 && soc.VictimFound.Length > 0) { if (!ch.IsImmortal()) { ch.SendText("You don't see them here.\r\n"); return true; } if (!victim.IsNPC()) { const string ldbase = "From far away, "; if (victim.IsIgnoring(ch)) { ch.SendText("They are ignoring you.\r\n"); return false; } Room original = ch.InRoom; ch.RemoveFromRoom(); ch.AddToRoom(victim.InRoom); string ldmsg = ldbase; ldmsg += soc.CharFound; SocketConnection.Act(ldmsg, ch, null, victim, SocketConnection.MessageTarget.character); ldmsg = ldbase; ldmsg += soc.VictimFound; SocketConnection.Act(ldmsg, ch, null, victim, SocketConnection.MessageTarget.victim); if (!String.IsNullOrEmpty(soc.AudioFile) && ch.InRoom != null) { foreach (CharData cd in ch.InRoom.People) { cd.SendSound(soc.AudioFile); } } ch.RemoveFromRoom(); ch.AddToRoom(original); } else { ch.SendText("They aren't here.\r\n"); } } else { SocketConnection.Act(soc.CharFound, ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act(soc.VictimFound, ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act(soc.OthersFound, ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); if (!String.IsNullOrEmpty(soc.AudioFile) && ch.InRoom != null) { foreach (CharData cd in ch.InRoom.People) { cd.SendSound(soc.AudioFile); } } // If mobs are to respond to socials, it should be inserted here. // This might be useful for some quests, mob functions, or other things. } return true; }