public static void Fill(CharData ch, string[] str) { if( ch == null ) return; Object fountain = null; if (ch.IsBlind()) { ch.SendText("You can't see what you're trying to fill.\r\n"); return; } if (str.Length == 0) { ch.SendText("Fill what?\r\n"); return; } Object obj = ch.GetObjCarrying(str[0]); if (!obj) { ch.SendText("You do not have that item.\r\n"); return; } bool found = false; foreach (Object fount in ch.InRoom.Contents) { if (fount.FlyLevel != ch.FlightLevel) continue; if (fount.ItemType == ObjTemplate.ObjectType.drink_container) { fountain = fount; found = true; break; } } if (!found) { ch.SendText("There is nothing to fill from here!\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.drink_container) { ch.SendText("You can't fill that.\r\n"); return; } if (obj.Values[1] != 0 && obj.Values[2] != fountain.Values[2]) { ch.SendText("There is already another liquid in it.\r\n"); return; } if (obj.Values[1] >= obj.Values[0]) { ch.SendText("Your container is full.\r\n"); return; } SocketConnection.Act("You fill $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); obj.Values[2] = fountain.Values[2]; obj.Values[1] = obj.Values[0]; return; }
/// <summary> /// Drop an item. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Drop(CharData ch, string[] str) { if( ch == null ) return; Object cash; if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("You muscles won't respond!\r\n"); return; } if (str.Length == 0) { ch.SendText("Drop what?\r\n"); return; } if (MUDString.IsNumber(str[0])) { /* 'drop NNNN coins' */ int amount; Int32.TryParse(str[0], out amount); if (amount <= 0) { ch.SendText("Sorry, you can't do that.\r\n"); return; } if (str.Length < 2) { ch.SendText("That's fine, but *what* do you want to drop?\r\n"); return; } if ("copper".StartsWith(str[1], StringComparison.CurrentCultureIgnoreCase)) { if (ch.GetCopper() < amount) { ch.SendText("You haven't got that many &n&+ycopper&n coins.\r\n"); return; } ch.SpendCopper(amount); cash = Object.CreateMoney(amount, 0, 0, 0); cash.AddToRoom(ch.InRoom); cash.FlyLevel = ch.FlightLevel; } else if ("silver".StartsWith(str[1], StringComparison.CurrentCultureIgnoreCase)) { if (ch.GetSilver() < amount) { ch.SendText("You haven't got that many &n&+wsilver&n coins.\r\n"); return; } ch.SpendSilver(amount); (Object.CreateMoney(0, amount, 0, 0)).AddToRoom(ch.InRoom); } else if ("gold".StartsWith(str[1], StringComparison.CurrentCultureIgnoreCase)) { if (ch.GetGold() < amount) { ch.SendText("You haven't got that many &+Ygold&n coins.\r\n"); return; } ch.SpendGold(amount); (Object.CreateMoney(0, 0, amount, 0)).AddToRoom(ch.InRoom); } else if ("platinum".StartsWith(str[1], StringComparison.CurrentCultureIgnoreCase)) { if (ch.GetPlatinum() < amount) { ch.SendText("You haven't got that many &+Wplatinum&n coins.\r\n"); return; } ch.SpendPlatinum(amount); (Object.CreateMoney(0, 0, 0, amount)).AddToRoom(ch.InRoom); } else { ch.SendText("They haven't minted that type of &+Lcoin&n yet.\r\n"); return; } /* Disabled merging of coin types. This should eventually be re-enabled for ( obj = ch.in_room.contents; obj; obj = obj_next ) { obj_next = obj.next_content; switch ( obj.pIndexData.vnum ) { case StaticObjects.OBJECT_NUMBER_MONEY_ONE: amount += 1; obj.ExtractFromWorld();; break; case StaticObjects.OBJECT_NUMBER_MONEY_SOME: amount += obj.value[0]; obj.ExtractFromWorld();; break; } } */ ch.SendText("Done.\r\n"); SocketConnection.Act("$n&n drops some &n&+wcoins&n.", ch, null, null, SocketConnection.MessageTarget.room); return; } if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0])) { /* 'drop iobj' */ Object iobj = ch.GetObjCarrying(str[0]); if (!iobj) { ch.SendText("You do not have that item.\r\n"); return; } if (!ch.CanDropObject(iobj)) { ch.SendText("You can't release your grip on it.\r\n"); return; } iobj.RemoveFromChar(); iobj.AddToRoom(ch.InRoom); // Prevent item duping - Xangis CharData.SavePlayer(ch); iobj.FlyLevel = ch.FlightLevel; SocketConnection.Act("You drop $p&n.", ch, iobj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n discards $p&n.", ch, iobj, null, SocketConnection.MessageTarget.room); if (iobj.HasFlag(ObjTemplate.ITEM_TRANSIENT)) { SocketConnection.Act("$p&n crumbles to dust.", ch, iobj, null, SocketConnection.MessageTarget.all); iobj.RemoveFromWorld(); } else if (ch.InRoom.TerrainType == TerrainType.lava && !iobj.HasFlag(ObjTemplate.ITEM_NOBURN)) { SocketConnection.Act("$p&n melts as it sinks into the &+RLava&n.", ch, iobj, null, SocketConnection.MessageTarget.all); if (!ch.IsNPC()) { ((PC)ch).Destroyed.AddItem(iobj); } iobj.RemoveFromWorld(); } } else { /* 'drop all' or 'drop all.obj' */ bool found = false; for (int i = ch.Carrying.Count - 1; i >= 0 ; i--) { Object obj = ch.Carrying[i]; if ( (str.Length < 2 || MUDString.NameContainedIn(str[0].Substring(4), obj.Name)) && CharData.CanSeeObj(ch, obj) && obj.WearLocation == ObjTemplate.WearLocation.none && ch.CanDropObject(obj)) { found = true; obj.RemoveFromChar(); obj.AddToRoom(ch.InRoom); SocketConnection.Act("You drop $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n drops $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); if (obj.HasFlag(ObjTemplate.ITEM_TRANSIENT)) { SocketConnection.Act("$p&n crumbles to dust.", ch, obj, null, SocketConnection.MessageTarget.all); if (!ch.IsNPC()) { ((PC)ch).Destroyed.AddItem(obj); } obj.RemoveFromWorld(); } else if (ch.InRoom.TerrainType == TerrainType.lava && !obj.HasFlag(ObjTemplate.ITEM_NOBURN)) { SocketConnection.Act("$p&n melts as it sinks into the &+RLava&n.", ch, obj, null, SocketConnection.MessageTarget.all); if (!ch.IsNPC()) { ((PC)ch).Destroyed.AddItem(obj); } obj.RemoveFromWorld(); } } } if (!found) { if (str.Length > 1) { ch.SendText("You are not carrying anything."); } else { SocketConnection.Act("You are not carrying any $T&n.", ch, null, str[0].Substring(4), SocketConnection.MessageTarget.character); } } } return; }
/// <summary> /// Eat something. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Eat(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (ch.IsBlind()) return; if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("You can't eat while you're fighting!\r\n"); return; } if (str.Length == 0) { ch.SendText("Eat what?\r\n"); return; } if (!(obj = ch.GetObjCarrying(str[0]))) { ch.SendText("You do not have that item.\r\n"); return; } if (!ch.IsImmortal()) { if (obj.ItemType != ObjTemplate.ObjectType.food && obj.ItemType != ObjTemplate.ObjectType.pill) { ch.SendText("That's not edible.\r\n"); return; } if (!ch.IsNPC() && ((PC)ch).Hunger > 40) { ch.SendText("You are too full to eat more.\r\n"); return; } } SocketConnection.Act("You consume $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n inhales $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); switch (obj.ItemType) { case ObjTemplate.ObjectType.food: if (!ch.IsNPC()) { int condition = ((PC)ch).Hunger; if (!ch.IsUndead()) { ch.AdjustHunger(obj.Values[0]); } if (((PC)ch).Hunger > 40) { ch.SendText("You are full.\r\n"); } else if (condition == 0 && ((PC)ch).Hunger > 0) { ch.SendText("You are no longer hungry.\r\n"); } } if (obj.Values[3] != 0 && !CharData.CheckImmune(ch, Race.DamageType.poison)) { /* The shit was poisoned! */ Affect af = new Affect(); SocketConnection.Act("$n chokes and gags.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You choke and gag.\r\n"); af.Type = Affect.AffectType.spell; af.Value = "poison"; af.Duration = 2 * obj.Values[0]; af.AddModifier(Affect.Apply.strength, -(obj.Level / 7 + 2)); af.SetBitvector(Affect.AFFECT_POISON); ch.CombineAffect(af); } break; case ObjTemplate.ObjectType.pill: { for (int i = 1; i <= 4; i++) { String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(obj.Values[i]); if (String.IsNullOrEmpty(spellName)) { Log.Error("Eat: Spell number " + obj.Values[i] + " not found for pill object " + obj.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap."); } Spell spell = StringLookup.SpellLookup(spellName); if (!spell) { Log.Error("Eat: Spell '" + spellName + "' not found for pill object " + obj.ObjIndexNumber + ". Make sure it's in the spells file."); } else { spell.Invoke(ch, obj.Values[0], ch); } } } break; } if (!ch.IsNPC() || (ch.IsNPC() && ch.IsAffected(Affect.AFFECT_CHARM))) { obj.RemoveFromWorld(); } return; }
/// <summary> /// Equip a weapon. Now calls equip_hand to resolve the actual equipping /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Wield(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("Your body refuses the call to movement.\r\n"); return; } if (!ch.IsNPC() && ch.IsAffected( Affect.AFFECT_WRAITHFORM)) { ch.SendText("You try, but your &n&+wghoul&n form resists your attempts.\r\n"); return; } if (str.Length == 0) { ch.SendText("Wield what?\r\n"); return; } if (!(obj = ch.GetObjCarrying(str[0]))) { ch.SendText("You do not have that item.\r\n"); return; } if (!obj.HasWearFlag(ObjTemplate.WEARABLE_WIELD)) { if (obj.ItemType == ObjTemplate.ObjectType.weapon) { ch.SendText("That object is not usable as a weapon.\r\n"); return; } if (obj.ItemType == ObjTemplate.ObjectType.ranged_weapon && !obj.HasWearFlag(ObjTemplate.WEARABLE_HOLD)) { ch.SendText("That object is not usable as a missile weapon.\r\n"); return; } if (obj.ItemType == ObjTemplate.ObjectType.ranged_weapon) { // Ranged weapons flagged wither wield or hold are fine to use -- Xangis } else { ch.SendText("That object is not a weapon.\r\n"); return; } } if (!ch.HasInnate(Race.RACE_WEAPON_WIELD)) { ch.SendText("You are not able to wield a weapon.\r\n"); return; } if (!obj.IsWearableBy(ch)) return; Object.EquipInHand(ch, obj, Object.EQUIP_WIELD); return; }
/// <summary> /// Compares two objects to see which one is better. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Compare(CharData ch, string[] str) { if( ch == null ) return; Object obj2 = null; if (ch.IsNPC()) return; if (str.Length < 1 || String.IsNullOrEmpty(str[0])) { ch.SendText("&nCompare what to what?\r\n"); return; } Object obj1 = ch.GetObjCarrying(str[0]); if (!obj1) { ch.SendText("&nYou do not have that item.\r\n"); return; } if (str.Length < 2 || String.IsNullOrEmpty(str[1])) { foreach (Object obj3 in ch.Carrying) { if (obj3.WearLocation != ObjTemplate.WearLocation.none && CharData.CanSeeObj(ch, obj3) && obj1.ItemType == obj3.ItemType && (obj1.WearFlags[0] & obj3.WearFlags[0] & ~ObjTemplate.WEARABLE_CARRY.Vector) != 0) { obj2 = obj3; break; } } if (!obj2) { ch.SendText("&nYou aren't wearing anything comparable.\r\n"); return; } } else { obj2 = ch.GetObjCarrying(str[1]); if (!obj2) { /* Strip off number argument, subtrDescriptor._actFlags one, paste it together */ int number = MUDString.NumberArgument(str[1], ref str[1]); if (number > 1) number--; string newArg2 = String.Format("{0}.{1}", number, str[1]); obj2 = ch.GetObjWear(newArg2); if (!obj2) { ch.SendText("&nYou do not have that item.\r\n"); return; } if ((obj1.WearFlags[0] & obj2.WearFlags[0] & ~ObjTemplate.WEARABLE_CARRY.Vector) == 0) { ch.SendText("&nThey are not comparable items.\r\n"); return; } } } string msg = null; int value1 = 0; int value2 = 0; if (obj1 == obj2) { msg = "You compare $p&n to itself. It looks about the same."; } else if (obj1.ItemType != obj2.ItemType) { msg = "$p&n and $P&n are not the same type of item."; } else { switch (obj1.ItemType) { default: msg = "You can't compare $p&n and $P&n."; break; case ObjTemplate.ObjectType.trash: msg = "They're both junk."; break; case ObjTemplate.ObjectType.armor: case ObjTemplate.ObjectType.clothing: case ObjTemplate.ObjectType.container: case ObjTemplate.ObjectType.drink_container: case ObjTemplate.ObjectType.food: value1 = obj1.Values[0]; value2 = obj2.Values[0]; break; case ObjTemplate.ObjectType.spellbook: case ObjTemplate.ObjectType.light: value1 = obj1.Values[2]; value2 = obj1.Values[2]; break; case ObjTemplate.ObjectType.shield: value1 = obj1.Values[3]; value2 = obj2.Values[3]; break; case ObjTemplate.ObjectType.treasure: value1 = obj1.Cost; value2 = obj2.Cost; break; case ObjTemplate.ObjectType.weapon: value1 = obj1.Values[1] * obj1.Values[2]; value2 = obj2.Values[1] * obj2.Values[2]; break; } } if (String.IsNullOrEmpty(msg)) { if (obj2.WearLocation != ObjTemplate.WearLocation.none) { if (value1 == value2) msg = "$p&n and $P&n (equipped) look about the same."; else if (value1 > value2) msg = "$p&n looks better than $P&n (equipped)."; else msg = "$p&n looks worse than $P&n (equipped)."; } else { if (value1 == value2) msg = "$p&n and $P&n look about the same."; else if (value1 > value2) msg = "$p&n looks better than $P&n."; else msg = "$p&n looks worse than $P&n."; } } SocketConnection.Act(msg, ch, obj1, obj2, SocketConnection.MessageTarget.character); 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> /// Put on a piece of equipment. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Wear(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA)) { ch.SendText("Your body refuses the call to movement.\r\n"); return; } if (!ch.IsNPC() && ch.IsAffected( Affect.AFFECT_WRAITHFORM)) { ch.SendText("You try, but your &n&+wghoul&n form resists your attempts.\r\n"); return; } if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("You can't wear stuff while you're fighting!\r\n"); return; } if (str.Length == 0) { ch.SendText("Wear, wield, or hold what?\r\n"); return; } if (str[0] == "all") { foreach (Object iobj in ch.Carrying) { if (iobj.WearLocation != ObjTemplate.WearLocation.none || !CharData.CanSeeObj(ch, iobj)) { continue; } if (iobj.HasWearFlag(ObjTemplate.WEARABLE_WIELD) && !ch.HasInnate(Race.RACE_WEAPON_WIELD)) { continue; } Object.WearObject(ch, iobj, false); if (iobj.Trap != null && iobj.Trap.CheckTrigger( Trap.TriggerType.wear)) { ch.SetOffTrap(iobj); if (ch.CurrentPosition == Position.dead) { return; } } } return; } if (!(obj = ch.GetObjCarrying(str[0]))) { ch.SendText("You do not have that item.\r\n"); return; } if (obj.HasWearFlag(ObjTemplate.WEARABLE_WIELD) && !ch.HasInnate(Race.RACE_WEAPON_WIELD)) { ch.SendText("You are not able to wield a weapon.\r\n"); return; } Object.WearObject(ch, obj, true); if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.wear)) { ch.SetOffTrap(obj); if (ch.CurrentPosition == Position.dead) { return; } } return; }
/// <summary> /// Sell an item. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Sell(CharData ch, string[] str) { if( ch == null ) return; Object obj; CharData keeper; string arg2 = String.Empty; int cost; if (str.Length == 0) { ch.SendText("Sell what?\r\n"); return; } if (!(keeper = ch.FindShopkeeper(arg2))) { return; } if (!ch.IsNPC()) { // Won't buy from bottom 25% of faction range. if (((PC)ch).GetFaction(keeper) < (Limits.MIN_FACTION / 2)) { SocketConnection.Act("$n&+W tells you 'I won't do business with scum like you.'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } } if (!(obj = ch.GetObjCarrying(str[0]))) { SocketConnection.Act("$n&+W tells you 'You don't have that item.'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } if (!ch.CanDropObject(obj)) { ch.SendText("You couldn't possibly part with that.\r\n"); return; } if (!CharData.CanSeeObj(keeper, obj)) { SocketConnection.Act("$n&+W tells you 'I can't see that item.'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } if ((cost = Object.GetCost(ch, keeper, obj, false)) <= 0 || obj.HasFlag(ObjTemplate.ITEM_NOSELL)) { SocketConnection.Act("$n&n looks uninterested in $p&n.", keeper, obj, ch, SocketConnection.MessageTarget.victim); return; } if (cost > obj.Cost) { Log.Error("Shopkeeper with index number {0} buys for more than 100 percent of value.\r\n", keeper.MobileTemplate.IndexNumber); cost = obj.Cost; } if (cost < 1) cost = 1; if (obj.HasFlag(ObjTemplate.ITEM_POISONED)) { SocketConnection.Act("$n&+W tells you 'I won't buy that! It's poisoned!'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } string buf = String.Format("You sell $p&n for {0}.", StringConversion.CoinString(cost)); SocketConnection.Act(buf, ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n sells $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); ch.ReceiveCash(cost); if (obj.ItemType == ObjTemplate.ObjectType.trash) { obj.RemoveFromWorld(); } else { obj.RemoveFromChar(); obj.ObjToChar(keeper); // Selling an object decreases its scarcity. --obj.ObjIndexData.Scarcity; } return; }
/// <summary> /// Smoke - consume a magical herb. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Smoke(CharData ch, string[] str) { if( ch == null ) return; Object herb; Object pipe; string arg1 = String.Empty; string arg2 = String.Empty; if (String.IsNullOrEmpty(arg1)) { SocketConnection.Act("You whip out a cigarette and puff away.", ch, null, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n lights up a cigarette and inhales deeply.", ch, null, null, SocketConnection.MessageTarget.room); return; } if (String.IsNullOrEmpty(arg2)) { ch.SendText("What do you want to smoke through?\r\n"); return; } if (!(herb = ch.GetObjCarrying(arg1))) { ch.SendText("You do not have $p&n.\r\n"); return; } if (herb.ItemType != ObjTemplate.ObjectType.herb) { ch.SendText("Its unsafe to smoke anything but &n&+gherbs&n.\r\n"); return; } if (!(pipe = ch.GetObjCarrying(arg2))) { ch.SendText("You do not have $P&n.\r\n"); return; } if (pipe.ItemType != ObjTemplate.ObjectType.pipe) { ch.SendText("You need a &+Lpipe&n of some sort, $P just won't do.\r\n"); return; } if ((Database.SystemData.WeatherData.Sky == Sysdata.SkyType.rain) && ((ch.InRoom.TerrainType != TerrainType.inside) || (ch.InRoom.TerrainType == TerrainType.swamp) || (ch.InRoom.TerrainType == TerrainType.forest))) { ch.SendText("There is no way you can smoke in these wet conditions.\r\n"); return; } if (ch.InRoom.IsWater()) { ch.SendText("The &n&+cwa&+Ct&n&+ce&+Cr&m makes that an impossiblity.\r\n"); return; } SocketConnection.Act("You pack $p&n into your $P.", ch, herb, pipe, SocketConnection.MessageTarget.character); SocketConnection.Act("You &n&+rlight&n $P&n and inhale deep $p&+W smoke&n.", ch, pipe, herb, SocketConnection.MessageTarget.character); SocketConnection.Act("You finish smoking $p&n.", ch, herb, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n smokes $p&n through $s $P&n.", ch, herb, pipe, SocketConnection.MessageTarget.room); // herb.Values[0] is not used for Herbs. for (int i = 1; i <= 4; i++) { String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(herb.Values[i]); if (String.IsNullOrEmpty(spellName)) { Log.Error("Smoke: Spell number " + herb.Values[i] + " not found for object " + herb.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap."); } Spell spell = StringLookup.SpellLookup(spellName); if (!spell) { Log.Error("Smoke: Spell '" + spellName + "' not found for object " + herb.ObjIndexNumber + ". Make sure it's in the spells file."); } else { spell.Invoke(ch, herb.Level, ch); } } // pipe.value[1] would be refering to de percent chance burnout of // pipe value set when creating item. int pipebreak = MUDMath.NumberRange(1, 100); if (pipebreak <= pipe.Values[1]) { SocketConnection.Act("Your $p&n cracks and becomes useless from too much &n&+rheat&n.", ch, pipe, null, SocketConnection.MessageTarget.character); SocketConnection.Act("You toss $p&n violently into the distance.", ch, pipe, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n throws away $p, as cracks have made it useless.", ch, pipe, null, SocketConnection.MessageTarget.room); pipe.RemoveFromWorld(); ; } if (!ch.IsNPC() || (ch.IsNPC() && ch.IsAffected(Affect.AFFECT_CHARM))) { herb.RemoveFromWorld(); } return; }
/// <summary> /// Quaff: Drink a potion. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Quaff(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (str.Length == 0) { ch.SendText("Quaff what?\r\n"); return; } if (!(obj = ch.GetObjCarrying(str[0]))) { ch.SendText("You do not have that potion.\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.potion) { ch.SendText("You can quaff only potions.\r\n"); return; } SocketConnection.Act("You quaff $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n drains $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); ch.WaitState(3); if (obj.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_51_POTION) { obj.RemoveFromWorld(); ; if (ch.Level != 50 || ch.ExperiencePoints < ExperienceTable.Table[ch.Level].LevelExperience) { ch.SendText("Nothing happens.\r\n"); return; } ch.AdvanceLevel(true); } if (obj.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_52_POTION) { obj.RemoveFromWorld(); if (ch.Level != 51 || ch.ExperiencePoints < ExperienceTable.Table[ch.Level].LevelExperience) { ch.SendText("Nothing happens.\r\n"); return; } ch.AdvanceLevel(true); } if (obj.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_53_POTION) { obj.RemoveFromWorld(); if (ch.Level != 52 || ch.ExperiencePoints < ExperienceTable.Table[ch.Level].LevelExperience) { ch.SendText("Nothing happens.\r\n"); return; } ch.AdvanceLevel(true); } if (obj.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_54_POTION) { obj.RemoveFromWorld(); if (ch.Level != 53 || ch.ExperiencePoints < ExperienceTable.Table[ch.Level].LevelExperience) { ch.SendText("Nothing happens.\r\n"); return; } ch.AdvanceLevel(true); } if (obj.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_55_POTION) { obj.RemoveFromWorld(); if (ch.Level != 54 || ch.ExperiencePoints < ExperienceTable.Table[ch.Level].LevelExperience) { ch.SendText("Nothing happens.\r\n"); return; } ch.AdvanceLevel(true); } // obj.Values[0] is not used for potions. for (int i = 1; i <= 4; i++) { String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(obj.Values[i]); if (String.IsNullOrEmpty(spellName)) { Log.Error("Quaff: Spell number " + obj.Values[i] + " not found for object " + obj.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap."); } Spell spell = StringLookup.SpellLookup(spellName); if (!spell) { Log.Error("Quaff: Spell '" + spellName + "' not found for object " + obj.ObjIndexNumber + ". Make sure it's in the spells file."); } else { spell.Invoke(ch, obj.Level, ch); } } obj.RemoveFromWorld(); 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> /// 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> /// 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> /// Apply poison to a weapon. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void PoisonWeapon(CharData ch, string[] str) { if (ch == null) { return; } Object obj; Object pobj = null; Affect af = new Affect(); /* Don't allow mobs or unskilled pcs to do this */ if (ch.IsNPC() || (!ch.IsNPC() && !ch.HasSkill("poison weapon"))) { ch.SendText("What do you think you are, a thief?\r\n"); return; } if (str.Length == 0) { ch.SendText("What are you trying to poison?\r\n"); return; } if (ch.Fighting != null) { ch.SendText("While you're fighting? Nice try.\r\n"); return; } if (!(obj = ch.GetObjCarrying(str[0]))) { ch.SendText("You do not have that weapon.\r\n"); return; } if (obj.ItemType != ObjTemplate.ObjectType.weapon) { ch.SendText("That item is not a weapon.\r\n"); return; } if (obj.HasFlag(ObjTemplate.ITEM_POISONED)) { ch.SendText("That weapon is already poisoned.\r\n"); return; } if (obj.Values[0] != 2) { ch.SendText("You don't have enough poison to cover that!\r\n"); return; } /* Now we have a valid weapon...check to see if we have the poison. */ foreach (Object iobj in ch.Carrying) { // here is where we should check to see if they have poison if (iobj.ItemType == ObjTemplate.ObjectType.drink_container && iobj.Values[2] == 27) { pobj = iobj; break; } } if (!pobj) { ch.SendText("You do not have any poison.\r\n"); return; } if (pobj.Values[1] <= 0 && pobj.Values[1] != -1) { SocketConnection.Act("Sorry, $p&n seems to be empty.", ch, pobj, null, SocketConnection.MessageTarget.character); return; } ch.WaitState(Skill.SkillList["poison weapon"].Delay); /* Check the skill percentage */ if (!ch.CheckSkill("poison weapon")) { ch.SendText("You failed and spill some on yourself. &+ROuch!&n\r\n"); Combat.InflictDamage(ch, ch, ch.Level, "poison weapon", ObjTemplate.WearLocation.none, AttackType.DamageType.poison); SocketConnection.Act("$n spills the &+Gpoison&n all over!", ch, null, null, SocketConnection.MessageTarget.room); pobj.Values[1] -= 2; return; } /* Can't have people smearing gunk on artifacts */ if (obj.InsultArtifact(ch)) { pobj.Values[1]--; return; } SocketConnection.Act("You apply the &+Gpoison&n to $p&n, which glistens wickedly!", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n pours the &+Gli&n&+gq&+Gu&n&+gid&n over $p&n, which glistens wickedly!", ch, obj, null, SocketConnection.MessageTarget.room); af.Value = "poison weapon"; af.Type = Affect.AffectType.skill; af.Duration = ch.Level + MUDMath.Dice(4, ch.Level / 2); af.AddModifier(Affect.Apply.none, pobj.Values[3]); af.Level = ch.Level; af.SetBitvector(Affect.AFFECT_POISON); obj.AddAffect(af); // Consume one unit of the poison source. pobj.Values[1]--; return; }
/// <summary> /// Give an item to someone. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Give(CharData ch, string[] str) { if( ch == null ) return; CharData victim; string arg1 = String.Empty; string arg2 = String.Empty; if (String.IsNullOrEmpty(arg1) || String.IsNullOrEmpty(arg2)) { ch.SendText("Give what to whom?\r\n"); return; } if (MUDString.IsNumber(arg1)) { /* 'give NNNN coins victim' */ string buf; string arg3 = String.Empty; int amount; Int32.TryParse(arg1, out amount); if (amount <= 0) { ch.SendText("Sorry, you can't do that.\r\n"); return; } if (String.IsNullOrEmpty(arg3)) { ch.SendText("Give what to whom?\r\n"); return; } victim = ch.GetCharRoom(arg3); if (victim == null) { ch.SendText("They aren't here.\r\n"); return; } if (!MUDString.IsPrefixOf(arg2, "copper")) { if (ch.GetCopper() < amount) { ch.SendText("You haven't got that many &+ycopper&n coins.\r\n"); return; } ch.SpendCopper(amount); SocketConnection.Act("You give $N&n some &+ycopper&n.", ch, null, victim, SocketConnection.MessageTarget.character); buf = String.Format("$n&n gives you {0} &+ycopper&n.", amount); SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n gives $N&n some &+ycopper&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); // prog_bribe_trigger( victim, ch, amount ); if (!ch.CheckQuest(victim, null, amount)) { victim.ReceiveCopper(amount); } // Prevent money duping CharData.SavePlayer(ch); CharData.SavePlayer(victim); return; } if (!MUDString.IsPrefixOf(arg2, "silver")) { if (ch.GetSilver() < amount) { ch.SendText("You haven't got that many silver coins.\r\n"); return; } ch.SpendSilver(amount); SocketConnection.Act("You give $N&n some silver.", ch, null, victim, SocketConnection.MessageTarget.character); buf = String.Format("$n&n gives you {0} silver.", amount); SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n gives $N&n some silver.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); // prog_bribe_trigger( victim, ch, amount * 10); if (!ch.CheckQuest(victim, null, (amount * 10))) victim.ReceiveSilver(amount); // Prevent money duping CharData.SavePlayer(ch); CharData.SavePlayer(victim); return; } if (!MUDString.IsPrefixOf(arg2, "gold")) { if (ch.GetGold() < amount) { ch.SendText("You haven't got that many &+Ygold&n coins.\r\n"); return; } ch.SpendGold(amount); SocketConnection.Act("You give $N&n some &+Ygold&n.", ch, null, victim, SocketConnection.MessageTarget.character); buf = String.Format("$n&n gives you {0} &+Ygold&n.", amount); SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n gives $N&n some &+Ygold&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); // prog_bribe_trigger( victim, ch, amount *100); if (!ch.CheckQuest(victim, null, (amount * 100))) { victim.ReceiveGold(amount); } // Prevent money duping CharData.SavePlayer(ch); CharData.SavePlayer(victim); return; } if (!MUDString.IsPrefixOf(arg2, "platinum")) { if (ch.GetPlatinum() < amount) { ch.SendText("You haven't got that many &+Wplatinum&n coins.\r\n"); return; } ch.SpendPlatinum(amount); SocketConnection.Act("You give $N&n some &+Wplatinum&n.", ch, null, victim, SocketConnection.MessageTarget.character); buf = String.Format("$n&n gives you {0} &+Wplatinum&n.", amount); SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n gives $N&n some &+Wplatinum&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); // prog_bribe_trigger( victim, ch, amount* 1000 ); if (!ch.CheckQuest(victim, null, (amount * 1000))) { victim.ReceivePlatinum(amount); } // Prevent money duping CharData.SavePlayer(ch); CharData.SavePlayer(victim); return; } ch.SendText("You don't have any of _that_ type of coin yet.\r\n"); return; } Object obj = ch.GetObjCarrying(arg1); if (!obj) { ch.SendText("You do not have that item.\r\n"); return; } if (obj.WearLocation != ObjTemplate.WearLocation.none) { ch.SendText("You must remove it first.\r\n"); return; } victim = ch.GetCharRoom(arg2); if (victim == null) { ch.SendText("They aren't here.\r\n"); return; } if (!ch.CanDropObject(obj)) { ch.SendText("You couldn't possibly part with it.\r\n"); return; } /* * How silly of shopkeepers to refuse blessed items... previously vampires would * refuse blessed items... now all undead types refuse blessed items. */ if (obj.HasFlag(ObjTemplate.ITEM_BLESS) && victim.IsUndead()) { SocketConnection.Act("$N&n refuses to touch the blessed $p&n.", ch, obj, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n tries to give $N&n a $p&n but $E refuses.", ch, obj, victim, SocketConnection.MessageTarget.room); SocketConnection.Act("You refuse to accept the blessed $p&n from $n&n.", ch, obj, victim, SocketConnection.MessageTarget.victim); return; } if (victim.CarryNumber + 1 > Limits.MAX_CARRY) { SocketConnection.Act("$N&n has $S hands full.", ch, null, victim, SocketConnection.MessageTarget.character); return; } if (victim.CarryWeight + obj.GetWeight() > victim.MaxCarryWeight()) { SocketConnection.Act("$N&n cannot carry that much weight.", ch, null, victim, SocketConnection.MessageTarget.character); return; } if (!CharData.CanSeeObj(victim, obj)) { SocketConnection.Act("$N&n can't see it.", ch, null, victim, SocketConnection.MessageTarget.character); return; } obj.RemoveFromChar(); obj.ObjToChar(victim); // Prevent item duplication. CharData.SavePlayer(ch); CharData.SavePlayer(victim); SocketConnection.Act("You give $p&n to $N&n.", ch, obj, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n gives you $p&n.", ch, obj, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n gives $p&n to $N&n.", ch, obj, victim, SocketConnection.MessageTarget.everyone_but_victim); // prog_give_trigger( victim, ch, obj ); if (Database.IsArtifact(obj.ObjIndexData.IndexNumber)) { string buf = String.Format("{0} has given artifact {1} to {2}", ch.Name, obj.ObjIndexData.IndexNumber, victim.Name); Log.Trace(buf); } if (!victim.IsNPC()) { return; } // Destroy the item so they can't kill the mob for the item. if (ch.CheckQuest(victim, obj, 0)) { obj.RemoveFromWorld(); } return; }
/// <summary> /// Value: Find out how much a shopkeeper will pay for an item. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Value(CharData ch, string[] str) { if( ch == null ) return; Object obj; CharData keeper; int cost; if (str.Length == 0) { ch.SendText("Value what?\r\n"); return; } if (!(keeper = ch.FindShopkeeper(""))) return; if (!(obj = ch.GetObjCarrying(str[0]))) { SocketConnection.Act("$n&n tells you 'You don't have that item'.", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } if (!ch.CanDropObject(obj)) { ch.SendText("That's not something you can sell.\r\n"); return; } if (!CharData.CanSeeObj(keeper, obj)) { SocketConnection.Act("$n&+W tells you 'You are offering me an imaginary object!?!?'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } if ((cost = Object.GetCost(ch, keeper, obj, false)) <= 0) { SocketConnection.Act("$n&n looks uninterested in $p&n.", keeper, obj, ch, SocketConnection.MessageTarget.victim); return; } if (obj.HasFlag(ObjTemplate.ITEM_POISONED)) { SocketConnection.Act("$n&+W tells you 'I won't buy that! It's poisoned!'&n", keeper, null, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; } string buf = String.Format("$n&+W tells you 'I'll give you {0} &n&+ycopper&+W coins for $p&n.'", cost); SocketConnection.Act(buf, keeper, obj, ch, SocketConnection.MessageTarget.victim); ch.ReplyTo = keeper; return; }
/// <summary> /// Place an object in your hand. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Hold(CharData ch, string[] str) { if( ch == null ) return; Object obj; if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("You can't move!\r\n"); return; } if (!ch.IsNPC() && ch.IsAffected( Affect.AFFECT_WRAITHFORM)) { ch.SendText("You may not wear, wield, or hold anything in &+Wghoul&n form.\r\n"); return; } if (str.Length == 0 || (obj = ch.GetObjCarrying(str[0])) == null) { ch.SendText("Hold what now?\r\n"); return; } // Light items are automatically holdable. if (!obj.HasWearFlag(ObjTemplate.WEARABLE_HOLD) && obj.ItemType != ObjTemplate.ObjectType.light) { ch.SendText("You can't hold that!\r\n"); return; } if (obj.ItemType == ObjTemplate.ObjectType.weapon || obj.ItemType == ObjTemplate.ObjectType.ranged_weapon) { ch.SendText("You WIELD weapons, they're useless if you hold them.\r\n"); return; } if (!obj.IsWearableBy(ch)) return; if (Object.EquipInHand(ch, obj, Object.EQUIP_HOLD)) { SocketConnection.Act("You hold $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n holds $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); } 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; }