/// <summary> /// Zap a wand, using its spell power. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Zap(CharData ch, string[] str) { if( ch == null ) return; Object wand = null; Object obj = null; CharData victim; int level; if (str.Length == 0 && ch.Fighting == null) { ch.SendText("Zap whom or what?\r\n"); return; } if (!String.IsNullOrEmpty(str[0]) && !(wand = ch.GetObjWear(str[0]))) { if (!(wand = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one))) { ch.SendText("You hold nothing in your hand.\r\n"); return; } } else /* Wand was first argument.. arg is now second argument. */ if (wand.ItemType != ObjTemplate.ObjectType.wand) { ch.SendText("You can zap only with a wand.\r\n"); return; } level = wand.Level; if (String.IsNullOrEmpty(str[0])) { if (ch.Fighting != null) { victim = ch.Fighting; } else { ch.SendText("Zap whom or what?\r\n"); return; } } else { if (((victim = ch.GetCharRoom(str[0])) == null) && (obj = ch.GetObjHere(str[0])) == null) { ch.SendText("You can't find your _targetType.\r\n"); return; } } if (ch.IsNPC() && !ch.IsFreewilled()) { SocketConnection.Act("You try to zap $p&n, but you have no free will.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n tries to zap $p&n, but has no free will.", ch, wand, null, SocketConnection.MessageTarget.room); return; } String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(wand.Values[3]); if (String.IsNullOrEmpty(spellName)) { ch.SendText("You try to zap, but your wand fizzles.\r\n"); Log.Error("Zap: Spell number " + wand.Values[3] + " not found in SpellNumberToTextMap for object " + wand.ObjIndexNumber + "."); return; } Spell spell = StringLookup.SpellLookup(spellName); if (!spell) { ch.SendText("You try to zap, but your wand fizzles.\r\n"); Log.Error("Zap: Spell '" + spellName + "' not found for object " + wand.ObjIndexNumber + ". Check that it exists in the spells file."); return; } ch.PracticeSkill("wands"); if (wand.Values[2] > 0) { if (victim != null) { if (victim == ch) { SocketConnection.Act("You zap yourself with $p&n.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n zaps $mself with $p&n.", ch, wand, null, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("You zap $N&n with $p&n.", ch, wand, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n zaps $N&n with $p&n.", ch, wand, victim, SocketConnection.MessageTarget.room); } } else { SocketConnection.Act("You zap $P&n with $p&n.", ch, wand, obj, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n zaps $P&n with $p&n.", ch, wand, obj, SocketConnection.MessageTarget.room); } if (!ch.IsNPC() && (MUDMath.NumberPercent() > ((PC)ch).SkillAptitude["wands"])) { switch (MUDMath.NumberBits(3)) { case 0: case 1: case 2: case 3: SocketConnection.Act("You are unable to invoke the power of $p&n.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n is unable to invoke the power of $p&N.", ch, wand, null, SocketConnection.MessageTarget.room); break; case 4: case 5: case 6: SocketConnection.Act("You summon the power of $p&n, but it fizzles away.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n summons the power of $p&n, but it fizzles away.", ch, wand, null, SocketConnection.MessageTarget.room); break; case 7: SocketConnection.Act("You can't control the power of $p&n, and it &+Rexplodes&n!", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n &n&+rexplodes&n into fragments!", ch, wand, null, SocketConnection.MessageTarget.room); /* * Command.damage( ) call after Object.extract_obj in case the damage would * have extracted ch. This is okay because we merely mark * obj.deleted; it still retains all values until list_update. * Sloppy? Okay, create another integer variable. * I hate sloppy... */ wand.RemoveFromWorld(); Combat.InflictDamage(ch, ch, level, "wands", ObjTemplate.WearLocation.none, AttackType.DamageType.energy); break; } return; } Magic.ObjectCastSpell(ch, spell, level, victim, obj); } if (--(wand.Values[2]) <= 0) { if (!ch.IsNPC() && MUDMath.NumberPercent() > ((PC)ch).SkillAptitude["wands"]) { SocketConnection.Act("$p&n &n&+rexplodes&n into fragments.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n &+Rexplodes&n into fragments.", ch, wand, null, SocketConnection.MessageTarget.room); wand.RemoveFromWorld(); Combat.InflictDamage(ch, ch, level, "wands", ObjTemplate.WearLocation.none, AttackType.DamageType.energy); } else { SocketConnection.Act("$p&n blazes bright and is gone.", ch, wand, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n blazes bright and is gone.", ch, wand, null, SocketConnection.MessageTarget.room); wand.RemoveFromWorld(); } } return; }
/// <summary> /// Command to climb something. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Climb(CharData ch, string[] str) { if( ch == null ) return; int chance; if (!ch.HasSkill("climb")) { ch.SendText("You lack the skills to climb anything.\r\n"); return; } if (str.Length == 0) { ch.SendText("Climb what?\r\n"); return; } Object obj = ch.GetObjHere(str[0]); if (!obj) { ch.SendText("Uhh... what exactly did you want to climb!?\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.wall) { ch.SendText("That wasn't exactly designed for climbing.\r\n"); return; } if (ch.IsNPC()) { chance = ch.Level * 3 / 2 + 20; } else { chance = ((PC)ch).SkillAptitude["climb"]; } // Agility helps. chance += ch.GetCurrAgi() / 10; switch (obj.ObjIndexData.IndexNumber) { case StaticObjects.OBJECT_NUMBER_WALL_STONE: chance += 5; break; case StaticObjects.OBJECT_NUMBER_WALL_IRON: chance -= 15; break; default: ch.SendText("That wasn't exactly designed for climbing.\r\n"); return; } // Maximum chance of 98% if (chance > 98) { chance = 98; } if (MUDMath.NumberPercent() >= chance) { ch.SendText("You try to climb it, but you fall on your ass!\r\n"); ch.CurrentPosition = Position.sitting; ch.WaitState(5); return; } ch.SendText("With great skill, you scale the wall!\r\n"); // Value 0 of a wall object is the direction that has been walled... // This means that they should move in that direction. We leave it up to // move_char to make sure that there is actually an exit in that direction. // we use the climbing bit to allow them to pass the walls in move_char. ch.SetAffectBit(Affect.AFFECT_CLIMBING); ch.Move((Exit.Direction)obj.Values[0]); ch.RemoveAffect(Affect.AFFECT_CLIMBING); return; }
/// <summary> /// Unlock something, like a door or a container. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Unlock(CharData ch, string[] str) { if( ch == null ) return; string arg1 = String.Empty; Exit.Direction door; if (str.Length == 0) { ch.SendText("What do you wish to unlock?\r\n"); return; } if (!MUDString.StringsNotEqual(str[0], "door") && arg1.Length != 0) { door = Movement.FindDoor(ch, arg1); } else { door = Movement.FindDoor(ch, str[0]); } if (door >= 0 && !(ch.Level < Limits.LEVEL_AVATAR && ch.InRoom.ExitData[(int)door] && ch.InRoom.ExitData[(int)door].ExitFlags != 0 && ch.InRoom.ExitData[(int)door].HasFlag(Exit.ExitFlag.secret))) { /* 'unlock door' */ Exit reverseExit; Room toRoom; Exit exit = ch.InRoom.GetExit(door); if (!exit.HasFlag(Exit.ExitFlag.closed)) { ch.SendText("It's not closed.\r\n"); return; } if (exit.Key < 0) { ch.SendText("It can't be unlocked.\r\n"); return; } if (!ch.GetKey(exit.Key) && !ch.IsImmortal()) { ch.SendText("You lack the key.\r\n"); return; } if (!exit.HasFlag(Exit.ExitFlag.locked)) { ch.SendText("It's already unlocked.\r\n"); return; } exit.RemoveFlag(Exit.ExitFlag.locked); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n unlocks the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); if (exit.HasFlag(Exit.ExitFlag.destroys_key)) { (ch.GetKey(exit.Key)).RemoveFromWorld(); SocketConnection.Act("The $d eats the key!", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); SocketConnection.Act("The $d eats the key!", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); } /* unlock the other side */ if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && reverseExit.TargetRoom == ch.InRoom) { reverseExit.RemoveFlag(Exit.ExitFlag.locked); } return; } Object obj = ch.GetObjHere(str[0]); if (obj) { /* 'unlock portal' */ if (obj.ItemType == ObjTemplate.ObjectType.portal) { if (!Macros.IsSet(obj.Values[1], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[4] < 0) { ch.SendText("It can't be unlocked.\r\n"); return; } if (!ch.GetKey(obj.Values[4])) { ch.SendText("You lack the key.\r\n"); return; } if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_LOCKED)) { ch.SendText("It's already unlocked.\r\n"); return; } Macros.RemoveBit(ref obj.Values[3], ObjTemplate.PORTAL_LOCKED); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n unlocks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } /* 'unlock object' */ if (obj.ItemType != ObjTemplate.ObjectType.container) { ch.SendText("That is not a container.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[2] < 0) { ch.SendText("It can't be unlocked.\r\n"); return; } if (!ch.GetKey(obj.Values[2])) { ch.SendText("You lack the key.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector)) { ch.SendText("It's already unlocked.\r\n"); return; } Macros.RemoveBit(ref obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n unlocks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } return; }
/// <summary> /// Command for corpse carving. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Carve(CharData ch, string[] str) { if( ch == null ) return; Object weap; Race.Parts value; if (str.Length == 0) { ch.SendText("What do you want to carve?\r\n"); return; } Object corpse = ch.GetObjHere(str[0]); if (!corpse) { ch.SendText("I don't see that around here.\r\n"); return; } if (corpse.ItemType != ObjTemplate.ObjectType.pc_corpse) { ch.SendText("That's not a player corpse!\r\n"); return; } if (str.Length < 2) { ch.SendText("Parts of that corpse that are left:\r\n"); if (corpse.Values[0] == 0) { ch.SendText("None.\r\n"); } else { ch.SendText(StringConversion.PartsBitString((Race.Parts)corpse.Values[0])); } return; } // 11 is for piercing eapons if (!(weap = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one)) || weap.Values[3] != 11) { ch.SendText("You need some sort of stabbing weapon for carving.\r\n"); return; } if (!MUDString.StringsNotEqual(str[1], "head")) value = Race.Parts.skull; else if (!MUDString.StringsNotEqual(str[1], "arms")) value = Race.Parts.arms; else if (!MUDString.StringsNotEqual(str[1], "legs")) value = Race.Parts.legs; else if (!MUDString.StringsNotEqual(str[1], "heart")) value = Race.Parts.heart; else if (!MUDString.StringsNotEqual(str[1], "brains")) value = Race.Parts.brains; else if (!MUDString.StringsNotEqual(str[1], "guts")) value = Race.Parts.guts; else if (!MUDString.StringsNotEqual(str[1], "hands")) value = Race.Parts.hands; else if (!MUDString.StringsNotEqual(str[1], "feet")) value = Race.Parts.feet; else if (!MUDString.StringsNotEqual(str[1], "fingers")) value = Race.Parts.fingers; else if (!MUDString.StringsNotEqual(str[1], "ears")) value = Race.Parts.ears; else if (!MUDString.StringsNotEqual(str[1], "eyes")) value = Race.Parts.eyes; else if (!MUDString.StringsNotEqual(str[1], "tongue")) value = Race.Parts.tongue; else if (!MUDString.StringsNotEqual(str[1], "eyestalks")) value = Race.Parts.eyestalks; else if (!MUDString.StringsNotEqual(str[1], "tentacles")) value = Race.Parts.tentacles; else if (!MUDString.StringsNotEqual(str[1], "fins")) value = Race.Parts.fins; else if (!MUDString.StringsNotEqual(str[1], "wings")) value = Race.Parts.wings; else if (!MUDString.StringsNotEqual(str[1], "tail")) value = Race.Parts.tail; else if (!MUDString.StringsNotEqual(str[1], "claws")) value = Race.Parts.claws; else if (!MUDString.StringsNotEqual(str[1], "fangs")) value = Race.Parts.fangs; else if (!MUDString.StringsNotEqual(str[1], "scales")) value = Race.Parts.scales; else if (!MUDString.StringsNotEqual(str[1], "horns")) value = Race.Parts.horns; else if (!MUDString.StringsNotEqual(str[1], "tusks")) value = Race.Parts.tusks; else { ch.SendText("No such part.\r\n"); return; } if (!Macros.IsSet(corpse.Values[0], (int)value)) { ch.SendText("That part has either already been removed or never existed.\r\n"); return; } Macros.RemoveBit(ref corpse.Values[0], (int)value); if (ch.CheckSkill("carve")) { ch.SendText("You managed to pry it loose!\r\n"); } else { ch.SendText("You mangled that part badly.\r\n"); return; } /* corpse of {0} */ string name = MUDString.LastArgument(corpse.Name); // This is where we would normally create the object... Object part; switch (value) { default: part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SEVERED_SKULL), 0); break; case Race.Parts.arms: // Arms are wieldable as a club. part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SLICED_ARM), 0); break; case Race.Parts.legs: // Legs are wieldable as a club, more damage than arms. part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SLICED_LEG), 0); break; case Race.Parts.scalp: // Scalp can be attached to belt. part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SEVERED_SCALP), 0); break; case Race.Parts.heart: // Heart can be eaten as food. part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_TORN_HEART), 0); break; } string buf = String.Format("{0} {1}", StringConversion.PartsBitString(value), name); part.Name = buf; part.ShortDescription = String.Empty; buf = String.Format("the{0} of {1}", StringConversion.PartsBitString(value), name); part.ShortDescription = buf; buf = String.Format("The{0} of {1}&n {2} lying here.", StringConversion.PartsBitString(value), name, MUDString.IsAre(StringConversion.PartsBitString(value))); part.FullDescription = buf; part.Cost = 0; part.Level = corpse.Level; if (value == Race.Parts.skull) // Should be skull. part.Timer = -1; else part.Timer = MUDMath.Dice(5, 20); part.AddFlag(ObjTemplate.ITEM_NOSELL); corpse.AddToObject(part); }
/// <summary> /// Like look, but more detailed. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Examine(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("&nWhat do you wish to examine?\r\n"); return; } CommandType.Interpret(ch, "look " + str[0]); Object obj = ch.GetObjHere(str[0]); if (obj) { // Show material and condition. string text = String.Format("It appears to be made of {0}&n and is of {1} craftsmanship.\r\n", Material.Table[(int)obj.Material].Name, ObjTemplate.CraftsmanshipString(obj.Craftsmanship)); ch.SendText(text); text = String.Format("It is in {0} percent condition.\r\n", obj.Condition); ch.SendText(text); if (obj.HasFlag(ObjTemplate.ITEM_NOSELL)) { text = String.Format("It doesn't appear to be worth much.\r\n"); ch.SendText(text); } switch (obj.ItemType) { default: break; case ObjTemplate.ObjectType.drink_container: case ObjTemplate.ObjectType.container: case ObjTemplate.ObjectType.quiver: case ObjTemplate.ObjectType.npc_corpse: case ObjTemplate.ObjectType.pc_corpse: case ObjTemplate.ObjectType.storage_chest: ch.SendText("\r\n&nWhen you look inside, you see:\r\n"); ch.LookInContainer(str[0], false); break; case ObjTemplate.ObjectType.weapon: text = String.Format("It is a weapon of type {0}.\r\n", ((ObjTemplate.WeaponType)(obj.Values[0]))); ch.SendText(text); break; case ObjTemplate.ObjectType.shield: ch.SendText("&nIt is "); if (obj.Values[5] > 0) ch.SendText("\r\n&nIt is &+Lspiked&n."); //buf = String.Format( "{0}, and {1} in size.&n\r\n", // shield_thickness_string(obj.value[4]), shield_size_string(obj.value[2])); //ch.SendText( buf ); break; case ObjTemplate.ObjectType.armor: text = String.Format("It can be worn on the {0}.", StringConversion.WearString(obj)); ch.SendText(text); break; } // Show item level if eq restrictions are in effect - Xangis. if (Macros.IsSet((int)Database.SystemData.ActFlags, (int)Sysdata.MudFlags.levelrestrictedeq)) { if (obj.Level < 10) ch.SendText("This is a piece of newbie equipment.\r\n"); else if (obj.Level < 25) ch.SendText("This is a piece of low-level equipment.\r\n"); if (obj.Level < 40) ch.SendText("This is a piece of mid-level equipment.\r\n"); else ch.SendText("This is a piece of high-level equipment.\r\n"); } } return; }
/// <summary> /// Called by the cast function to process a spell's targets and react accordingly. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="argument"></param> private static void ProcessSpellTargets(CharData ch, Spell spell, string argument) { Object obj = null; Target target = null; CharData victim = null; if (!ch.IsClass(CharClass.Names.bard)) switch (spell.ValidTargets) { default: Log.Error("Magic.Cast: bad target type for spell {0}. Type is: {1}", spell.Name, spell.ValidTargets.ToString()); return; case TargetType.none: target = new Target(argument); break; case TargetType.singleCharacterWorld: victim = ch.GetCharWorld(argument); if (victim == null) { ch.SendText("Cast the spell on whom?\r\n"); return; } target = new Target(victim); break; case TargetType.trap: ch.SendText("You cannot cast a trap!\r\n"); return; case TargetType.singleCharacterOffensive: if (String.IsNullOrEmpty(argument)) { victim = ch.Fighting; if (victim == null) { if (ch.IsClass(CharClass.Names.psionicist)) ch.SendText("Will the spell upon whom?\r\n"); else ch.SendText("Cast the spell upon whom?\r\n"); return; } } else { victim = ch.GetCharRoom(argument); if (!victim) { ch.SendText("They aren't here.\r\n"); return; } } if (ch.IsAffected( Affect.AFFECT_CHARM) && ch.Master == victim) { ch.SendText("You can't do that to your master!.\r\n"); return; } if (Combat.IsSafe(ch, victim)) return; // Combat.IsSafe could wipe out victim, as it calls procs if a boss // check and see that victim is still valid if (!victim) return; Crime.CheckAttemptedMurder(ch, victim); target = new Target(victim); ch.BreakInvisibility(); break; case TargetType.singleCharacterDefensive: if (String.IsNullOrEmpty(argument)) { victim = ch; } else { victim = ch.GetCharRoom(argument); if (victim == null) { ch.SendText("They aren't here.\r\n"); return; } } target = new Target(victim); break; case TargetType.self: if (!String.IsNullOrEmpty(argument) && !MUDString.NameContainedIn(argument, ch.Name) && "me".Equals(argument, StringComparison.CurrentCultureIgnoreCase) && "self".Equals(argument, StringComparison.CurrentCultureIgnoreCase)) { ch.SendText("You cannot cast this spell on another.\r\n"); return; } target = new Target(ch); break; case TargetType.objectInInventory: if (String.IsNullOrEmpty(argument)) { ch.SendText("What item should the spell be cast upon?\r\n"); return; } obj = ch.GetObjCarrying(argument); if (obj == null) { ch.SendText("You are not carrying that.\r\n"); return; } target = new Target(obj); break; case TargetType.objectInRoom: if (String.IsNullOrEmpty(argument)) { ch.SendText("What should the spell be cast upon?\r\n"); return; } obj = ch.GetObjHere(argument); if (obj == null) { ch.SendText("You do not see that here.\r\n"); return; } target = new Target(obj); break; case TargetType.objectCorpse: target = new Target(argument); break; case TargetType.objectOrCharacter: if (String.IsNullOrEmpty(argument)) { if (ch.Fighting != null) victim = ch.Fighting; else { ch.SendText("Cast upon what?\r\n"); return; } } else if (!(victim = ch.GetCharRoom(argument))) { obj = ch.GetObjHere(argument); } if (victim != null) { target = new Target(victim); } else if (obj != null) { target = new Target(obj); } else { ch.SendText("You do not see that here.\r\n"); return; } break; case TargetType.singleCharacterRanged: if (String.IsNullOrEmpty(argument)) { victim = ch.Fighting; if (victim == null) { ch.SendText("Cast the spell on whom?\r\n"); return; } } else { victim = ch.GetCharRoom(argument); if (!victim) { ch.SendText("They aren't here.\r\n"); return; } // Ranged combat. // // TODO: FIXME: The next line does not successfully get the required argument. //int dir = Movement.FindExit(ch, arg3); //if (ch._level >= Limits.LEVEL_IMMORTAL) //{ // buf = String.Format("Looking for {0} to the {1}.\r\n", arg2, arg3); // ch.SendText(buf); //} //if (ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.walled) // || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.blocked) // || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.secret) // || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.closed) // || !ch._inRoom._exitData[dir]._targetRoom // || ch._inRoom._area != ch._inRoom._exitData[dir]._targetRoom._area) //{ // ch.SendText("You see nothing in that direction.\r\n"); // return; //} //room2 = Movement.FindRoom(ch, arg3); //if (room2 == null) //{ // ch.SendText("You see nothing in that direction.\r\n"); // return; //} //victim = CharData.GetCharAtRoom(room2, ch, arg2); //if (victim == null) //{ // Room room3; // if (room2._exitData[dir] && ((room3 = Room.GetRoom(room2._exitData[dir]._vnum))) && // spell == Spell.SpellList["fireball"]) // { // victim = CharData.GetCharAtRoom(room3, ch, arg2); // } //} //if (victim == null) //{ // ch.SendText("They aren't here.\r\n"); // return; //} //} //end else } //end else if (ch.IsAffected(Affect.AFFECT_CHARM) && ch.Master == victim) { ch.SendText("You can't do that to your master!.\r\n"); return; } if (Combat.IsSafe(ch, victim)) return; // Combat.IsSafe could wipe out victim, as it calls procs if a boss // check and see that victim is still valid if (!victim) return; Crime.CheckAttemptedMurder(ch, victim); target = new Target(victim); ch.BreakInvisibility(); break; } int beats = 0; // For quick chant if (!ch.IsClass(CharClass.Names.bard) && !ch.IsClass(CharClass.Names.psionicist)) { ch.SendText( "You begin casting...\r\n" ); if( "ventriloquate".Equals(spell.Name, StringComparison.CurrentCultureIgnoreCase )) { if( spell.ValidTargets == TargetType.singleCharacterOffensive || spell.ValidTargets == TargetType.singleCharacterRanged ) SocketConnection.Act( "$n&n begins casting an offensive spell...", ch, null, null, SocketConnection.MessageTarget.room ); else SocketConnection.Act( "$n&n begins casting...", ch, null, null, SocketConnection.MessageTarget.room ); } beats = spell.CastingTime; } else if (ch.IsClass(CharClass.Names.bard)) { ch.SendText( "You begin singing...\r\n" ); SocketConnection.Act( "$n&n starts singing...", ch, null, null, SocketConnection.MessageTarget.room ); beats = 0; } if (!ch.IsClass(CharClass.Names.psionicist) && !ch.IsClass(CharClass.Names.bard)) { // Characters with int of 110 have normal memtimes. // int of 100 worsens casting times by 10% // with an int of 55 casting times are doubled. // This may seem a bit harsh, but keep in mind any // casters are very likely to have an int above 100, as it // is their prime requisite. 120 is the max int for Grey Elves // to start. if (ch.IsClass(CharClass.Names.cleric) || ch.IsClass(CharClass.Names.druid) || ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin)) { beats = ( beats * 110 ) / ch.GetCurrWis(); } else if (ch.IsClass( CharClass.Names.shaman)) { beats = ( beats * 330 ) / ( ch.GetCurrInt() + ( ch.GetCurrWis() * 2 ) ); } else { beats = ( beats * 110 ) / ch.GetCurrInt(); } if( ch.CheckSkill("quick chant", PracticeType.only_on_success) ) { beats = beats / 2; } /* * A check for impossibly long cast times...came about from a player * trying to cast when feebleminded. 100 casting time is arbitrary. */ if( beats > 100 ) { ch.SendText( "Forget it! In your present state you haven't a dream of success.\r\n" ); return; } ch.WaitState( beats ); if( CheckHypnoticPattern( ch ) ) { return; } CastData caster = new CastData(); caster.Who = ch; caster.Eventdata = Event.CreateEvent( Event.EventType.spell_cast, beats, ch, target, spell ); Database.CastList.Add( caster ); ch.SetAffectBit( Affect.AFFECT_CASTING ); } else if (ch.IsClass( CharClass.Names.psionicist)) { ch.WaitState( beats ); if( CheckHypnoticPattern( ch ) ) { return; } ch.PracticeSpell( spell ); int mana = 0; if( !ch.IsImmortal() && !ch.IsNPC() && ch.Level < ( spell.SpellCircle[ (int)ch.CharacterClass.ClassNumber ] * 4 + 1 ) && MUDMath.NumberPercent() > ((PC)ch).SpellAptitude[spell.Name]) { ch.SendText( "You lost your concentration.\r\n" ); SocketConnection.Act( "&+r$n&n&+r's face flushes white for a moment.&n", ch, null, null, SocketConnection.MessageTarget.room ); ch.CurrentMana -= mana / 2; } else { ch.CurrentMana -= mana; string buf = String.Format( "Spell {0} ({1}) being willed by {2}", spell, spell.Name, ch.Name ); Log.Trace( buf ); ch.SetAffectBit( Affect.AFFECT_CASTING ); FinishSpell( ch, spell, target ); } if( ch.CurrentPosition > Position.sleeping && ch.CurrentMana < 0 ) { ch.WaitState( 2 * Event.TICK_PER_SECOND ); ch.SendText( "&+WThat last spe&+wll w&+Las a _bitvector&+l much...&n\r\n" ); ch.CurrentPosition = Position.standing; ch.Fighting = null; SocketConnection.Act( "$n&n collapses from exhaustion&n.", ch, null, null, SocketConnection.MessageTarget.room ); ch.CurrentPosition = Position.sleeping; } if( spell.ValidTargets == TargetType.singleCharacterOffensive && victim && victim.Master != ch && victim != ch && victim.IsAwake() ) { foreach( CharData roomChar in ch.InRoom.People ) { if( victim == roomChar && !victim.Fighting ) { victim.AttackCharacter( ch ); break; } } } } else if( ch.IsClass(CharClass.Names.bard )) { ch.WaitState( 0 ); // Create an event to handle the spell CastData caster = new CastData(); caster.Who = ch; caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG, ch, target, spell ); caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 2, ch, target, spell); caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 3, ch, target, spell); caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 4, ch, target, spell); caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 5, ch, target, spell); Database.CastList.Add( caster ); ch.SetAffectBit( Affect.AFFECT_SINGING ); } return; }
/// <summary> /// Pour a liquid. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Pour(CharData ch, string[] str) { if( ch == null ) return; Object obj; string arg1 = String.Empty; string arg2 = String.Empty; if (ch.IsBlind()) return; if (!(obj = ch.GetObjCarrying(arg1))) { ch.SendText("You do not have that item.\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.drink_container) { ch.SendText("You can't fill that.\r\n"); return; } if (!MUDString.StringsNotEqual("out", arg2)) { ch.SendText("You pour it out.\r\n"); obj.Values[1] = 0; return; } Object otherobj = ch.GetObjHere(arg2); if (!otherobj) { ch.SendText("Pour it where?\r\n"); return; } if (otherobj.Values[2] != obj.Values[2] && otherobj.Values[1] != 0) { ch.SendText("It's got another liquid in it.\r\n"); return; } SocketConnection.Act("You fill $p&n.", ch, otherobj, null, SocketConnection.MessageTarget.character); otherobj.Values[2] = obj.Values[2]; otherobj.Values[1] += obj.Values[1]; obj.Values[1] = 0; // Over pour in code => just pour it back in the first container. if (otherobj.Values[1] > otherobj.Values[0]) { obj.Values[1] = otherobj.Values[1] - otherobj.Values[0]; otherobj.Values[1] = otherobj.Values[0]; } 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> /// Command to open a door or a container. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Open(CharData ch, string[] str) { if( ch == null ) return; Object obj; Exit.Direction door; if (str.Length == 0 ) { ch.SendText("What do you wish to open?\r\n"); return; } if (!MUDString.StringsNotEqual(str[0], "door") && str.Length > 1 && str[1].Length > 0) { door = Movement.FindDoor(ch, str[1]); } else { door = Movement.FindDoor(ch, str[0]); } if (door != Exit.Direction.invalid && !(ch.Level < Limits.LEVEL_AVATAR && ch.InRoom.ExitData[(int)door] && ch.InRoom.ExitData[(int)door].ExitFlags != 0 && ch.InRoom.ExitData[(int)door].HasFlag(Exit.ExitFlag.secret))) { /* 'open door' */ Exit reverseExit; Room toRoom; if (ch.FlightLevel > 0) { ch.SendText("You see no doors this high up!\r\n"); return; } if (ch.CurrentPosition == Position.fighting) { ch.SendText("Stop fighting first!\r\n"); return; } Exit exit = ch.InRoom.GetExit(door); if (!exit.HasFlag(Exit.ExitFlag.closed)) { ch.SendText("It's already open.\r\n"); return; } if (exit.HasFlag(Exit.ExitFlag.locked)) { ch.SendText("It's locked.\r\n"); return; } exit.RemoveFlag(Exit.ExitFlag.closed); SocketConnection.Act("$n&n opens the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); ch.SendText("Done.\r\n"); /* open the other side */ if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && reverseExit.TargetRoom == ch.InRoom) { reverseExit.RemoveFlag(Exit.ExitFlag.closed); reverseExit.RemoveFlag(Exit.ExitFlag.secret); foreach (CharData roomChar in ch.InRoom.People) { SocketConnection.Act("The $d opens.", roomChar, null, reverseExit.Keyword, SocketConnection.MessageTarget.character); } } return; } if ((obj = ch.GetObjHere(str[0]))) { /* 'open portal' */ if (obj.ItemType == ObjTemplate.ObjectType.portal) { if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSEABLE)) { ch.SendText("You can't do that.\r\n"); return; } if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("It's already open.\r\n"); return; } if (Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_LOCKED)) { ch.SendText("It's locked.\r\n"); return; } Macros.RemoveBit(ref obj.Values[3], ObjTemplate.PORTAL_CLOSED); ch.SendText("Done.\r\n"); SocketConnection.Act("$n&n opens $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } /* 'open object' */ if (obj.ItemType != ObjTemplate.ObjectType.container && obj.ItemType != ObjTemplate.ObjectType.quiver) { ch.SendText("That's not something that can be opened.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It's already open.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSEABLE.Vector)) { ch.SendText("You can't do that.\r\n"); return; } if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector)) { ch.SendText("It's locked.\r\n"); return; } Macros.RemoveBit(ref obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector); ch.SendText("Done.\r\n"); SocketConnection.Act("$n&n opens $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.open)) { ch.SetOffTrap(obj); if (ch.CurrentPosition == Position.dead) return; } return; } ch.SendText("Open what?\r\n"); return; }
/// <summary> /// Pick a lock. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Pick(CharData ch, string[] str) { if( ch == null ) return; Object obj; Exit.Direction door; if (str.Length == 0) { ch.SendText("Pick what, your nose?\r\n"); return; } if (ch.Riding) { ch.SendText("You can't do that while mounted.\r\n"); return; } ch.WaitState(Skill.SkillList["pick lock"].Delay); // Look for guards or other mobs who could be "in the way". foreach (CharData charData in ch.InRoom.People) { if (charData.IsNPC() && charData.IsAwake() && ch.Level + 5 < charData.Level) { SocketConnection.Act("$N&n is standing too close to the lock.", ch, null, charData, SocketConnection.MessageTarget.character); return; } } // Check skill roll for player, make sure mob isn't charmed. if ((!ch.IsNPC() && MUDMath.NumberPercent() > ((PC)ch).SkillAptitude["pick lock"]) || (ch.IsNPC() && ch.IsAffected( Affect.AFFECT_CHARM))) { ch.PracticeSkill("pick lock"); ch.SendText("You failed.\r\n"); return; } if ((door = Movement.FindDoor(ch, str[0])) >= 0) { /* 'pick door' */ Exit reverseExit; Room toRoom; Exit exit = ch.InRoom.GetExit(door); if (!exit.HasFlag(Exit.ExitFlag.closed)) { ch.SendText("It's not closed.\r\n"); return; } if (exit.Key < 0) { ch.SendText("It can't be picked.\r\n"); return; } if (!exit.HasFlag(Exit.ExitFlag.locked)) { ch.SendText("It's already unlocked.\r\n"); return; } if (exit.HasFlag(Exit.ExitFlag.pickproof)) { ch.SendText("You failed.\r\n"); return; } exit.RemoveFlag(Exit.ExitFlag.locked); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n picks the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); /* pick the other side */ if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && reverseExit.TargetRoom == ch.InRoom) { reverseExit.RemoveFlag(Exit.ExitFlag.locked); } return; } if ((obj = ch.GetObjHere(str[0]))) { /* 'pick portal' */ if (obj.ItemType == ObjTemplate.ObjectType.portal) { if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[4] < 0) { ch.SendText("It can't be unlocked.\r\n"); return; } if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_LOCKED)) { ch.SendText("It's already unlocked.\r\n"); return; } if (Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_PICKPROOF)) { ch.SendText("You failed.\r\n"); return; } Macros.RemoveBit(ref obj.Values[3], ObjTemplate.PORTAL_LOCKED); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n picks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } /* 'pick object' */ if (obj.ItemType != ObjTemplate.ObjectType.container) { ch.SendText("That is not a container.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[2] < 0) { ch.SendText("It can't be unlocked.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector)) { ch.SendText("It's already unlocked.\r\n"); return; } if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_PICKPROOF.Vector)) { ch.SendText("You failed.\r\n"); return; } Macros.RemoveBit(ref obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n picks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } 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> /// Lock something, like a door or a container. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Lock(CharData ch, string[] str) { if( ch == null ) return; Exit.Direction door; if (str.Length == 0) { ch.SendText("What do you wish to lock?\r\n"); return; } if ((door = Movement.FindDoor(ch, str[0])) >= 0) { /* 'lock door' */ Exit reverseExit; Room toRoom; Exit exit = ch.InRoom.GetExit(door); if (!exit.HasFlag(Exit.ExitFlag.closed)) { ch.SendText("It's not closed.\r\n"); return; } if (exit.Key < 0 && !ch.IsImmortal()) { ch.SendText("It can't be locked.\r\n"); return; } if (!ch.GetKey(exit.Key) && !ch.IsImmortal()) { ch.SendText("You lack the key.\r\n"); return; } if (exit.HasFlag(Exit.ExitFlag.locked)) { ch.SendText("It's already locked.\r\n"); return; } exit.AddFlag(Exit.ExitFlag.locked); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n locks the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); /* lock the other side */ if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && reverseExit.TargetRoom == ch.InRoom) { reverseExit.AddFlag(Exit.ExitFlag.locked); } return; } Object obj = ch.GetObjHere(str[0]); if (obj) { /* 'lock portal' */ if (obj.ItemType == ObjTemplate.ObjectType.portal) { if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[4] < 0) { ch.SendText("It can't be locked.\r\n"); return; } if (!ch.GetKey(obj.Values[4])) { ch.SendText("You lack the key.\r\n"); return; } if (Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_LOCKED)) { ch.SendText("It's already locked.\r\n"); return; } Macros.SetBit(ref obj.Values[3], ObjTemplate.PORTAL_LOCKED); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n locks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } /* 'lock object' */ if (obj.ItemType != ObjTemplate.ObjectType.container) { ch.SendText("That is not a container.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It's not closed.\r\n"); return; } if (obj.Values[2] < 0 && !ch.IsImmortal()) { ch.SendText("It can't be locked.\r\n"); return; } if (!ch.GetKey(obj.Values[2]) && !ch.IsImmortal()) { ch.SendText("You lack the key.\r\n"); return; } if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector)) { ch.SendText("It's already locked.\r\n"); return; } Macros.SetBit(ref obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector); ch.SendText("*Click*\r\n"); SocketConnection.Act("$n&n locks $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } return; }
/// <summary> /// Finds an object in the world based on a keyword. /// </summary> /// <param name="ch"></param> /// <param name="argument"></param> /// <returns></returns> public static Object GetObjectInWorld( CharData ch, string argument ) { string arg = String.Empty; Object obj = ch.GetObjHere( argument ); if( obj != null ) { return obj; } int number = MUDString.NumberArgument( argument, ref arg ); int count = 0; foreach( Object it in Database.ObjectList ) { obj = it; if( CharData.CanSeeObj( ch, obj ) && MUDString.NameContainedIn( arg, obj._name ) ) { if( ++count == number ) return obj; } } count = 0; foreach( Object it in Database.ObjectList ) { obj = it; if( CharData.CanSeeObj( ch, obj ) && MUDString.NameIsPrefixOfContents( arg, obj._name ) ) { if( ++count == number ) return obj; } } return null; }
/// <summary> /// Make a clone of something. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Clone(CharData ch, string[] str) { if( ch == null ) return; string text; Object obj; CharData mob; if (str.Length == 0) { ch.SendText("Clone what?\r\n"); return; } if (str.Length > 1 && !MUDString.IsPrefixOf(str[0], "object")) { mob = null; obj = ch.GetObjHere(str[1]); if (obj == null) { ch.SendText("You don't see that here.\r\n"); return; } } else if (str.Length > 1 && !MUDString.IsPrefixOf(str[0], "mobile") || (!MUDString.IsPrefixOf(str[0], "character"))) { obj = null; mob = ch.GetCharRoom(str[1]); if (mob == null) { ch.SendText("You don't see that here.\r\n"); return; } } else { mob = ch.GetCharRoom(str[0]); obj = ch.GetObjHere(str[0]); if (mob == null && obj == null) { ch.SendText("You don't see that here.\r\n"); return; } } /* clone object */ if (obj != null) { Object clone = Database.CreateObject(obj.ObjIndexData, 0); Database.CloneObject(obj, ref clone); if (obj.CarriedBy != null) { clone.ObjToChar(ch); } else { clone.AddToRoom(ch.InRoom); } Object.RecursiveClone(ch, obj, clone); SocketConnection.Act("$n has created $p.", ch, clone, null, SocketConnection.MessageTarget.room); SocketConnection.Act("You clone $p.", ch, clone, null, SocketConnection.MessageTarget.character); text = String.Format("{0} clones {1}.", ch.Name, clone.ShortDescription); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOAD, ch.GetTrust(), text); return; } if (mob != null) { if (!mob.IsNPC()) { ch.SendText("You can only clone mobiles.\r\n"); return; } CharData clone = Database.CreateMobile(mob.MobileTemplate); Database.CloneMobile(mob, clone); foreach (Object obj2 in mob.Carrying) { Object newObj = Database.CreateObject(obj2.ObjIndexData, 0); Database.CloneObject(obj2, ref newObj); Object.RecursiveClone(ch, obj2, newObj); newObj.ObjToChar(clone); newObj.WearLocation = obj2.WearLocation; } clone.AddToRoom(ch.InRoom); SocketConnection.Act("$n has created $N.", ch, null, clone, SocketConnection.MessageTarget.room); SocketConnection.Act("You clone $N.", ch, null, clone, SocketConnection.MessageTarget.character); text = String.Format("{0} clones {1}.", ch.Name, clone.ShortDescription); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOAD, ch.GetTrust(), text); return; } }
/// <summary> /// Put an object into another object. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Put(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (str.Length < 2) { ch.SendText("Put what into what?\r\n"); return; } if (!MUDString.StringsNotEqual(str[1], "all") || !MUDString.IsPrefixOf("all.", str[1])) { ch.SendText("You can't do that.\r\n"); return; } Object container = ch.GetObjHere(str[1]); if (!container) { SocketConnection.Act("You see no $T&n here.", ch, null, str[1], SocketConnection.MessageTarget.character); return; } /* Added put <missileweap> <quiver> */ if (container.ItemType != ObjTemplate.ObjectType.container && container.ItemType != ObjTemplate.ObjectType.quiver) { ch.SendText("That's not a container.\r\n"); return; } if (Macros.IsSet(container.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { SocketConnection.Act("The $d&n is &n&+ystrapped&n shut.", ch, null, container.Name, SocketConnection.MessageTarget.character); return; } if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0])) { /* 'put obj container' */ obj = ch.GetObjCarrying(str[0]); if (!obj) { ch.SendText("You do not have that item.\r\n"); return; } if (obj == container) { ch.SendText("You can't fold it into itself.\r\n"); return; } if (!ch.CanDropObject(obj)) { ch.SendText("You can't seem to let go of it.\r\n"); return; } if (obj.GetWeight() + container.GetWeight() - container.Weight > container.Values[0]) { ch.SendText("It won't fit.\r\n"); return; } /* Added put <missileweap> <quiver> */ if (container.ItemType == ObjTemplate.ObjectType.quiver && obj.ItemType != ObjTemplate.ObjectType.missile_weapon) { SocketConnection.Act("$p&n doesn't belong in $P&n.", ch, obj, container, SocketConnection.MessageTarget.character); return; } obj.RemoveFromChar(); container.AddToObject(obj); SocketConnection.Act("You put $p&n in $P&n.", ch, obj, container, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n slips $p&n into $P&n.", ch, obj, container, SocketConnection.MessageTarget.room); if (obj.Trap != null && obj.Trap.CheckTrigger(Trap.TriggerType.get_put)) { ch.SetOffTrap(obj); } } else { /* 'put all container' or 'put all.obj container' */ bool stuff = false; foreach (Object iobj in ch.Carrying) { if (iobj.WearLocation != ObjTemplate.WearLocation.none) { continue; } if (container.ItemType == ObjTemplate.ObjectType.quiver && iobj.ItemType != ObjTemplate.ObjectType.missile_weapon) { continue; } if ((str[0][3] == '\0' || MUDString.NameContainedIn(str[0].Substring(4), iobj.Name)) && CharData.CanSeeObj(ch, iobj) && iobj.WearLocation == ObjTemplate.WearLocation.none && iobj != container && ch.CanDropObject(iobj) && iobj.GetWeight() + container.GetWeight() <= container.Values[0]) { iobj.RemoveFromChar(); container.AddToObject(iobj); stuff = true; SocketConnection.Act("You put $p&n in $P&n.", ch, iobj, container, SocketConnection.MessageTarget.character); // Descriptor._actFlags( "$n&n puts $p&n in $P&n.", ch, iobj, container, Descriptor.MessageTarget.room ); if (iobj.Trap != null && iobj.Trap.CheckTrigger( Trap.TriggerType.get_put)) { ch.SetOffTrap(iobj); if (ch.CurrentPosition == Position.dead) { return; } } } else if (iobj.GetWeight() + container.GetWeight() > container.Values[0] && iobj != container) { SocketConnection.Act("$p&n won't fit into $P&n.", ch, iobj, container, SocketConnection.MessageTarget.character); } } if (stuff) { SocketConnection.Act("$n&n puts some stuff in $P&n.", ch, null, container, SocketConnection.MessageTarget.room); } } return; }
/// <summary> /// Close something, like a door or a container. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Close(CharData ch, string[] str) { if( ch == null ) return; string arg1 = String.Empty; Exit.Direction door; if (str.Length == 0) { ch.SendText("What do you wish to close?\r\n"); return; } if (!MUDString.StringsNotEqual(str[0], "door") && arg1.Length > 0) { door = Movement.FindDoor(ch, arg1); } else { door = Movement.FindDoor(ch, str[0]); } if (door >= 0) { /* 'close door' */ Exit reverseExit; Room toRoom; if (ch.FlightLevel > 0) { ch.SendText("You can't reach that from up here!\r\n"); return; } if (ch.CurrentPosition == Position.fighting) { ch.SendText("You can't close doors while fighting!.\r\n"); return; } Exit exit = ch.InRoom.GetExit(door); if (exit.HasFlag(Exit.ExitFlag.closed)) { ch.SendText("It's already closed.\r\n"); return; } if (exit.HasFlag(Exit.ExitFlag.bashed)) { SocketConnection.Act("The $d has been bashed open and cannot be closed.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character); return; } exit.AddFlag(Exit.ExitFlag.closed); SocketConnection.Act("$n&n closes the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room); ch.SendText("Done.\r\n"); /* close the other side */ if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && reverseExit.TargetRoom == ch.InRoom) { reverseExit.AddFlag(Exit.ExitFlag.closed); foreach (CharData roomChar in ch.InRoom.People) { SocketConnection.Act("The $d closes.", roomChar, null, reverseExit.Keyword, SocketConnection.MessageTarget.character); } } return; } Object obj = ch.GetObjHere(str[0]); if (obj) { /* 'close portal' */ if (obj.ItemType == ObjTemplate.ObjectType.portal) { if (Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSED)) { ch.SendText("It's already closed.\r\n"); return; } if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSEABLE)) { ch.SendText("You can't do that.\r\n"); return; } Macros.SetBit(ref obj.Values[3], ObjTemplate.PORTAL_CLOSED); ch.SendText("Done.\r\n"); SocketConnection.Act("$n&n closes $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } /* 'close object' */ if (obj.ItemType != ObjTemplate.ObjectType.container) { ch.SendText("That's not something that can be closed.\r\n"); return; } if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { ch.SendText("It's already closed.\r\n"); return; } if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSEABLE.Vector)) { ch.SendText("You can't do that.\r\n"); return; } Macros.SetBit(ref obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector); ch.SendText("Done.\r\n"); SocketConnection.Act("$n&n closes $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); return; } return; }
/// <summary> /// Use a scroll to invoke its magical spells. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Recite(CharData ch, string[] str) { if( ch == null ) return; Object scroll; Object obj = null; CharData victim; string arg1 = String.Empty; string arg2 = String.Empty; if (!(scroll = ch.GetObjCarrying(arg1))) { ch.SendText("You do not have that &+Wscroll&n.\r\n"); return; } if (scroll.ItemType != ObjTemplate.ObjectType.scroll) { ch.SendText("You can recite only &+Wscrolls&n.\r\n"); return; } if (String.IsNullOrEmpty(arg2)) { victim = ch; if (ch.Fighting != null) { victim = ch.Fighting; } } else { if (((victim = ch.GetCharRoom(arg2)) == null) && !(obj = ch.GetObjHere(arg2))) { ch.SendText("You can't find it.\r\n"); return; } } if (!ch.CanSpeak()) { ch.SendText("Your lips move but no sound comes out.\r\n"); return; } if (ch.IsNPC() && !ch.IsFreewilled()) { SocketConnection.Act("You try to recite $p&n, but you have no free will.", ch, scroll, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n tries to recite $p&n, but has no free will.", ch, scroll, null, SocketConnection.MessageTarget.room); return; } ch.WaitState(2 * Event.TICK_COMBAT); SocketConnection.Act("You recite $p&n.", ch, scroll, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n recites $p&n.", ch, scroll, null, SocketConnection.MessageTarget.room); if (ch.CheckSkill("scrolls")) { switch (MUDMath.NumberBits(3)) { case 0: case 1: case 2: case 3: SocketConnection.Act("You can't understand $p&n at all.", ch, scroll, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n can't understand $p&n at all.", ch, scroll, null, SocketConnection.MessageTarget.room); return; case 4: case 5: case 6: ch.SendText("You must have said something incorrectly.\r\n"); SocketConnection.Act("$n&n must have said something incorrectly.", ch, null, null, SocketConnection.MessageTarget.room); SocketConnection.Act("$p&n blazes brightly, then is gone.", ch, scroll, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n blazes brightly and disappears.", ch, scroll, null, SocketConnection.MessageTarget.room); scroll.RemoveFromWorld(); ; return; case 7: SocketConnection.Act( "You completely botch the recitation, and $p&n bursts into &+Rflames&n!!", ch, scroll, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$p&n &+rglows&n and then bursts into &+Rflame&n!", ch, scroll, null, SocketConnection.MessageTarget.room); /* * Command.damage( ) call after Object.extract_obj in case the damage would * have extracted ch. This is okay because we merely mark * obj.deleted; it still retains all values until list_update. * Sloppy? Okay, create another integer variable. */ scroll.RemoveFromWorld(); Combat.InflictDamage(ch, ch, scroll.Level, "scrolls", ObjTemplate.WearLocation.none, AttackType.DamageType.fire); return; } } if (scroll.Level > ch.Level) { SocketConnection.Act("$p&n is too high level for you.", ch, scroll, null, SocketConnection.MessageTarget.character); } else { /* scroll.Values[0] is not used for scrolls */ for (int i = 1; i <= 4; i++) { String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(scroll.Values[i]); if (String.IsNullOrEmpty(spellName)) { Log.Error("Recite: Spell number " + obj.Values[i] + " not found for object " + scroll.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap."); } Spell spell = StringLookup.SpellLookup(spellName); if (!spell) { Log.Error("Recite: Spell '" + spellName + "' not found for object " + scroll.ObjIndexNumber + ". Make sure it's in the spells file."); } else { spell.Invoke(ch, scroll.Level, ch); } } } if (!ch.IsNPC() || (ch.IsNPC() && ch.IsAffected(Affect.AFFECT_CHARM))) { scroll.RemoveFromWorld(); } return; }
/// <summary> /// Ingest a liquid. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Drink(CharData ch, string[] str) { if( ch == null ) return; Object obj = null; if (ch.IsBlind()) { return; } if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("You can't drink while you're fighting!\r\n"); return; } if (str.Length == 0 && ch.InRoom != null) { foreach (Object iobj in ch.InRoom.Contents) { if (iobj.ItemType == ObjTemplate.ObjectType.drink_container) { obj = iobj; break; } } if (!obj) { ch.SendText("Drink what?\r\n"); return; } } else { if (!(obj = ch.GetObjHere(str[0]))) { ch.SendText("You can't find it.\r\n"); return; } } // Allow bards to get twice as drunk as other classes - Xangis if (!ch.IsNPC() && !ch.IsImmortal() && ((PC)ch).Drunk > 15 && ch.IsClass(CharClass.Names.bard) && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk) { ch.SendText("You fail to reach your mouth. *Hic*\r\n"); return; } if (!ch.IsNPC() && !ch.IsImmortal() && ((PC)ch).Drunk > 25 && ch.IsClass(CharClass.Names.bard) && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk) { ch.SendText("You fail to reach your mouth. *Hic*\r\n"); return; } switch (obj.ItemType) { default: ch.SendText("You can't drink from that.\r\n"); break; case ObjTemplate.ObjectType.drink_container: // -1 Means a container never goes empty. if (obj.Values[1] <= 0 && obj.Values[1] != -1) { ch.SendText("It is already &+Lempty&n.\r\n"); return; } /* No drinking if you're full */ if ((!ch.IsImmortal()) && ( (!ch.IsNPC() && ((PC)ch).Thirst > 40) || (!ch.IsNPC() && ((PC)ch).Hunger > 50))) { ch.SendText("You couldn't possibly drink any more.\r\n"); return; } int liquid; if ((liquid = obj.Values[2]) >= Liquid.Table.Length) { Log.Error("Drink: bad liquid number {0}.", liquid); liquid = obj.Values[2] = 0; } SocketConnection.Act("You drink $T from $p&n.", ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n drinks $T from $p&n.", ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.room); int amount = MUDMath.NumberRange(3, 10); if (obj.Values[0] != -1) { amount = Math.Min(amount, obj.Values[1]); } ch.AdjustDrunk(amount * Liquid.Table[liquid].DrunkValue); if (!ch.IsUndead()) { ch.AdjustHunger(amount * Liquid.Table[liquid].HungerValue); if (ch.IsAffected(Affect.AFFECT_THIRST)) { ch.AdjustThirst((amount * Liquid.Table[liquid].ThirstValue) / 12); ch.SendText("That doesn't taste as &+bwet&n as it used to.\r\n"); } else { ch.AdjustThirst(amount * Liquid.Table[liquid].ThirstValue); } } else { /* If blood */ if (Liquid.Table[liquid].Name == "blood") { ch.AdjustHunger(amount * 2); ch.AdjustThirst(amount); } } if (!ch.IsNPC() && ((PC)ch).Drunk > 10) { ch.SendText("You feel &n&+gdrunk&n.\r\n"); } if (!ch.IsNPC() && ((PC)ch).Hunger > 20) { ch.SendText("You are &n&+yfull&n.\r\n"); } if (!ch.IsNPC() && ((PC)ch).Thirst > 20) { ch.SendText("You do not feel &n&+cth&+Ci&n&+cr&+Cst&n&+cy&n.\r\n"); } if (obj.Values[3] != 0 && !CharData.CheckImmune(ch, Race.DamageType.poison)) { /* The shit was poisoned ! */ Affect af = new Affect(); ch.SendText("You choke and gag.\r\n"); SocketConnection.Act("$n chokes and gags.", ch, null, null, SocketConnection.MessageTarget.room); af.Type = Affect.AffectType.spell; af.Value = "poison"; af.Duration = 3 * amount; af.AddModifier(Affect.Apply.strength, -(obj.Level / 7 + 1)); af.SetBitvector(Affect.AFFECT_POISON); ch.CombineAffect(af); } /* HOLY_WATER and UNHOLY_WATER effects */ if ((ch.IsGood() && obj.Values[2] == 27) || (ch.IsEvil() && obj.Values[2] == 28)) { int heal = MUDMath.Dice(1, 8); if (ch.Hitpoints < ch.GetMaxHit()) { ch.Hitpoints = Math.Min(ch.Hitpoints + heal, ch.GetMaxHit()); ch.UpdatePosition(); ch.SendText("You feel a little better!\r\n"); } } if ((ch.IsEvil() && obj.Values[2] == 27) || (ch.IsGood() && obj.Values[2] == 28)) { int harm = MUDMath.Dice(1, 10); ch.Hitpoints = Math.Max(ch.Hitpoints - harm, -10); ch.SendText("You choke and feel as if you'd swallowed boiling oil!\r\n"); ch.UpdatePosition(); } /* End (UN)HOLY_WATER effects */ // -1 Means a container never goes empty. if (obj.Values[1] != -1) { obj.Values[1] -= amount; if (obj.Values[1] <= 0) { ch.SendText("The container is now &+Lempty&n.\r\n"); obj.Values[1] = 0; } } break; } return; }
/// <summary> /// Try to find hidden things. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Search(CharData ch, string[] str) { if( ch == null ) return; Room toRoom; Exit reverseExit; Exit exit = null; Object obj; bool isArg; Exit.Direction door; if (ch.InRoom == null) { ch.SendText("There's no searching to be done here.\r\n"); return; } /* Calculate the probability that ch finds something. */ int chance = ch.GetCurrInt() * 35 / 100; chance += ch.GetCurrWis() * 35 / 100; chance += ch.GetCurrLuck() * 10 / 100; // Dwarves, being natural architects, can search better - Xangis if (ch.GetRace() == Race.RACE_DWARF) chance += 25; if (chance > 95) chance = 95; if (chance < 10) chance = 10; /* Searching with arguments. */ if (str.Length != 0) { isArg = true; obj = ch.GetObjHere(str[0]); if (obj == null) { ch.SendText("You don't see that object here.\r\n"); return; } switch (obj.ItemType) { 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)) { SocketConnection.Act("$p&n is closed.", ch, obj, null, SocketConnection.MessageTarget.character); return; } break; default: ch.SendText("That is not a container!\r\n"); return; } } else { isArg = false; obj = null; } /* Lag ch from searching. */ if (ch.Level < Limits.LEVEL_AVATAR) { ch.WaitState(MUDMath.FuzzyNumber(18)); } List<Object> list; if (obj != null) { list = obj.Contains; } else { list = ch.InRoom.Contents; } foreach (Object obj2 in list) { if (obj2.HasFlag(ObjTemplate.ITEM_SECRET) && chance > MUDMath.NumberPercent() && obj2.FlyLevel == ch.FlightLevel) { obj2.RemoveFlag(ObjTemplate.ITEM_SECRET); SocketConnection.Act("You find $p&n.", ch, obj2, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n points out $p&n!", ch, obj, null, SocketConnection.MessageTarget.room); return; } } /* Look for a hidden exit. */ door = Exit.Direction.invalid; for (int doornum = 0; doornum <= Limits.MAX_DIRECTION; doornum++) { /* If there's a secret exit that leads to a room. */ exit = ch.InRoom.GetExit((Exit.Direction)doornum); if (exit && exit.HasFlag(Exit.ExitFlag.secret) && exit.TargetRoom) { door = (Exit.Direction)doornum; break; } } if (isArg) { door = Exit.Direction.invalid; } if (door != Exit.Direction.invalid) { if (exit == null) { Log.Error("Command.Search: null exit found", 0); return; } if (exit.TargetRoom == null) { Log.Error("Command.Search: exit to null room found", 0); return; } if (MUDMath.NumberPercent() < chance) { if (ch.FlightLevel > 0) { ch.SendText("You're too high to be sure of what you saw.\r\n"); return; } ch.SendText("You found a hidden exit!\r\n"); SocketConnection.Act("$n&n points out a secret exit!", ch, null, null, SocketConnection.MessageTarget.room); /* Search out one side. */ exit.RemoveFlag(Exit.ExitFlag.secret); /* And the other side, if it exists. */ toRoom = Room.GetRoom(exit.IndexNumber); if (toRoom && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door))) && (reverseExit.TargetRoom == ch.InRoom)) { reverseExit.RemoveFlag(Exit.ExitFlag.secret); } return; } } if (!isArg) { // Chance of finding people hiding in the room foreach (CharData roomChar in ch.InRoom.People) { if (!roomChar.IsAffected(Affect.AFFECT_HIDE) || roomChar.FlightLevel != ch.FlightLevel) continue; if (MUDMath.NumberPercent() < chance) { roomChar.RemoveAffect(Affect.AFFECT_HIDE); /* People without DI can't search out invis hiding pplz. */ if (CharData.CanSee(ch, roomChar)) { SocketConnection.Act("$n&n points out $N&n lurking here!", ch, null, roomChar, SocketConnection.MessageTarget.room); SocketConnection.Act("You point out $N&n lurking here!", ch, null, roomChar, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n reveals your hiding spot!", ch, null, roomChar, SocketConnection.MessageTarget.victim); return; } roomChar.SetAffectBit(Affect.AFFECT_HIDE); } } } ch.SendText("You find nothing new.\r\n"); return; }
/// <summary> /// Pick up an item. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Get(CharData ch, string[] str) { if( ch == null ) return; Object container; bool found; Object obj; if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA)) { ch.SendText("Try as you might, your body refuses to move!\r\n"); return; } /* Get type. */ if (str.Length == 0 || String.IsNullOrEmpty(str[0])) { ch.SendText("Get what?\r\n"); return; } if (str.Length < 2) { if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0])) { /* 'get obj' */ obj = Object.GetObjFromList(ch.InRoom.Contents, ch, str[0]); if (obj == null) { SocketConnection.Act("I see no $T&n here.", ch, null, str[0], SocketConnection.MessageTarget.character); return; } if (ch.CarryNumber + 1 > Limits.MAX_CARRY) { ch.SendText("You have your hands full.\r\n"); return; } Object.GetObject(ch, obj, null); } else { /* 'get all' or 'get all.obj' */ found = false; for(int i = (ch.InRoom.Contents.Count - 1); i >= 0; i--) { Object iobj = ch.InRoom.Contents[i]; if (iobj.FlyLevel != ch.FlightLevel) { continue; } if ((str[0].Equals("all", StringComparison.CurrentCultureIgnoreCase) || MUDString.NameContainedIn(str[0].Substring(4), iobj.Name)) && CharData.CanSeeObj(ch, iobj)) { found = true; if (ch.CarryNumber + 1 > Limits.MAX_CARRY) { ch.SendText("You have your hands full.\r\n"); return; } Object.GetObject(ch, iobj, null); } } if (!found) { if (str[0].Equals("all", StringComparison.CurrentCultureIgnoreCase)) { ch.SendText("You see nothing here.\r\n"); } else { SocketConnection.Act("You see no $T&n here.", ch, null, str[0].Substring(4), SocketConnection.MessageTarget.character); } } } } else { /* 'get ... container' */ if (!MUDString.StringsNotEqual(str[1], "all") || !MUDString.IsPrefixOf("all.", str[1])) { ch.SendText("That doesn't seem possible.\r\n"); return; } container = ch.GetObjHere(str[1]); if (!container) { SocketConnection.Act("You don't see any $T&n here.", ch, null, str[1], SocketConnection.MessageTarget.character); return; } switch (container.ItemType) { default: ch.SendText("Unfortunately, that's not a container.\r\n"); return; case ObjTemplate.ObjectType.quiver: case ObjTemplate.ObjectType.container: case ObjTemplate.ObjectType.npc_corpse: break; case ObjTemplate.ObjectType.pc_corpse: { string descr = container.ShortDescription; string name = String.Empty; } break; } if (ch.CurrentPosition == Position.fighting || ch.Fighting) { ch.SendText("You're too busy to be doing that!\r\n"); return; } if (Macros.IsSet(container.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector)) { SocketConnection.Act("The $d&n is fastened shut.", ch, null, container.Name, SocketConnection.MessageTarget.character); return; } if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0])) { /* 'get obj container' */ obj = Object.GetObjFromList(container.Contains, ch, str[0]); if (!obj) { SocketConnection.Act("You search the $T&n with little success.", ch, null, str[1], SocketConnection.MessageTarget.character); return; } if (ch.CarryNumber + 1 > Limits.MAX_CARRY) { ch.SendText("You have your hands full.\r\n"); return; } Object.GetObject(ch, obj, container); } else { /* 'get all container' or 'get all.obj container' */ found = false; for( int i = (container.Contains.Count - 1); i >= 0; i--) { if ((str[0].Equals("all", StringComparison.CurrentCultureIgnoreCase) || MUDString.NameContainedIn(str[0].Substring(4), container.Contains[i].Name)) && CharData.CanSeeObj(ch, container.Contains[i])) { found = true; if (ch.CarryNumber + 1 > Limits.MAX_CARRY) { ch.SendText("You have your hands full.\r\n"); return; } Object.GetObject(ch, container.Contains[i], container); if (container.ItemType == ObjTemplate.ObjectType.pc_corpse) { CharData.SavePlayer(ch); Database.CorpseList.Save(); } } } if (!found) { if (str[0].Equals("all", StringComparison.CurrentCultureIgnoreCase)) { SocketConnection.Act("You see nothing in the $T&n.", ch, null, str[1], SocketConnection.MessageTarget.character); } else { SocketConnection.Act("You see nothing like that in the $T&n.", ch, null, str[1], SocketConnection.MessageTarget.character); } } } } 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; }