/// <summary> /// Teleport to another location. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Goto(CharData ch, string[] str) { if( ch == null ) return; CharData realChar = ch.GetChar(); if (!realChar.Authorized("goto") || !ch.IsImmortal()) { return; } if (str.Length == 0) { ch.SendText("Goto where?\r\n"); return; } Room location = Room.FindLocation(ch, str[0]); if (!location) { ch.SendText("No such location.\r\n"); return; } if (location.IsPrivate()) { ch.SendText("That room is private right now.\r\n"); return; } if (ch.Fighting) { Combat.StopFighting(ch, true); } if (!ch.HasActionBit(PC.PLAYER_WIZINVIS)) { if (!ch.IsNPC() && ((PC)ch).ImmortalData.DisappearMessage.Length > 0) { SocketConnection.Act("$T", ch, null, ((PC)ch).ImmortalData.DisappearMessage, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n disappears in a puff of smoke.", ch, null, null, SocketConnection.MessageTarget.room); } } ch.RemoveFromRoom(); ch.AddToRoom(location); if (!ch.HasActionBit(PC.PLAYER_WIZINVIS)) { if (!ch.IsNPC() && ((PC)ch).ImmortalData.AppearMessage.Length > 0) { SocketConnection.Act("$T", ch, null, ((PC)ch).ImmortalData.AppearMessage, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n appears in a swirling mist", ch, null, null, SocketConnection.MessageTarget.room); } } CommandType.Interpret(ch, "look auto"); return; }
/// <summary> /// Tracking mob has found the person its after. Attack or react accordingly. /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> public static void FoundPrey( CharData ch, CharData victim ) { string victname = String.Empty; string text = String.Empty; string lbuf = String.Empty; if (!victim) { Log.Error("FoundPrey: null victim", 0); return; } if (!victim.InRoom) { Log.Error("FoundPrey: null victim._inRoom", 0); return; } ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, string.Format("{0}&n has found {1}.", ch.ShortDescription, victim.Name)); if (ch.IsAffected(Affect.AFFECT_TRACK)) { ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting(ch); return; } if (ch.IsAffected(Affect.AFFECT_JUSTICE_TRACKER)) { /* Give Justice the ability to ground flying culprits */ if (victim.FlightLevel != 0) { SocketConnection.Act("$n&n forces you to land!", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n forces $N&n to land!", ch, null, victim, SocketConnection.MessageTarget.room_vict); victim.FlightLevel = 0; } SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.room); SocketConnection.Act("$n&n chains you up.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n binds $N&n so $E can't move.", ch, null, victim, SocketConnection.MessageTarget.room); victim.SetAffectBit(Affect.AFFECT_BOUND); victim.RemoveFromRoom(); if (ch.InRoom.Area.JailRoom != 0) { victim.AddToRoom(Room.GetRoom(victim.InRoom.Area.JailRoom)); } else { victim.SendText("Justice is broken in this town - there is no jail and you're screwed.\r\n"); } Combat.StopHunting(ch); return; } victname = victim.IsNPC() ? victim.ShortDescription : victim.Name; if (ch.FlightLevel != victim.FlightLevel) { if (ch.CanFly()) { if (ch.FlightLevel < victim.FlightLevel && ch.FlightLevel < CharData.FlyLevel.high) { Command.Fly(ch, new string[] { "up" }); } else { Command.Fly(ch, new string[] { "down" }); } } else { SocketConnection.Act("$n peers around looking for something.", ch, null, null, SocketConnection.MessageTarget.room); } return; } if (!CharData.CanSee(ch, victim)) { if (MUDMath.NumberPercent() < 90) return; switch (MUDMath.NumberBits(5)) { case 0: text = String.Format("You can't hide forever, {0}!", victname); Command.Say(ch, new string[]{text}); break; case 1: SocketConnection.Act("$n&n sniffs around the room.", ch, null, victim, SocketConnection.MessageTarget.room); text = "I can smell your blood!"; Command.Say(ch, new string[]{text}); break; case 2: text = String.Format("I'm going to tear {0} apart!", victname); Command.Yell(ch, new string[]{text}); break; case 3: Command.Say(ch, new string[]{"Just wait until I find you..."}); break; default: SocketConnection.Act("$p peers about looking for something.", ch, null, null, SocketConnection.MessageTarget.room); break; } return; } if (ch.InRoom.HasFlag(RoomTemplate.ROOM_SAFE) && ch.IsNPC()) { text = String.Format("Hunting mob {0} found a safe room {1}.", ch.MobileTemplate.IndexNumber, ch.InRoom.IndexNumber); Log.Trace(text); return; } if (ch.CurrentPosition > Position.kneeling) { switch (MUDMath.NumberBits(5)) { case 0: text = String.Format("I will eat your heart, {0}!", victname); Command.Say(ch, new string[]{text}); break; case 1: text = String.Format("You want a piece of me, {0}?", victname); Command.Say(ch, new string[]{text}); break; case 2: text = String.Format("How does your flesh taste {0}, like chicken?", victname); Command.Say(ch, new string[]{text}); break; case 3: SocketConnection.Act("$n&n howls gleefully and lunges at $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n howls gleefully and lunges at you!", ch, null, victim, SocketConnection.MessageTarget.victim); break; case 4: SocketConnection.Act("$n&n charges headlong into $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n charges headlong into you!", ch, null, victim, SocketConnection.MessageTarget.victim); break; default: break; } Combat.StopHunting(ch); Combat.CheckAggressive(victim, ch); if (ch.Fighting) return; // Backstab if able, otherwise just kill them. // Kill if they don't have the skill or if they don't have a stabber. if (!ch.HasSkill("backstab")) { Combat.CombatRound(ch, victim, String.Empty); } else if (!Combat.Backstab(ch, victim)) { Combat.CombatRound(ch, victim, String.Empty); } } return; }
/// <summary> /// Enter a portal. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Enter(CharData ch, string[] str) { if( ch == null ) return; Room location; bool ship = false; if (str.Length == 0) { ch.SendText("Enter what?\r\n"); return; } if (ch.Fighting) { ch.SendText("Not while you're fighting!\r\n"); return; } Room original = ch.InRoom; Object portal = Object.GetObjFromList(ch.InRoom.Contents, ch, str[0]); if (!portal) { SocketConnection.Act("There is no $t in here.", ch, str[0], null, SocketConnection.MessageTarget.character); return; } if (portal.ItemType != ObjTemplate.ObjectType.portal) { if (portal.ItemType != ObjTemplate.ObjectType.ship && portal.ItemType != ObjTemplate.ObjectType.vehicle) { ch.SendText("That's not a portal.\r\n"); return; } ship = true; } if (!ship) { if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("That portal is closed.\r\n"); return; } if (portal.Values[2] == 0) { SocketConnection.Act("$p&n has no power left.", ch, portal, null, SocketConnection.MessageTarget.character); return; } if (!Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_NO_CURSED) && (ch.IsAffected( Affect.AFFECT_CURSE) )) { ch.SendText("Your deity has forsaken you.\r\n"); return; } location = Room.GetRoom(portal.Values[0]); if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_BUGGY) && MUDMath.NumberPercent() < 5) { location = Movement.GetRandomRoom(); } if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_RANDOM)) { location = Movement.GetRandomRoom(); portal.Values[0] = location.IndexNumber; } if (!location) { ch.SendText("The target room for this portal does not exist.\r\n"); return; } if (location == original) { SocketConnection.Act("$p&n doesn't seem to go anywhere.", ch, portal, null, SocketConnection.MessageTarget.character); return; } } else { location = Room.GetRoom(portal.Values[1]); if (!location) { ch.SendText("That boat is broken. You may not board it.\r\n"); return; } } if (location.IsPrivate()) { ch.SendText("There is no room for you on the other side.\r\n"); return; } if (!ship) { SocketConnection.Act("$n&n steps into $p&n.", ch, portal, null, SocketConnection.MessageTarget.room); if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_RANDOM) || Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_BUGGY)) { SocketConnection.Act("You walk through $p&n and find yourself somewhere else...", ch, portal, null, SocketConnection.MessageTarget.character); } else { SocketConnection.Act("You enter $p&n.", ch, portal, null, SocketConnection.MessageTarget.character); } } else { SocketConnection.Act("$n&n boards $p&n.", ch, portal, null, SocketConnection.MessageTarget.room); SocketConnection.Act("You board $p&n.", ch, portal, null, SocketConnection.MessageTarget.character); } ch.RemoveFromRoom(); ch.AddToRoom(location); if (!ship) { if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_RANDOM) || Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_BUGGY)) { SocketConnection.Act("$n&n has arrived from elsewhere.", ch, portal, null, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n&n steps out of $p&n.", ch, portal, null, SocketConnection.MessageTarget.room); } } else { SocketConnection.Act("$n&n has boarded.", ch, portal, null, SocketConnection.MessageTarget.room); } CommandType.Interpret(ch, "look auto"); if (!ship) { if (portal.Values[2] > 0) /* * This way i prevent an underflow */ portal.Values[2]--; if (portal.Values[2] == 0)/* * If there are no more charges; remove */ { SocketConnection.Act("$p&n fades out of existence.", ch, portal, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n fades out of existence.", ch, portal, null, SocketConnection.MessageTarget.room); portal.RemoveFromWorld(); return; } if (Macros.IsSet(portal.Values[3], ObjTemplate.PORTAL_GO_WITH)) { portal.RemoveFromRoom(); portal.AddToRoom(location); } } foreach (CharData follower in original.People) { if (!follower.IsAffected(Affect.AFFECT_CHARM) || follower.Master != ch) { continue; } if (follower.CurrentPosition < Position.standing) { CommandType.Interpret(ch, "stand"); } if (follower.CurrentPosition == Position.standing && follower.Wait == 0) { SocketConnection.Act("You follow $N&n.", follower, null, ch, SocketConnection.MessageTarget.character); Enter(follower, str); } } return; }
/// <summary> /// Command to fly in a particular direction. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Fly(CharData ch, string[] str) { if( ch == null ) return; Room troom; Exit texit; if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("&+cNot &+Wwhile &+cyou&+Wr fi&+cghting...&n\r\n"); return; } if (ch.Riding) { if (!ch.Riding.CanFly()) { ch.SendText("Your mount can't fly.\r\n"); return; } } if (str.Length == 0 && ch.CanFly()) { ch.SendText("Yep, you're flying. Maybe you want to fly up or fly down."); return; } if (str.Length == 0 && !ch.CanFly()) { ch.SendText("Alas you are landbound.\r\n"); return; } if (!MUDString.IsPrefixOf(str[0], "up")) { if (!ch.CanFly()) { ch.SendText("You cannot fly.\r\n"); return; } if (!ch.InRoom.IsFlyable()) { ch.SendText("You cannot fly here.\r\n"); return; } if (ch.InRoom.TerrainType == TerrainType.plane_of_air) { ch.SendText("That's not really an option here.\r\n"); return; } if (ch.FlightLevel < CharData.FlyLevel.high) { SocketConnection.Act("$n&n flies up higher.", ch, null, null, SocketConnection.MessageTarget.room); ch.FlightLevel++; SocketConnection.Act("$n&n flies in from below.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You fly up.\r\n"); CommandType.Interpret(ch, "look auto"); foreach (CharData follower in ch.InRoom.People) { if (follower == ch) { continue; } if (follower.Master == ch && follower.CanFly() && follower.FlightLevel == (ch.FlightLevel - 1) && follower.CurrentPosition == Position.standing && follower.CanMove()) { if (follower.FlightLevel < CharData.FlyLevel.high) { SocketConnection.Act("$n&n flies up.", follower, null, null, SocketConnection.MessageTarget.room); follower.FlightLevel++; follower.SendText("You fly up.\r\n"); SocketConnection.Act("$n&n flies in from below.", follower, null, null, SocketConnection.MessageTarget.room); } } } } else { // If in a zone then fly out. if (!ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP)) { int lower = ch.InRoom.Area.LowRoomIndexNumber; int higher = ch.InRoom.Area.HighRoomIndexNumber; int iroom; for (iroom = lower; iroom <= higher; iroom++) { troom = Room.GetRoom(iroom); if (!troom) continue; // Now check all exits. int i; for (i = 0; i < Limits.MAX_DIRECTION; i++) { texit = troom.ExitData[i]; if (!texit || !(texit.TargetRoom)) continue; if (texit.TargetRoom.Area.HasFlag(Area.AREA_WORLDMAP)) { // Found a way out. Should check for exit zone being flyable. ch.SendText("You fly up.\r\n"); SocketConnection.Act("$n&n flies up higher.", ch, null, null, SocketConnection.MessageTarget.room); ch.RemoveFromRoom(); ch.AddToRoom(Room.GetRoom(texit.IndexNumber)); ch.FlightLevel = CharData.FlyLevel.low; CommandType.Interpret(ch, "look auto"); return; } } } ch.SendText("You can't fly out of this zone.\r\n"); // Glitch or no exits to worldmap. } ch.SendText("If you were any higher you'd be Woody Harrelson.\r\n"); } } else if (!MUDString.IsPrefixOf(str[0], "down")) { if (ch.FlightLevel > 0) { SocketConnection.Act("$n&n flies down lower.", ch, null, null, SocketConnection.MessageTarget.room); ch.FlightLevel--; SocketConnection.Act("$n&n flies in from above.", ch, null, null, SocketConnection.MessageTarget.room); if (ch.FlightLevel == 0) { ch.SendText("You fly down to the ground.\r\n"); } else { ch.SendText("You fly down.\r\n"); } CommandType.Interpret(ch, "look auto"); foreach (CharData follower in ch.InRoom.People) { if (follower == ch) { continue; } if (follower.Master == ch && follower.CanFly() && follower.CurrentPosition == Position.standing && follower.CanMove()) { SocketConnection.Act("$n&n flies down.", follower, null, null, SocketConnection.MessageTarget.room); follower.FlightLevel--; follower.SendText("You fly down.\r\n"); SocketConnection.Act("$n&n flies in from above.", follower, null, null, SocketConnection.MessageTarget.room); } } } else { ch.SendText("You're already on the ground.\r\n"); } } else if (!MUDString.IsPrefixOf(str[0], "land")) { if (ch.FlightLevel > 0) { SocketConnection.Act("$n&n flies down lower.", ch, null, null, SocketConnection.MessageTarget.room); for (; ch.FlightLevel > 0; ch.FlightLevel--) { SocketConnection.Act("$n&n flies down lower.", ch, null, null, SocketConnection.MessageTarget.room); } ch.FlightLevel = 0; SocketConnection.Act("$n&n flies in from above.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You fly down to the ground.\r\n"); CommandType.Interpret(ch, "look auto"); foreach (CharData follower in ch.InRoom.People) { if (follower == ch) { continue; } if (follower.Master == ch && follower.CanFly() && follower.FlightLevel == (ch.FlightLevel + 1) && follower.CurrentPosition == Position.standing && follower.CanMove()) { for (; follower.FlightLevel > 0; follower.FlightLevel--) { SocketConnection.Act("$n&n flies down lower.", follower, null, null, SocketConnection.MessageTarget.room); } follower.FlightLevel = 0; follower.SendText("You fly down to the ground.\r\n"); SocketConnection.Act("$n&n flies in from above.", follower, null, null, SocketConnection.MessageTarget.room); } } } else { ch.SendText("You're already on the ground.\r\n"); } } else { ch.SendText("Fly where?\r\n"); } return; }
/// <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> /// Perform a command at another location. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void At(CharData ch, string[] str) { if( ch == null ) return; CharData realChar = ch.GetChar(); if (!realChar.Authorized("at")) { return; } if (str.Length < 2) { ch.SendText("At where what?\r\n"); return; } Room location = Room.FindLocation(ch, str[0]); if (!location) { ch.SendText("No such location.\r\n"); return; } if (location.IsPrivate()) { ch.SendText("That room is private right now.\r\n"); return; } Room original = ch.InRoom; ch.RemoveFromRoom(); ch.AddToRoom(location); string text = String.Join(" ", str, 1, (str.Length - 1)); CommandType.Interpret(ch, text); /* * See if 'ch' still exists before continuing! * Handles 'at XXXX quit' case. */ foreach (CharData worldChar in Database.CharList) { if (worldChar == ch) { ch.RemoveFromRoom(); ch.AddToRoom(original); break; } } return; }
public static void LookOut(CharData ch, string[] str) { if( ch == null ) return; Vehicle vehicle; if (ch.InRoom == null) return; foreach (Vehicle it in Database.VehicleList) { vehicle = it; if (vehicle.ParentObject == null) continue; if (ch.InRoom.IndexNumber == vehicle.EntryRoomTemplateNumber) { if (vehicle.ParentObject.InRoom) { // Copied from farsee code - Xangis Room room = ch.InRoom; ch.RemoveFromRoom(); ch.AddToRoom(vehicle.ParentObject.InRoom); CommandType.Interpret(ch, "look"); ch.RemoveFromRoom(); ch.AddToRoom(room); return; } } } ch.SendText("You do not see that here.\r\n"); 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; }
/// <summary> /// Used with AFK folks -- resets a player's idle timer and displays a string /// saying that they are back at keys. /// </summary> /// <param name="ch"></param> private static void StopIdling( CharData ch ) { if (!ch || !ch.Socket || ch.Socket.ConnectionStatus != ConnectionState.playing || !ch.WasInRoom || ch.InRoom != Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO"))) { return; } ch.Timer = 0; ch.RemoveFromRoom(); ch.AddToRoom( ch.WasInRoom ); ch.WasInRoom = null; Act( "$n&+L has returned from the &+RA&n&+rb&+Rys&n&+rs&+L.&n", ch, null, null, MessageTarget.room ); return; }
/// <summary> /// Looks at an object, mobile, or room. /// </summary> /// <param name="ch">The acting character.</param> /// <param name="str">Command arguments.</param> public static void LookCommand(CharData ch, string[] str) { if( ch == null ) return; // Build argument list, stripping articles. bool inside = false; List<String> args = new List<string>(str); for (int i = (args.Count - 1); i >= 0; i-- ) { if (args[i].Equals("in", StringComparison.CurrentCultureIgnoreCase) || args[i].Equals("i", StringComparison.CurrentCultureIgnoreCase)) { args.RemoveAt(i); inside = true; } else if (args[i].Equals("at", StringComparison.CurrentCultureIgnoreCase)) { args.RemoveAt(i); } } // If it's a mob that isn't switched, bail. if (ch.Socket == null) return; if (ch.CurrentPosition < Position.sleeping) { ch.SendText("&nYou can't see anything but &+Ystars&n! See how pretty!\r\n"); return; } if (ch.CurrentPosition == Position.sleeping) { ch.SendText("&nYou can't see anything, you're &+Lsleeping&n! Zzz.\r\n"); return; } if (ch.IsBlind()) return; // Look panel for ships. if ( args.Count > 0 && args[0].Equals("panel", StringComparison.CurrentCultureIgnoreCase)) { CommandType.Interpret(ch, "Lookpanel"); return; } // Look out for ships. if (args.Count > 0 && args[0].Equals("out", StringComparison.CurrentCultureIgnoreCase)) { CommandType.Interpret(ch, "Lookout"); return; } Object obj; Exit exit; string pdesc; int number = 0; string output = String.Empty; // 'look' or 'look auto' or 'look room' if (args.Count == 0 || args[0].Equals( "auto", StringComparison.CurrentCultureIgnoreCase) || args[0].Equals("room", StringComparison.CurrentCultureIgnoreCase)) { if (ch.InRoom == null) { ch.SendText("You are not in a room. You are just floating in empty space. This should never happen. You should <petition> someone for help.\r\n"); Log.Error("Character executing Commandlook command from null room: " + ch.Name); return; } if (ch.FlightLevel > 0) { switch (ch.FlightLevel) { case CharData.FlyLevel.low: ch.SendText("Hovering above "); break; case CharData.FlyLevel.medium: ch.SendText("Flying above "); break; case CharData.FlyLevel.high: ch.SendText("Flying high above "); break; } } if (!ch.HasActionBit(PC.PLAYER_GODMODE) && ch.InRoom.IsDark() && !ch.HasInnate(Race.RACE_ULTRAVISION) && !ch.IsAffected( Affect.AFFECT_ULTRAVISION)) { ch.SendText("&+lSomewhere\r\n"); } else if (!ch.HasActionBit(PC.PLAYER_GODMODE)) { String roomOpen = String.Empty; String roomClose = String.Empty; if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { roomOpen = "<zone>" + ch.InRoom.Area.Name + "</zone><roomTitle>"; roomClose = "</roomTitle>"; } else { roomClose = "&n\r\n"; } // Added support for both manual and automatic descriptions on the worldmap. if (!ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP) || ch.InRoom.Title.Length > 1) { output += roomOpen + ch.InRoom.Title + roomClose; } else { output += roomOpen + "No room title." + roomClose; } } else { if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText("<zone>" + ch.InRoom.Area.Name + "</zone>"); } Look.ShowRoomInfo(ch, ch.InRoom); } if (!ch.IsNPC() && !ch.HasActionBit(PC.PLAYER_GODMODE) && ch.InRoom.IsDark() && !ch.HasInnate(Race.RACE_ULTRAVISION) && !ch.IsAffected( Affect.AFFECT_ULTRAVISION)) { ch.SendText("&+LIt is pitch black...&n \r\n"); Look.ShowCharacterToCharacter(ch.InRoom.People, ch); return; } if (!ch.IsNPC() && (args.Count > 0 && (args[0].Equals("room", StringComparison.CurrentCultureIgnoreCase) || args[0].Equals("auto", StringComparison.CurrentCultureIgnoreCase)))) { String roomDescOpen = String.Empty; String roomDescClose = String.Empty; String mapSpace = String.Empty; if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { roomDescOpen = "<roomDescription>"; roomDescClose = "</roomDescription>"; } else { roomDescClose = "&n\r\n"; mapSpace = " "; } if( !ch.HasActionBit(PC.PLAYER_BRIEF) && !ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP)) { // Added support for both manual and automatic descriptions on the worldmap. if (ch.InRoom.Description.Length > 0) { output += roomDescOpen + " " + (ch.InRoom.Description.Trim()) + roomDescClose; } //else if (ch._inRoom.WorldmapTerrainType < Database.SystemData.MapInfo.Length) // output += roomDescOpen + mapSpace + Database.SystemData.MapInfo[ch._inRoom.WorldmapTerrainType].RoomDescription + roomDescClose; else { output += roomDescOpen + " No room description." + roomDescClose; } } } if (!String.IsNullOrEmpty(output)) { ch.SendText(output); } if (ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP)) { if (ch.HasActionBit(PC.PLAYER_MAP)) { Command.Worldmap(ch, null); } else if (!ch.IsNPC() && ch.Socket.Terminal != SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText("\r\n"); } } if (ch.InRoom.HasFlag(RoomTemplate.ROOM_SILENT)) { ch.SendText("&nIt seems preternaturally quiet.\r\n"); } CommandType.Interpret(ch, "exits auto"); Look.ShowRoomAffects(ch, ch.InRoom); Look.ShowListToCharacter(ch.InRoom.Contents, ch, false, false); Look.ShowCharacterToCharacter(ch.InRoom.People, ch); return; } // 'look direction' int door = -1; if (args.Count > 0) { if ("north".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 0; else if ("east".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 1; else if ("south".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 2; else if ("west".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 3; else if ("up".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 4; else if ("down".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 5; else if ("northwest".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 6; else if ("southwest".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 7; else if ("northeast".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 8; else if ("southeast".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 9; else if ("nw".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 6; else if ("sw".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 7; else if ("ne".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 8; else if ("se".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase)) door = 9; } if (door != -1) { // If no exit data, then return. exit = ch.InRoom.ExitData[door]; if (!exit) { ch.SendText("There's nothing to see in that direction.\r\n"); return; } if (exit.HasFlag(Exit.ExitFlag.walled)) { ch.SendText("There's a wall in the way.\r\n"); return; } // Check for farsee if ((ch.IsAffected( Affect.AFFECT_FARSEE) || ch.HasActionBit(PC.PLAYER_GODMODE)) && !exit.HasFlag(Exit.ExitFlag.closed)) { if (exit.TargetRoom) { Room room = ch.InRoom; ch.RemoveFromRoom(); ch.AddToRoom(Room.GetRoom(exit.IndexNumber)); CommandType.Interpret(ch, "look"); ch.RemoveFromRoom(); ch.AddToRoom(room); return; } ch.SendText("Nothing special there.\r\n"); } if (exit.Description.Length != 0) { ch.SendText(exit.Description); } else { ch.SendText("Nothing special there.\r\n"); } if (exit.Keyword.Length != 0) { if (exit.HasFlag(Exit.ExitFlag.bashed)) SocketConnection.Act("The $d has been bashed from its &n&+whinges&n.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.closed)) SocketConnection.Act("The $d is closed.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.secret)) SocketConnection.Act("The $d is secret.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.blocked)) SocketConnection.Act("The $d is blocked.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); } else { if (exit.HasFlag(Exit.ExitFlag.bashed)) { SocketConnection.Act("The door has been bashed from its &n&+whinges&n.", ch, null, null, SocketConnection.MessageTarget.character); } else if (exit.HasFlag(Exit.ExitFlag.closed)) SocketConnection.Act("The door is closed.", ch, null, null, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.is_door)) SocketConnection.Act("The door is open.", ch, null, null, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.secret)) SocketConnection.Act("The door is secret.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); else if (exit.HasFlag(Exit.ExitFlag.blocked)) SocketConnection.Act("The $d is blocked.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); } // If exit found, don't keep looking. return; } // Look inside something ('look in'). if (inside) { // 'look in' if (args.Count < 1) { ch.SendText("Look in what?\r\n"); return; } obj = ch.GetObjHere(args[0]); if (!obj) { ch.SendText("You do not see that here.\r\n"); return; } switch (obj.ItemType) { default: ch.SendText("That is not a container.\r\n"); break; case ObjTemplate.ObjectType.drink_container: if (obj.Values[1] == -1) { ch.SendText("It is full.\r\n"); break; } if (obj.Values[1] <= 0) { ch.SendText("It is empty.\r\n"); break; } output += "It's "; if (obj.Values[1] < obj.Values[0] / 4) output += "less than half"; else if (obj.Values[1] < (3 * obj.Values[0] / 4)) output += "about half"; else if (obj.Values[1] < obj.Values[0]) output += "more than half"; else output += "completely"; output += " full of a " + Liquid.Table[obj.Values[2]].Color + "liquid.\r\n"; ch.SendText(output); break; case ObjTemplate.ObjectType.quiver: case ObjTemplate.ObjectType.container: case ObjTemplate.ObjectType.npc_corpse: case ObjTemplate.ObjectType.pc_corpse: if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It is closed.\r\n"); break; } SocketConnection.Act("$p&n contains:", ch, obj, null, SocketConnection.MessageTarget.character, true); Look.ShowListToCharacter(obj.Contains, ch, true, true); break; case ObjTemplate.ObjectType.portal: SocketConnection.Act("A $p&n leads to:", ch, obj, null, SocketConnection.MessageTarget.character); output += Room.GetRoom(obj.Values[0]).Title + "\r\n"; output += Room.GetRoom(obj.Values[0]).Description; output += "\r\n"; ch.SendText(output); break; } return; } // Look at another char. if (args.Count > 0) { CharData victim = ch.GetCharRoom(args[0]); if (victim != null) { Look.ShowCharacterToCharacterFull(victim, ch); return; } } // Look at an object. if (args.Count > 0) { // Check inventory. obj = ch.GetObjCarrying(args[0]); // If not in inventory, check eq. if (obj == null) obj = ch.GetObjWear(args[0]); // If not on character, check room. if (obj == null) obj = Object.GetObjFromList(ch.InRoom.Contents, ch, args[0]); // If object found, show it to the char. if (obj != null) { pdesc = (Database.GetExtraDescription(args[0], obj.ExtraDescription)); if (pdesc.Length != 0) { ch.SendText(pdesc); } else if ((pdesc = (Database.GetExtraDescription(args[0], obj.ObjIndexData.ExtraDescriptions))).Length > 0) { ch.SendText(pdesc); } else if (obj.FullDescription.Length > 0) { ch.SendText(obj.FullDescription); ch.SendText("\r\n"); } if (obj.HasAffect(Affect.AffectType.skill, "poison weapon")) { if (ch.IsClass(CharClass.Names.thief) || ch.IsClass(CharClass.Names.assassin) || MUDMath.NumberPercent() < ch.GetCurrInt() / 2) ch.SendText("It has a &+Gsickly &+Lcolored&n hue.\r\n"); } return; } } // Look at an object in the room if (args.Count > 0) { int count = 0; foreach (Object iobj in ch.InRoom.Contents) { if (CharData.CanSeeObj(ch, iobj)) { pdesc = (Database.GetExtraDescription(args[0], iobj.ExtraDescription)); if (pdesc.Length != 0) { if (++count == number) { ch.SendText(pdesc); return; } continue; } pdesc = (Database.GetExtraDescription(args[0], iobj.ObjIndexData.ExtraDescriptions)); if (pdesc.Length != 0) { if (++count == number) { ch.SendText(pdesc); return; } continue; } if (MUDString.NameContainedIn(args[0], iobj.Name)) { if (++count == number) { ch.SendText(iobj.FullDescription); ch.SendText("\r\n"); return; } continue; } } } } // Check for room extra descriptions if (args.Count > 0) { pdesc = (Database.GetExtraDescription(args[0], ch.InRoom.ExtraDescriptions)); if (!String.IsNullOrEmpty(pdesc)) { ch.SendText(pdesc); return; } } ch.SendText("You do not see that here.\r\n"); return; }
/// <summary> /// Extracts a character from the world. If delete is true, it then deletes that character. /// </summary> /// <param name="ch"></param> /// <param name="delete"></param> public static void ExtractChar( CharData ch, bool delete ) { if( ch == null ) { Log.Error( "ExtractChar: null ch.", 0 ); return; } try { if (ch.Fighting) { Combat.StopFighting(ch, true); } Magic.ForgetAllSpells(ch); Event.DeleteAttachedEvents(ch); // Remove any affects we want to be gone next time they log in. ch.RemoveAffect(Affect.AFFECT_CASTING); ch.RemoveAffect(Affect.AFFECT_SINGING); // Meaning they're dead for good or have left the game. if (delete) { string name; if (ch.IsNPC()) { name = ch.ShortDescription; } else { name = ch.Name; } ch.DieFollower(name); if (ch.GroupLeader || ch.NextInGroup) { ch.RemoveFromGroup(ch); } /* Get rid of weapons _first_ */ { Object obj3 = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one); Object obj2 = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two); if (obj3 != null) { obj3.RemoveFromWorld(); } /* Now kill obj2 if it exists no matter if on body or floor */ if (obj2) { obj2.RemoveFromWorld(); } } for (int i = ch.Carrying.Count - 1; i >= 0; --i) { ch.Carrying[i].RemoveFromWorld(); } } CharData worldChar; for (int xx = Database.CharList.Count - 1; xx >= 0; xx--) { worldChar = Database.CharList[xx]; if (worldChar.ReplyTo == ch) { worldChar.ReplyTo = null; } if (worldChar.IsConsenting(ch)) { worldChar.StopConsenting(ch); SocketConnection.Act("You stop consenting $N&n.", worldChar, null, ch, SocketConnection.MessageTarget.character); } if (worldChar.IsIgnoring(ch)) { worldChar.StopIgnoring(ch); SocketConnection.Act("You stop ignoring $N&n.", worldChar, null, ch, SocketConnection.MessageTarget.character); } if (!worldChar.IsNPC() && ((PC)worldChar).Guarding == ch) { ((PC)worldChar).Guarding = null; SocketConnection.Act("You stop guarding $N&n.", worldChar, null, ch, SocketConnection.MessageTarget.character); } if (worldChar.IsHating(ch)) worldChar.StopHating(ch); if (worldChar.Hunting && worldChar.Hunting.Who == ch) Combat.StopHunting(worldChar); if (worldChar.Fearing && worldChar.Fearing.Who == ch) Combat.StopFearing(worldChar); // Remove from the active character list. // BUG: TODO: FIXME: This invalidates the list for anyone iterating through // a list that may kill characters, such as violence_update. // it = CharList.erase( it ); } if (ch.InRoom) { // This was placed *after* the act strings to be safe. for (int iwch = ch.InRoom.People.Count - 1; iwch >= 0; iwch--) { if (ch.InRoom.People[iwch] == ch) { ch.RemoveFromRoom(); break; } } } // They're not being yanked from game, probably just dead and going to the menu. if (!delete) { Room location; if (ch.Level < 5 || Macros.IsSet((int)Database.SystemData.ActFlags, (int)Sysdata.MudFlags.alwaysequip)) ch.ReceiveNewbieEquipment(); if (!ch.IsNPC() && (ch.GetOrigRace() < Limits.MAX_PC_RACE) && ((int)ch.CharacterClass.ClassNumber < CharClass.ClassList.Length)) { // Get the default respawn location based on currhome, then race/class default. location = Room.GetRoom(((PC)ch).CurrentHome); if (location == null) { int place; List<RepopulationPoint> repoplist = ch.GetAvailableRepops(); if (repoplist.Count < 1) { place = StaticRooms.GetRoomNumber("ROOM_NUMBER_START"); } else { place = repoplist[0].RoomIndexNumber; } location = Room.GetRoom(place); if (location == null) { Log.Error("Starting room does not exist for class {0} of player's race! Calling ch.AddToRoom() for altar.", (int)ch.CharacterClass.ClassNumber); ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_ALTAR"))); } } else { ch.AddToRoom(location); } } else { location = Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_START")); if (location == null) { Log.Error("Starting room {0} does not exist! Calling char_to_room for altar.", StaticRooms.GetRoomNumber("ROOM_NUMBER_START")); ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_ALTAR"))); } else { ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_START"))); } } return; } // Clear modifiers. if (ch.IsNPC()) { --ch.MobileTemplate.NumActive; } else { ((PC)ch).Hunger = 48; ((PC)ch).Thirst = 48; ((PC)ch).Drunk = 0; ((PC)ch).LastRentLocation = 0; ch.ArmorPoints = 100; ch.CurrentPosition = Position.standing; ch.Hitpoints = Math.Max(1, ch.Hitpoints); ch.CurrentMana = Math.Max(1, ch.CurrentMana); ch.CurrentMoves = Math.Max(1, ch.CurrentMoves); ((PC)ch).HitpointModifier = 0; ch.Hitroll = 0; ch.Damroll = 0; ch.SavingThrows[0] = 0; ch.SavingThrows[1] = 0; ch.SavingThrows[2] = 0; ch.SavingThrows[3] = 0; ch.SavingThrows[4] = 0; ch.ModifiedStrength = 0; ch.ModifiedIntelligence = 0; ch.ModifiedWisdom = 0; ch.ModifiedDexterity = 0; ch.ModifiedConstitution = 0; ch.ModifiedAgility = 0; ch.ModifiedCharisma = 0; ch.ModifiedPower = 0; ch.ModifiedLuck = 0; ((PC)ch).MaxStrMod = 0; ((PC)ch).MaxIntMod = 0; ((PC)ch).MaxWisMod = 0; ((PC)ch).MaxDexMod = 0; ((PC)ch).MaxConMod = 0; ((PC)ch).MaxAgiMod = 0; ((PC)ch).MaxChaMod = 0; ((PC)ch).MaxPowMod = 0; ((PC)ch).MaxLukMod = 0; } if (ch.Socket && ch.Socket.Original) { CommandType.Interpret(ch, "return"); } ch.DeleteMe = true; } catch (Exception ex) { Log.Error("Exception in ExtractChar: " + ex.ToString()); } return; }
/// <summary> /// Creates a character based on an object. Used for animate-object-type spells. /// </summary> /// <param name="obj"></param> /// <returns></returns> public CharData CreateCharacterFromObject( ref Object obj ) { int count; MobTemplate mobTemplate = Database.GetMobTemplate( StaticMobs.MOB_NUMBER_OBJECT ); if( !mobTemplate ) { Log.Error( "CreateCharacterFromObject: null object template.", 0 ); return null; } CharData mob = new CharData(); mob.MobileTemplate = mobTemplate; mob.Name = obj._name; mob.ShortDescription = obj._shortDescription; mob.FullDescription = obj._fullDescription; mob.Description = obj._fullDescription; mob.CharacterClass = mobTemplate.CharacterClass; mob.Level = Math.Max( obj._level, 1 ); mob.ActionFlags = mobTemplate.ActionFlags; mob.CurrentPosition = mobTemplate.DefaultPosition; for( count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count ) { mob.AffectedBy[ count ] = mobTemplate.AffectedBy[ count ]; } mob.Alignment = mobTemplate.Alignment; mob.Gender = mobTemplate.Gender; mob.SetPermRace( mobTemplate.Race ); mob.CurrentSize = Race.RaceList[ mob.GetRace() ].DefaultSize; if (mob.HasActionBit(MobTemplate.ACT_SIZEMINUS)) mob.CurrentSize--; if (mob.HasActionBit(MobTemplate.ACT_SIZEPLUS)) mob.CurrentSize++; mob.CastingSpell = 0; mob.CastingTime = 0; mob.PermStrength = 55; mob.PermIntelligence = 55; mob.PermWisdom = 55; mob.PermDexterity = 55; mob.PermConstitution = 55; mob.PermAgility = 55; mob.PermCharisma = 55; mob.PermPower = 55; mob.PermLuck = 55; mob.ModifiedStrength = 0; mob.ModifiedIntelligence = 0; mob.ModifiedWisdom = 0; mob.ModifiedDexterity = 0; mob.ModifiedConstitution = 0; mob.ModifiedAgility = 0; mob.ModifiedCharisma = 0; mob.ModifiedPower = 0; mob.ModifiedLuck = 0; mob.Resistant = mobTemplate.Resistant; mob.Immune = mobTemplate.Immune; mob.Susceptible = mobTemplate.Susceptible; mob.Vulnerable = mobTemplate.Vulnerable; mob.SetCoins( 0, 0, 0, 0 ); mob.ArmorPoints = MUDMath.Interpolate( mob.Level, 100, -100 ); // * MOB HITPOINTS * // // Was level d 8, upped it to level d 13 // considering mobs *still* won't have as many hitpoints as some players until // at least lvl 10, this shouldn't be too big an upgrade. // // Mob hitpoints are not based on constitution *unless* they have a // constitution modifier from an item, spell, or other affect mob.MaxHitpoints = mob.Level * 100; mob.Hitpoints = mob.GetMaxHit(); /* * Insert in list. */ Database.CharList.Add( mob ); // Increment in-game count of mob. mobTemplate.NumActive++; mob.AddToRoom( obj._inRoom ); return mob; }
/// <summary> /// Check for falling. Called from room update and movement. /// </summary> /// <param name="room"></param> /// <param name="target"></param> /// <param name="ch"></param> public static void CheckFall( Room room, Room target, CharData ch ) { int chance; if( !room || !target || !ch ) return; if( room.TerrainType != TerrainType.air && room.TerrainType != TerrainType.plane_of_air && room.TerrainType != TerrainType.underground_no_ground ) { if( MUDMath.NumberPercent() > room.FallChance ) return; } if( ch.CanFly() || ch.IsAffected( Affect.AFFECT_LEVITATE ) ) return; if( ch.InRoom.People != null ) { SocketConnection.Act( "You are falling down!", ch, null, null, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n falls away.", ch, null, null, SocketConnection.MessageTarget.room ); } ch.RemoveFromRoom(); ch.AddToRoom( target ); if( !ch.HasSkill( "safe_fall" ) ) chance = 0; else if( ch.IsNPC() ) chance = ( ( ch.Level * 3 ) / 2 ) + 15; else chance = ( (PC)ch ).SkillAptitude[ "safe fall" ]; // People with high agility have a small chance to safe fall, and those with // the skill already get a bonus. chance += ( ch.GetCurrAgi() / 20 ); // Minimum 1% chance of a bad fall. if( chance > 99 ) { chance = 99; } // Safe fall added by Xangis if( target.FallChance == 0 || !target.ExitData[ 5 ] || !target.ExitData[ 5 ].TargetRoom ) { if( MUDMath.NumberPercent() < chance ) { // Decent chance of skill increase - people don't fall very often. ch.PracticeSkill( "safe fall" ); ch.PracticeSkill( "safe fall" ); ch.PracticeSkill( "safe fall" ); ch.PracticeSkill( "safe fall" ); ch.SendText( "You fall to the ground!\r\n" ); if( MUDMath.NumberPercent() < chance ) { SocketConnection.Act( "$n&n falls from above and lands gracefully.", ch, null, null, SocketConnection.MessageTarget.room ); ch.SendText( "You land gracefully, avoiding any injury.\r\n" ); } else { SocketConnection.Act( "$n&n falls from above and lands on $s arse.", ch, null, null, SocketConnection.MessageTarget.room ); if( Race.MAX_SIZE > 0 && !ch.IsNPC() ) { Combat.InflictDamage(ch, ch, MUDMath.NumberRange(2, 4), String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.none); ch.CurrentPosition = Position.sitting; ch.WaitState( 3 ); } } } else { ch.SendText( "You slam into the ground!\r\n" ); ch.CurrentPosition = Position.sitting; ch.WaitState( 8 ); SocketConnection.Act( "$n&n comes crashing in from above.", ch, null, null, SocketConnection.MessageTarget.room ); if( Race.MAX_SIZE > 0 && !ch.IsNPC() ) { Combat.InflictDamage( ch, ch, ( ( MUDMath.NumberPercent() * (int)ch.CurrentSize ) / Race.MAX_SIZE ), String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.none); } } } else if( ch && ch.InRoom ) { if( ch.InRoom.People.Count > 0 ) { SocketConnection.Act( "$n&n falls by.", ch, null, null, SocketConnection.MessageTarget.room ); } } return; }
/// <summary> /// Tracking code. /// </summary> /// <param name="ch"></param> public static void HuntVictim( CharData ch ) { if (!ch || !ch.Hunting || !ch.IsAffected(Affect.AFFECT_TRACK)) { return; } if( ch.CurrentPosition != Position.standing ) { if( ch.IsAffected( Affect.AFFECT_TRACK ) ) { ch.SendText( "You abort your tracking effort.\r\n" ); ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting( ch ); } return; } CharData tmp = null; try { /* * Make sure the victim still exists. */ bool found = false; foreach (CharData it in Database.CharList) { ch = it; if (ch.Hunting != null && ch.Hunting.Who == tmp) found = true; } if (!found || !CharData.CanSee(ch, ch.Hunting.Who)) { if (!ch.IsAffected(Affect.AFFECT_TRACK)) CommandType.Interpret(ch, "say Damn! My prey is gone!"); else { ch.SendText("The trail seems to disappear.\r\n"); ch.RemoveAffect(Affect.AFFECT_TRACK); } Combat.StopHunting(ch); return; } if (ch.InRoom == ch.Hunting.Who.InRoom) { if (ch.Fighting) { return; } FoundPrey(ch, ch.Hunting.Who); return; } ch.WaitState(Skill.SkillList["track"].Delay); Exit.Direction dir = FindPath(ch.InRoom.IndexNumber, ch.Hunting.Who.InRoom.IndexNumber, ch, -40000, true); if (dir == Exit.Direction.invalid) { if (!ch.IsAffected(Affect.AFFECT_TRACK)) { SocketConnection.Act("$n&n says 'Damn! Lost $M!'", ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.room); } else { ch.SendText("You lose the trail.\r\n"); ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting(ch); } return; } /* * Give a random direction if the mob misses the die roll. */ if (MUDMath.NumberPercent() > 75) /* @ 25% */ { do { dir = Database.RandomDoor(); } while (!(ch.InRoom.ExitData[(int)dir]) || !(ch.InRoom.ExitData[(int)dir].TargetRoom)); } if (ch.InRoom.ExitData[(int)dir].HasFlag(Exit.ExitFlag.closed)) { CommandType.Interpret(ch, "open " + dir.ToString()); return; } ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, String.Format("{0}&n leaves room {1} to the {2}.", ch.ShortDescription, ch.InRoom.IndexNumber, dir.ToString())); if (ch.IsAffected(Affect.AFFECT_TRACK)) { SocketConnection.Act(String.Format("You sense $N&n's trail {0} from here...", dir.ToString()), ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.character); } ch.Move(dir); if (ch.IsAffected(Affect.AFFECT_TRACK)) SocketConnection.Act("$n&n peers around looking for tracks.", ch, null, null, SocketConnection.MessageTarget.room); if (!ch.Hunting) { if (!ch.InRoom) { string text = String.Empty; text = String.Format("Hunt_victim: no ch.in_room! Mob #{0}, _name: {1}. Placing mob in limbo (ch.AddToRoom()).", ch.MobileTemplate.IndexNumber, ch.Name); Log.Error(text, 0); ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO"))); text = String.Format("{0}&n has gone to limbo while hunting {1}.", ch.ShortDescription, ch.Hunting.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, text); return; } CommandType.Interpret(ch, "say Damn! Lost my prey!"); return; } if (ch.InRoom == ch.Hunting.Who.InRoom) { FoundPrey(ch, ch.Hunting.Who); } return; } catch (Exception ex) { Log.Error("Exception in HuntVictim: " + ex.ToString()); } }
/// <summary> /// Disembark (exit) from a ship or vehicle. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Disembark(CharData ch, string[] str) { if (ch == null || !ch.InRoom) { return; } foreach (Vehicle vehicle in Database.VehicleList) { if (!vehicle.ParentObject) continue; if (ch.InRoom.IndexNumber == vehicle.EntryRoomTemplateNumber) { if (vehicle.ParentObject.InRoom) { ch.RemoveFromRoom(); ch.AddToRoom(vehicle.ParentObject.InRoom); SocketConnection.Act("$n&n disembarks from $p&n.", ch, vehicle.ParentObject, null, SocketConnection.MessageTarget.room); SocketConnection.Act("You disembark from $p&n.", ch, vehicle.ParentObject, null, SocketConnection.MessageTarget.character); return; } } } ch.SendText("You don't realize you're not on a boat right now?\r\n"); }
public static void ReturnToLoad( CharData ch ) { if( !ch || !ch.InRoom ) return; if( ch.InRoom.Area != Room.GetRoom( ch.LoadRoomIndexNumber ).Area ) return; Exit.Direction dir = FindPath( ch.InRoom.IndexNumber, ch.LoadRoomIndexNumber, ch, -40000, true ); if( dir == Exit.Direction.invalid ) { return; } if( ch.InRoom.ExitData[ (int)dir ].HasFlag( Exit.ExitFlag.closed ) && !ch.IsAffected( Affect.AFFECT_PASS_DOOR ) && !ch.HasInnate( Race.RACE_PASSDOOR ) ) { CommandType.Interpret(ch, "unlock " + dir.ToString()); CommandType.Interpret(ch, "open " + dir.ToString()); return; } ch.Move( dir ); if( !ch.InRoom ) { string text = "Return_to_load: no ch._inRoom! Mob #" + ch.MobileTemplate.IndexNumber + ", _name: " + ch.Name + ". Placing mob in limbo (mob.AddToRoom())."; Log.Error( text, 0 ); ch.AddToRoom( Room.GetRoom( StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO") ) ); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_SPAM, 0, text); return; } 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; }