/// <summary> /// Song of armor. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongArmor( CharData ch, Spell spell, int level, Target target ) { ch.SendText( "You Sing a song of protection.\r\n" ); foreach( CharData victim in ch.InRoom.People ) { if (victim.IsAffected( Affect.AFFECT_ARMOR)) continue; Affect af = new Affect( Affect.AffectType.song, spell.Name, 4, Affect.Apply.ac, ( 0 - ( 10 + ( level / 5 ) ) ), Affect.AFFECT_ARMOR ); victim.CombineAffect( af ); victim.SendText( "You feel someone protecting you.\r\n" ); } return true; }
public static void GodMode(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (!ch.Authorized("godmode")) return; if (ch.HasActionBit(PC.PLAYER_GODMODE)) { ch.RemoveActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode off.\r\n"); } else { ch.SetActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode on.\r\n"); } return; }
/// <summary> /// Old-style clunky long-form text editing. /// /// TODO: Make this work better. /// </summary> /// <param name="ch"></param> /// <param name="argument"></param> public static void StringAdd( CharData ch, string argument ) { string text = String.Empty; int buflen = ch.Socket.EditingString.Length; int arglen = argument.Length; if( argument[ 0 ] == '.' ) { string arg1 = String.Empty; string arg2 = String.Empty; string arg3 = String.Empty; argument = OneArgument( argument, ref arg1 ); argument = OneArgument( argument, ref arg2 ); argument = OneArgument( argument, ref arg3 ); if( !StringsNotEqual( arg1, ".c" ) ) { ch.SendText( "String cleared.\r\n" ); ch.Socket.EditingString = String.Empty; return; } if( !StringsNotEqual( arg1, ".s" ) ) { ch.SendText( "String so far:\r\n" ); ch.SendText( ch.Socket.EditingString ); ch.SendText( String.Empty ); return; } if( !StringsNotEqual( arg1, ".r" ) ) { if( String.IsNullOrEmpty(arg2) ) { ch.SendText( "Usage: .r \"old string\" \"new string\"\r\n" ); return; } ch.Socket.EditingString = ch.Socket.EditingString.Replace( arg2, arg3 ); text += "'" + arg2 + "' replaced with '" + arg3 + "'.\r\n"; ch.SendText( text ); return; } if( !StringsNotEqual( arg1, ".h" ) ) { ch.SendText( "Sedit help (commands on blank line):\r\n" ); ch.SendText( ".r 'old' 'new' Replace a subpublic string (requires '', \"\").\r\n" ); ch.SendText( ".h Get help (this info).\r\n" ); ch.SendText( ".s Show public string so far.\r\n" ); ch.SendText( ".c Clear public string so far.\r\n" ); ch.SendText( "@ End public string.\r\n" ); return; } ch.SendText( "StringAdd: Invalid dot command.\r\n" ); return; } if( argument[ 0 ] == '@' ) { ch.Socket.EditingString = String.Empty; return; } // Truncate strings to 4096. if( buflen + arglen >= ( 4096 - 4 ) ) { string buf1 = ch.Name; ch.SendText( "The string was too long, the last line has been skipped.\r\n" ); buf1 += " is trying to write a description that's too long."; Log.Trace( buf1 ); // Force character out of editing mode. ch.Socket.EditingString = String.Empty; return; } if( ch.IsImmortal() ) { string message = String.Format( "\r\n&+gAdding {0} chars to {1} chars leaving {2} left.&n\r\n", arglen, buflen, ( 4096 - 4 - buflen - arglen ) ); ch.SendText( message ); } text += ch.Socket.EditingString + argument + "\r\n"; ch.Socket.EditingString = text; return; }
/// <summary> /// Tracking mob has found the person its after. Attack or react accordingly. /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> public static void FoundPrey( CharData ch, CharData victim ) { string victname = String.Empty; string text = String.Empty; string lbuf = String.Empty; if (!victim) { Log.Error("FoundPrey: null victim", 0); return; } if (!victim.InRoom) { Log.Error("FoundPrey: null victim._inRoom", 0); return; } ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, string.Format("{0}&n has found {1}.", ch.ShortDescription, victim.Name)); if (ch.IsAffected(Affect.AFFECT_TRACK)) { ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting(ch); return; } if (ch.IsAffected(Affect.AFFECT_JUSTICE_TRACKER)) { /* Give Justice the ability to ground flying culprits */ if (victim.FlightLevel != 0) { SocketConnection.Act("$n&n forces you to land!", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n forces $N&n to land!", ch, null, victim, SocketConnection.MessageTarget.room_vict); victim.FlightLevel = 0; } SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.room); SocketConnection.Act("$n&n chains you up.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n binds $N&n so $E can't move.", ch, null, victim, SocketConnection.MessageTarget.room); victim.SetAffectBit(Affect.AFFECT_BOUND); victim.RemoveFromRoom(); if (ch.InRoom.Area.JailRoom != 0) { victim.AddToRoom(Room.GetRoom(victim.InRoom.Area.JailRoom)); } else { victim.SendText("Justice is broken in this town - there is no jail and you're screwed.\r\n"); } Combat.StopHunting(ch); return; } victname = victim.IsNPC() ? victim.ShortDescription : victim.Name; if (ch.FlightLevel != victim.FlightLevel) { if (ch.CanFly()) { if (ch.FlightLevel < victim.FlightLevel && ch.FlightLevel < CharData.FlyLevel.high) { Command.Fly(ch, new string[] { "up" }); } else { Command.Fly(ch, new string[] { "down" }); } } else { SocketConnection.Act("$n peers around looking for something.", ch, null, null, SocketConnection.MessageTarget.room); } return; } if (!CharData.CanSee(ch, victim)) { if (MUDMath.NumberPercent() < 90) return; switch (MUDMath.NumberBits(5)) { case 0: text = String.Format("You can't hide forever, {0}!", victname); Command.Say(ch, new string[]{text}); break; case 1: SocketConnection.Act("$n&n sniffs around the room.", ch, null, victim, SocketConnection.MessageTarget.room); text = "I can smell your blood!"; Command.Say(ch, new string[]{text}); break; case 2: text = String.Format("I'm going to tear {0} apart!", victname); Command.Yell(ch, new string[]{text}); break; case 3: Command.Say(ch, new string[]{"Just wait until I find you..."}); break; default: SocketConnection.Act("$p peers about looking for something.", ch, null, null, SocketConnection.MessageTarget.room); break; } return; } if (ch.InRoom.HasFlag(RoomTemplate.ROOM_SAFE) && ch.IsNPC()) { text = String.Format("Hunting mob {0} found a safe room {1}.", ch.MobileTemplate.IndexNumber, ch.InRoom.IndexNumber); Log.Trace(text); return; } if (ch.CurrentPosition > Position.kneeling) { switch (MUDMath.NumberBits(5)) { case 0: text = String.Format("I will eat your heart, {0}!", victname); Command.Say(ch, new string[]{text}); break; case 1: text = String.Format("You want a piece of me, {0}?", victname); Command.Say(ch, new string[]{text}); break; case 2: text = String.Format("How does your flesh taste {0}, like chicken?", victname); Command.Say(ch, new string[]{text}); break; case 3: SocketConnection.Act("$n&n howls gleefully and lunges at $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n howls gleefully and lunges at you!", ch, null, victim, SocketConnection.MessageTarget.victim); break; case 4: SocketConnection.Act("$n&n charges headlong into $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n charges headlong into you!", ch, null, victim, SocketConnection.MessageTarget.victim); break; default: break; } Combat.StopHunting(ch); Combat.CheckAggressive(victim, ch); if (ch.Fighting) return; // Backstab if able, otherwise just kill them. // Kill if they don't have the skill or if they don't have a stabber. if (!ch.HasSkill("backstab")) { Combat.CombatRound(ch, victim, String.Empty); } else if (!Combat.Backstab(ch, victim)) { Combat.CombatRound(ch, victim, String.Empty); } } return; }
/// <summary> /// Song of slowness. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongSlowness( CharData ch, Spell spell, int level, Target target ) { Affect af = new Affect(); foreach( CharData victim in ch.InRoom.People ) { if( Magic.SpellSavingThrow( level, victim, AttackType.DamageType.magic_other ) ) { ch.SendText( "You failed!\r\n" ); continue; } // Removes haste, takes two castings to make a hasted person slowed if (victim.IsAffected( Affect.AFFECT_HASTE)) { victim.RemoveAffect(Affect.AFFECT_HASTE); victim.SendText( "You slow to your normal speed.\r\n" ); continue; } if (victim.IsAffected(Affect.AFFECT_SLOWNESS)) continue; af.Type = Affect.AffectType.song; af.Value = spell.Name; af.Duration = 6; af.SetBitvector( Affect.AFFECT_SLOWNESS ); victim.AddAffect(af); SocketConnection.Act( "&+R$n&+R moves much more slowly.&n", victim, null, null, SocketConnection.MessageTarget.room ); victim.SendText( "&+RYou feel yourself slowing down.&n\r\n" ); } return true; }
/// <summary> /// Song of nightmares. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongNightmares( CharData ch, Spell spell, int level, Target target ) { Affect af = new Affect(); foreach( CharData victim in ch.InRoom.People ) { if (victim.IsAffected(Affect.AFFECT_FEAR) || Magic.SpellSavingThrow(level, victim, AttackType.DamageType.black_magic ) ) { ch.SendText( "You have failed.\r\n" ); ch.SendText( "You resist the urge to panic.\r\n" ); continue; } af.Type = Affect.AffectType.song; af.Value = spell.Name; af.Duration = 1 + ( level / 7 ); af.SetBitvector( Affect.AFFECT_FEAR ); victim.AddAffect(af); SocketConnection.Act( "$N&n is scared!", ch, null, victim, SocketConnection.MessageTarget.character ); victim.SendText( "You are scared!\r\n" ); SocketConnection.Act( "$N&n is scared!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim ); CommandType.Interpret( victim, "flee" ); if( victim.IsNPC() ) Combat.StartFearing( victim, ch ); } return true; }
/// <summary> /// Prints a player's command history. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void History(CharData ch, string[] str) { if (ch == null || ch.Socket == null) { return; } int num = 0; foreach (HistoryData history in ch.Socket.CommandHistory) { ++num; string text = " " + MUDString.PadInt(Math.Abs(num), 4) + ": " + history.Command + "\r\n"; ch.SendText(text); } return; }
/// <summary> /// Say something on the guild chat channel. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void GuildChat(CharData ch, string[] str) { if( ch == null ) return; CharData realChar = ch.GetChar(); if (realChar.IsNPC() || !realChar.IsGuild()) { ch.SendText("You aren't a guildmember!\r\n"); return; } SocketConnection.SendToChannel(ch, String.Join(" ", str), TalkChannel.guild, "guild"); return; }
public static void GuildDonate(CharData ch, string[] str) { if( ch == null ) return; Coins coin = new Coins(); int coinage; bool success = false; if (ch.IsNPC()) { return; } Guild guild = ((PC)ch).GuildMembership; if (guild == null) { ch.SendText("You're not in a guild!\r\n"); return; } if (str.Length == 0) { ch.SendText("Deposit what?\r\n"); return; } if (!coin.FillFromString(str, ch)) { ch.SendText("&+LSyntax: &+RSoc deposit &n&+r<&+L# of coins&n&+r> <&+Lcoin type&n&+r>&n\r\n"); return; } if (coin.Copper == 0 && coin.Silver == 0 && coin.Gold == 0 && coin.Platinum == 0) { ch.SendText("You have none of that type of &+Lcoin&n yet.\r\n"); return; } for (coinage = 0; coinage < 4; coinage++) { switch (coinage) { case 0: //copper if (coin.Copper < 0) { ch.SendText("You can't deposit a debt!\r\n"); continue; } if (coin.Copper > ch.GetCopper()) { ch.SendText("You don't have that much &+ycopper&n coin!\r\n"); continue; } if (coin.Copper == 0) continue; ch.SpendCopper(coin.Copper); success = true; break; case 1: //silver if (coin.Silver < 0) { ch.SendText("You can't deposit a debt!\r\n"); continue; } if (coin.Silver > ch.GetSilver()) { ch.SendText("You don't have that much &+wsilver&n coin!\r\n"); continue; } if (coin.Silver == 0) continue; ch.SpendSilver(coin.Silver); success = true; break; case 2: //gold if (coin.Gold < 0) { ch.SendText("You can't deposit a debt!\r\n"); continue; } if (coin.Gold > ch.GetGold()) { ch.SendText("You don't have that much &+Ygold&n coin!\r\n"); continue; } if (coin.Gold == 0) continue; ch.SpendGold(coin.Gold); success = true; break; case 3: //platinum if (coin.Platinum < 0) { ch.SendText("You can't deposit a debt!\r\n"); continue; } if (coin.Platinum > ch.GetPlatinum()) { ch.SendText("You don't have that much &+Wplatinum&n coin!\r\n"); continue; } if (coin.Platinum == 0) continue; ch.SpendPlatinum(coin.Platinum); success = true; break; } //end switch } //end for if (success) { int value = coin.Copper + 10 * coin.Silver + 100 * coin.Gold + 1000 * coin.Platinum; int count; for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count) { if (!MUDString.StringsNotEqual(guild.Members[count].Name, ch.Name)) { guild.Members[count].Fine -= value; if (guild.Members[count].Fine < 0) { guild.Members[count].Fine = 0; ch.SendText("&+WThank you for the donation!&n\r\n"); } else { ch.SendText("You reduce your fine.\r\n"); } } } guild.GuildBankAccount.Copper += coin.Copper; guild.GuildBankAccount.Silver += coin.Silver; guild.GuildBankAccount.Gold += coin.Gold; guild.GuildBankAccount.Platinum += coin.Platinum; guild.Save(); CharData.SavePlayer(ch); } else { ch.SendText("&+LSyntax: &+RSoc deposit &n&+r<&+L# of coins&n&+r> <&+Lcoin type&n&+r>&n\r\n"); } return; }
/// <summary> /// Bandage someone's wounds. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Bandage(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC() || !ch.HasSkill("bandage")) { ch.SendText("You don't know how to bandage!\r\n"); return; } if (str.Length == 0) { ch.SendText("Bandage whom?\r\n"); return; } CharData victim = ch.GetCharRoom(str[0]); if (victim == null) { ch.SendText("They're not here.\r\n"); return; } if (victim.Hitpoints > 0) { ch.SendText("They do not need your help.\r\n"); return; } int chance = ((PC)ch).SkillAptitude["bandage"]; if (ch.IsClass(CharClass.Names.cleric)) chance += 4; else if (ch.IsClass(CharClass.Names.antipaladin)) chance -= 4; /* Don't allow someone doing more than 1 pt. of damage with bandage. */ int change = (Math.Max(chance - MUDMath.NumberPercent(), -1) / 20) + 1; // Bandage is rarely used, make it likely to increase ch.PracticeSkill("bandage"); ch.PracticeSkill("bandage"); ch.PracticeSkill("bandage"); ch.WaitState(Skill.SkillList["bandage"].Delay); if (change < 0) { ch.SendText("You just made the problem worse!\r\n"); SocketConnection.Act("$n&n tries bandage you but your condition only worsens.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n tries bandage $N&n but $S condition only worsens.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); } else if (change > 0) { ch.SendText("You manage to fix them up a _bitvector.\r\n"); SocketConnection.Act("$n&n bandages you.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n bandages $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); } else { ch.SendText("Your bandaging attempt had no effect.\r\n"); SocketConnection.Act("$n&n tries to bandage you but the wounds are too great.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n tries to bandage $N&n but is unable to have any effect.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); } victim.Hitpoints += change; victim.UpdatePosition(); return; }
/// <summary> /// Guard someone - try to prevent them from becoming the target of attacks. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Guard(CharData ch, string[] str) { if( ch == null ) return; CharData worldChar; if (ch.IsNPC()) return; if (!ch.HasSkill("guard")) { ch.SendText("Guard!? You can't even protect yourself!\r\n"); return; } if (str.Length == 0) { if (!((PC)ch).Guarding) { ch.SendText("Guard who?\r\n"); return; } if (!((PC)ch).Guarding) { string buf = "You are guarding " + (((PC)ch).Guarding.IsNPC() ? ((PC)ch).Guarding.ShortDescription : ((PC)ch).Guarding.Name) + ".\r\n"; ch.SendText(buf); return; } } if (!MUDString.StringsNotEqual(str[0], "who")) { if (!((PC)ch).Guarding) { ch.SendText("You are not guarding anyone.\r\n"); } else { SocketConnection.Act("You are guarding $N&n.", ch, null, ((PC)ch).Guarding, SocketConnection.MessageTarget.character); } foreach (CharData it in Database.CharList) { worldChar = it; if (worldChar.IsNPC()) { continue; } if (((PC)worldChar).Guarding && ((PC)worldChar).Guarding == ch) { SocketConnection.Act("$N&n is guarding you.", ch, null, worldChar, SocketConnection.MessageTarget.character); } } return; } CharData victim = ch.GetCharRoom(str[0]); if (!victim) { ch.SendText("You don't see them here.\r\n"); return; } if (victim == ch) { ch.SendText("You no longer guard anyone.\r\n"); ((PC)ch).Guarding = null; return; } if (ch.IsClass(CharClass.Names.paladin) && victim.IsEvil()) { ch.SendText("Their blackened soul is hardly worth the effort.\r\n"); return; } if (((PC)ch).Guarding) { SocketConnection.Act("$N&n stops guarding you.", ((PC)ch).Guarding, null, ch, SocketConnection.MessageTarget.character); SocketConnection.Act("You stop guarding $N&n.", ch, null, ((PC)ch).Guarding, SocketConnection.MessageTarget.character); } ((PC)ch).Guarding = victim; SocketConnection.Act("You now guard $N&n.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n is now guarding you.", ch, null, victim, SocketConnection.MessageTarget.victim); return; }
/// <summary> /// Say something to the members of your group. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void GroupChat(CharData ch, string[] str) { if( ch == null ) return; // No arguments, no leader, no chance. if (!ch.GroupLeader) { ch.SendText("Tell who, yourself? You are not in a group!\r\n"); return; } if (str.Length < 1) { ch.SendText("Tell your group what?\r\n"); return; } if (!ch.CanSpeak()) { ch.SendText("Your lips move but no sound comes out.\r\n"); return; } String text = String.Join(" ", str, 1, (str.Length - 1)); text = DrunkSpeech.MakeDrunk(text, ch); foreach (CharData groupChar in Database.CharList) { string buf; if (groupChar == ch) { buf = String.Format("&+GYou tell the group '&n&+G{0}&+G'.&n\r\n", text); ch.SendText(buf); continue; } if (groupChar.IsSameGroup(ch) && !groupChar.InRoom.HasFlag(RoomTemplate.ROOM_SILENT) && !groupChar.HasInnate(Race.RACE_MUTE) && !groupChar.IsAffected(Affect.AFFECT_MUTE) && groupChar.IsAwake()) { buf = String.Format("&+G{0}&n&+G tells the group '&n&+G{1}&+G'.&n\r\n", ch.ShowNameTo(groupChar, true), SocketConnection.TranslateText(text, ch, groupChar)); groupChar.SendText(buf); } } return; }
public static void Group(CharData ch, string[] str) { if( ch == null ) return; // Group with no arguments should show group staus. if (str.Length == 0) { ch.ShowGroup(); return; } if (!MUDString.IsPrefixOf(str[0], "all")) { int added = 0; foreach (CharData ivictim in ch.InRoom.People) { if (ivictim == ch || ivictim.FlightLevel != ch.FlightLevel || ch.IsRacewar(ivictim)) continue; if (((ivictim.IsNPC() && ivictim.HasActionBit(MobTemplate.ACT_PET)) || (!ivictim.IsNPC() && ivictim.IsConsenting(ch))) && ivictim.Master == ch && !ivictim.GroupLeader) { ch.AddGroupMember(ivictim); ++added; } } if (added < 1) { ch.SendText("No new group members.\r\n"); } return; } CharData victim = ch.GetCharRoom(str[0]); if (!victim) { ch.SendText("They aren't here.\r\n"); return; } if (ch == victim) { ch.RemoveFromGroup(victim); return; } if (ch.IsRacewar(victim) && !victim.IsNPC()) { ch.SendText("You can't group with such slime!\r\n"); return; } if (ch.IsSameGroup(victim)) { if (ch.GroupLeader == ch) { ch.RemoveFromGroup(victim); } else { ch.SendText("Only the leader of a group may kick someone out.\r\n"); } return; } if (ch.GroupLeader == null || ch.GroupLeader == ch) { string buf; if (victim.GroupLeader == null) { if ((!victim.IsNPC() && !victim.IsConsenting(ch)) || (victim.IsNPC() && victim.Master != ch)) { buf = String.Format("{0} doesn't want to be in your group.\r\n", victim.ShowNameTo(ch, true)); ch.SendText(buf); } else { ch.GroupLeader = ch; ch.AddGroupMember(victim); } } else { buf = String.Format("{0} is in another group.\r\n", victim.ShowNameTo(ch, true)); ch.SendText(buf); } } else { ch.SendText("You must be the head of the group to add someone.\r\n"); } return; }
/// <summary> /// Teleport to another location. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Goto(CharData ch, string[] str) { if( ch == null ) return; CharData realChar = ch.GetChar(); if (!realChar.Authorized("goto") || !ch.IsImmortal()) { return; } if (str.Length == 0) { ch.SendText("Goto where?\r\n"); return; } Room location = Room.FindLocation(ch, str[0]); if (!location) { ch.SendText("No such location.\r\n"); return; } if (location.IsPrivate()) { ch.SendText("That room is private right now.\r\n"); return; } if (ch.Fighting) { Combat.StopFighting(ch, true); } if (!ch.HasActionBit(PC.PLAYER_WIZINVIS)) { if (!ch.IsNPC() && ((PC)ch).ImmortalData.DisappearMessage.Length > 0) { SocketConnection.Act("$T", ch, null, ((PC)ch).ImmortalData.DisappearMessage, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n disappears in a puff of smoke.", ch, null, null, SocketConnection.MessageTarget.room); } } ch.RemoveFromRoom(); ch.AddToRoom(location); if (!ch.HasActionBit(PC.PLAYER_WIZINVIS)) { if (!ch.IsNPC() && ((PC)ch).ImmortalData.AppearMessage.Length > 0) { SocketConnection.Act("$T", ch, null, ((PC)ch).ImmortalData.AppearMessage, SocketConnection.MessageTarget.room); } else { SocketConnection.Act("$n appears in a swirling mist", ch, null, null, SocketConnection.MessageTarget.room); } } CommandType.Interpret(ch, "look auto"); return; }
/// <summary> /// Hide yourself or an object. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Hide(CharData ch, string[] str) { if( ch == null ) return; /* Check player's skill */ if (!ch.HasSkill("hide")) { if(str.Length != 0) { HideItem(ch, new[] { str[0] }); return; } ch.SendText("You're far too obvious to hide anywhere.\r\n"); return; } if (ch.Riding) { ch.SendText("You can't do that while mounted.\r\n"); return; } if (ch.CurrentPosition <= Position.sleeping) { return; } ch.SendText("You attempt to hide.\r\n"); if (ch.IsAffected(Affect.AFFECT_HIDE)) { ch.RemoveAffect(Affect.AFFECT_HIDE); } if (ch.CheckSkill("hide")) { ch.SetAffectBit(Affect.AFFECT_HIDE); } ch.WaitState(12); return; }
/// <summary> /// Shows details about a guild. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void GuildInfo(CharData ch, string[] str) { if( ch == null ) return; int count; int members = 0; if (!ch.IsGuild()) { ch.SendText("You aren't a guildmember.\r\n"); return; } Guild guild = ((PC)ch).GuildMembership; string buf1 = String.Empty; string text = String.Format("{0}\r\n", guild.Name); buf1 += text; text = String.Format("Motto: \"{0}\"\r\n", guild.Motto); buf1 += text; buf1 += "-----------------------------------------------------------------------------\r\n"; text = String.Format("{0}\r\n", guild.Description); buf1 += text; text = String.Format("Leader: {0}\r\n", guild.Overlord); buf1 += text; text = String.Format("Members: {0}\r\nFrags: &+W{1}&n\r\n", guild.NumMembers, guild.Frags); buf1 += text; text = String.Format("Vault: {0} &+Wplatinum&n, {1} &+Ygold&n, {2} silver, {3} &+ycopper&n\r\n", guild.GuildBankAccount.Platinum, guild.GuildBankAccount.Gold, guild.GuildBankAccount.Silver, guild.GuildBankAccount.Copper); buf1 += text; text = String.Format("Current Applicant: {0}\r\n", guild.Applicant ? guild.Applicant.Name : "(none)"); buf1 += text; if (((PC)ch).GuildRank == Guild.Rank.leader) { text = String.Format("\r\n&+cRank Titles:&n\r\n Exile: {0}\r\n Parole: {1}\r\n Normal: {2}\r\n Senior: {3}\r\n" + " Officer: {4}\r\n Deputy: {5}\r\n Leader: {6}\r\n", guild.RankNames[(int)Guild.Rank.exiled], guild.RankNames[(int)Guild.Rank.parole], guild.RankNames[(int)Guild.Rank.normal], guild.RankNames[(int)Guild.Rank.senior], guild.RankNames[(int)Guild.Rank.officer], guild.RankNames[(int)Guild.Rank.deputy], guild.RankNames[(int)Guild.Rank.leader]); buf1 += text; } text = String.Format("\r\nMember Rank Fine:\r\n"); buf1 += text; for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count) { if (guild.Members[count].Filled) { members++; text = String.Format("{0}) &+r{1}&n{2} {3} {4}&+yc&n\r\n", members, (ch.GetCharWorld(guild.Members[count].Name) ? 'o' : ' '), MUDString.PadStr(guild.Members[count].Name, 15), guild.RankNames[(int)guild.Members[count].Rank], MUDString.PadInt(guild.Members[count].Fine, 8)); buf1 += text; } } if (guild.Ostracized.Length > 0) { text = String.Format("Ostracized: {0}\r\n", guild.Ostracized); buf1 += text; } ch.SendText(buf1); return; }
/// <summary> /// Hide an item. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void HideItem(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("Hide what?\r\n"); return; } Object obj = Object.GetObjectInRoom(ch, str[0]); if (!obj) { ch.SendText("You do not see that here.\r\n"); return; } if (!obj.HasWearFlag(ObjTemplate.WEARABLE_CARRY)) { SocketConnection.Act("You attempt to hide $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n stands in front of $p&n with arms outstretched.", ch, obj, null, SocketConnection.MessageTarget.room); ch.WaitState(12); return; } if (obj.ItemType == ObjTemplate.ObjectType.pc_corpse || obj.ItemType == ObjTemplate.ObjectType.npc_corpse) { ch.SendText("You can't hide corpses.\r\n"); return; } SocketConnection.Act("You hide $p&n.", ch, obj, null, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n hides $p&n.", ch, obj, null, SocketConnection.MessageTarget.room); obj.AddFlag(ObjTemplate.ITEM_SECRET); ch.WaitState(24); return; }
/// <summary> /// Show the list of guilds. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Guilds(CharData ch, string[] str) { if( ch == null ) return; int found = 0; string text = String.Format("&+BGuild Members Pkills Pdeaths Mkills Mdeaths Frags&n\r\n"); string buf1 = text; foreach (Guild guild in Database.GuildList) { text = String.Format("{0} {1} {2} {3} {4} {5} &+W{6}&n\r\n", guild.Name, guild.NumMembers, guild.PlayerKills, guild.PlayerDeaths, guild.MonsterKills, guild.MonsterDeaths, guild.Frags); buf1 += text; found++; } if (found == 0) text = String.Format("There are no guilds currently formed.\r\n"); else text = String.Format("You see {0} guild{1} in the game.\r\n", found, found == 1 ? String.Empty : "s"); buf1 += text; ch.SendText(buf1); 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> /// Take money from your guild bank account. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void GuildWithdraw(CharData ch, string[] str) { if( ch == null ) return; string arg = String.Empty; if (ch.IsNPC()) return; Guild guild = ((PC)ch).GuildMembership; if (guild == null) { ch.SendText("You're not in a guild!\r\n"); return; } if (((PC)ch).GuildRank < Guild.Rank.deputy) { ch.SendText("You'll have to be promoted before you can withdraw from the guild.\r\n"); return; } if (str.Length == 0) { ch.SendText("Withdraw what?\r\n"); return; } if (MUDString.IsNumber(str[0])) { int amount; Int32.TryParse(str[0], out amount); if (amount <= 0) { ch.SendText("Sorry, you can't do that.\r\n"); return; } if ("copper".StartsWith(arg, StringComparison.CurrentCultureIgnoreCase)) { if (guild.GuildBankAccount.Copper < amount) { ch.SendText("The guild doesen't have that many &n&+ycopper&n coins.\r\n"); return; } ch.ReceiveCopper(amount); guild.GuildBankAccount.Copper -= amount; } else if ("silver".StartsWith(arg, StringComparison.CurrentCultureIgnoreCase)) { if (guild.GuildBankAccount.Silver < amount) { ch.SendText("The guild doesen't have that many &n&+wsilver&n coins.\r\n"); return; } ch.ReceiveSilver(amount); guild.GuildBankAccount.Silver -= amount; } else if ("gold".StartsWith(arg, StringComparison.CurrentCultureIgnoreCase)) { if (guild.GuildBankAccount.Gold < amount) { ch.SendText("The guild doesen't have that many &+Ygold&n coins.\r\n"); return; } ch.ReceiveGold(amount); guild.GuildBankAccount.Gold -= amount; } else if ("platinum".StartsWith(arg, StringComparison.CurrentCultureIgnoreCase)) { if (guild.GuildBankAccount.Platinum < amount) { ch.SendText("The guild doesen't have that many &+Wplatinum&n coins.\r\n"); return; } ch.ReceivePlatinum(amount); guild.GuildBankAccount.Platinum -= amount; } else { ch.SendText("You don't have any idea what you are trying to do, do you?\r\n"); return; } guild.Save(); CharData.SavePlayer(ch); ch.SendText("You make a withdrawal.\r\n"); } else { ch.SendText("&+LSyntax: &+RWithdraw &n&+r<&+L# of coins&n&+r> <&+Lcoin type&n&+r>&n\r\n"); } return; }
/// <summary> /// Song of idiocy. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongIdiocy( CharData ch, Spell spell, int level, Target target ) { Affect af = new Affect(); foreach( CharData victim in ch.InRoom.People ) { if (victim.IsAffected(Affect.AFFECT_FEEBLEMIND) || Magic.SpellSavingThrow( level, victim, AttackType.DamageType.black_magic ) ) { ch.SendText( "You failed!\r\n" ); continue; } af.Type = Affect.AffectType.song; af.Value = spell.Name; af.Duration = level / 9; af.AddModifier(Affect.Apply.intelligence, 0 - (level + 15)); af.SetBitvector(Affect.AFFECT_FEEBLEMIND); victim.AddAffect(af); SocketConnection.Act( "A dumb look crosses $n&n's face and $e starts to drool.", victim, null, null, SocketConnection.MessageTarget.room ); victim.SendText( "You feel _REALLY_ dumb.\r\n" ); } return true; }
/* * Modified to up the damage and allow for a * chance to stun victim or self * damage = (level) d2, for an average of 75 hp at level 50 * stun damage = (level) d3, for an average of 100 hp at level 50 * Player vs player damage is reduced in damage() */ /// <summary> /// Headbutt. Usable to initiate combat and during combat. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Headbutt(CharData ch, string[] str) { if( ch == null ) return; int chance; int ko; string text; /* Check player's level and class, mobs can use this skill */ if ((!ch.HasSkill("headbutt"))) { ch.SendText("Your skull is much too soft to headbutt anyone.\r\n"); return; } if (ch.IsBlind()) { return; } CharData victim = ch.Fighting; if (str.Length != 0) { if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead) { ch.SendText("They are nowhere to be seen.\r\n"); return; } } else { if (!victim || victim.CurrentPosition == Position.dead) { ch.SendText("You aren't fighting anyone.\r\n"); return; } } /* anti headbutt me code */ if (ch == victim) { ch.SendText("You get dizzy as you ponder the mechanics of headbutting yourself.\r\n"); return; } if (ch.CurrentPosition < Position.fighting) { ch.SendText("You need to stand up to do that.\r\n"); return; } /* Check size of ch vs. victim. */ /* If ch is too small. */ /* Made it 2 sizes */ if (ch.CurrentSize - 2 > victim.CurrentSize) { SocketConnection.Act("You would crush such a small and delicate being with your mass.", ch, null, victim, SocketConnection.MessageTarget.character); return; } /* Ch 2 or more sizes larger than victim => bad! */ if (ch.CurrentSize + 1 < victim.CurrentSize) { SocketConnection.Act("You can't reach their head!", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n slams $s head into your thigh.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n slams $s head into $N's thigh.", ch, null, victim, SocketConnection.MessageTarget.room_vict); ch.WaitState((Skill.SkillList["headbutt"].Delay * 9) / 10); if (victim.Fighting == null) { Combat.SetFighting(victim, ch); } return; } ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["headbutt"].Delay)); ch.PracticeSkill("headbutt"); if (!ch.Fighting) { Combat.SetFighting(ch, victim); } if (!victim.Fighting) { Combat.SetFighting(victim, ch); } /* Added a PC skill level */ // Chance was over-downgraded at some point. Was skill level - 5%, // then it was changed to skill level / 2 giving a level 50 a headbutt // success rate of about 47%. I've upped it to 4/5 of skill level, // meaning that a level 50 has a success rate of 76%, which is a good // target success rate. Keep in mind minotaur will have a success rate of // about 83%. if (ch.IsNPC()) { chance = 50 + ch.Level; } else { chance = ((PC)ch).SkillAptitude["headbutt"] * 4 / 5; } // Minotaur headbutt bonus if (ch.GetRace() == Race.RACE_MINOTAUR) { chance += 7; } if (victim.CurrentPosition < Position.fighting) { chance /= 3; } if (MUDMath.NumberPercent() < chance) /* Headbutt successful, possible KO */ { /* First give the victim a chance to dodge */ if (Combat.CheckDodge(ch, victim)) { return; } /* OK, lets settle for stun right now * a skill level of 100% has a 20% chance of stun * a skill level of 50% has a 2.5% chance of stun * a skill level of 23% has a 1% chance of stun * immortals get a 15% bonus */ // The stun math was bad. Stun was way more often that it should have // been. Now we have a flat /4 chance, meaning a the following stun chances // at each skill level: // 25 = 5% 50 = 10 % 75 = 15% 95 = 19% ko = chance / 4; if (ch.IsImmortal()) { ko += 15; } text = String.Format("Commandheadbutt: {0}&n attempting a KO with {1}%% chance.", ch.Name, ko); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text); if (MUDMath.NumberPercent() < ko + 1) { // deal some decent damage // This was previously level d 3 which was fairly pathetic. // Level d 8 = 50 min, 400 max at level 50 with an average of 225 // PvP damage is quartered, so headbutt will do about 56 against a player. if (ch.GetRace() != Race.RACE_MINOTAUR) { Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 8), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); } else { Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 9), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); } if (victim.CurrentPosition > Position.stunned) { SocketConnection.Act("$n&n staggers about, then collapses in a heap.", victim, null, null, SocketConnection.MessageTarget.room); victim.SendText("You fall to the ground &+Wstunned&n.\r\n"); SocketConnection.Act("$n&n is &+Wstunned!&n", victim, null, null, SocketConnection.MessageTarget.room); victim.CurrentPosition = Position.stunned; victim.WaitState((Skill.SkillList["headbutt"].Delay)); text = String.Format("Commandheadbutt: {0}&n stunned {1}&n.", ch.Name, victim.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text); } } else { // just your ordinary headbutt damage // This was previously level d 2 which was fairly pathetic. // Level d 6 = 50 min, 300 max at level 50 with an average of 175 // PvP damage is quartered, so headbutt will do about 43 against a player. if (ch.GetRace() != Race.RACE_MINOTAUR) { if (!Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 6), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon)) { // Someone blasts you in the head it'll definitely stun you for 3/4 of a second. victim.WaitState(3); } } else { if (!Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 7), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon)) { // Someone blasts you in the head with horns it'll definitely stun you for a second. // -- Xangis victim.WaitState(4); } } } } else /* Headbutt failed, possible damgage to self, possible KO of self */ { /* Don't allow char to kill self, just mort self */ /* Give them a chance to not take any damage */ // Checking chance instead of player's level. Since this should be based on skill // this should be about right (average of 24% chance of screwing yourself at level 50 // instead of 50%, 17% chance for minos). if (MUDMath.NumberPercent() < chance) { ch.SendText("Your headbutt fails to strike its target.\r\n"); SocketConnection.Act("$n&n tries to headbutt $N&n but can't quite connect.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n bobs around you in a feeble attempt at a headbutt.", ch, null, victim, SocketConnection.MessageTarget.victim); return; } SocketConnection.Act("You bang your head against the brick wall of $N&n.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n tries a headbutt but $N&n gets the best of $m.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim); SocketConnection.Act("$n&n bangs into you in a feeble attempt at a headbutt.", ch, null, victim, SocketConnection.MessageTarget.victim); // KO chance of 24% for normals, 17% for minos. // You have to fail three checks to get your ass kicked by KO, one for the actual skill check, // one for the damage check and finally one for the KO check. // keep in mind this KO does damage of about 100 to self at level 50, which is a hell of a lot // for a failed skill. // The chance of ko'ing yourself at each skill level is as follows: (after all 3 checks) // Skill 25 = 59.2% Skill 50 = 29.6% Skill 75 = 14.4% Skill 95 = 9.38% ko = 108 - chance; int dam; if (MUDMath.NumberPercent() < ko) { // doh! This is gonna hurt //deal some decent damage...to self! if (ch.GetRace() != Race.RACE_MINOTAUR) { dam = MUDMath.Dice(ch.Level, 3); } else { dam = MUDMath.Dice(ch.Level, 2); } if (dam > ch.Hitpoints) { dam = ch.Hitpoints + 1; } if (Combat.InflictDamage(ch, ch, dam, "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon)) { // ch invalidated, can't send messages. return; } SocketConnection.Act("$n&n staggers about, then collapses in a heap.", ch, null, null, SocketConnection.MessageTarget.room); ch.SendText("You fall to the ground stunned.\r\n"); SocketConnection.Act("$n&n is stunned!", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.stunned; ch.WaitState((Skill.SkillList["headbutt"].Delay * 2)); text = String.Format("Commandheadbutt: {0}&n stunned self.", ch.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text); } else { // Was previously level d 2, which averaged 30 damage at 20 and 75 at 50. PC to PC // damage is not quartered when it is done to yourself, so this it kind of high at the // upper levels. This has been reduced by level / 5, so the damage at 50 averages 65 // instead of 65. // Keep in mind that the real penalties come from KO and comparitively someone that // fails a bash doesen't take insane damage. dam = MUDMath.Dice(ch.Level, 2) - ch.Level / 5; if (dam > ch.Hitpoints) { dam = ch.Hitpoints + 1; } Combat.InflictDamage(ch, ch, dam, "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); } } //end if() headbutt failed return; }
/// <summary> /// Song of obscrurement. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongObscurement( CharData ch, Spell spell, int level, Target target ) { Affect af = new Affect(); foreach( CharData victim in ch.InRoom.People ) { if( victim.IsAffected( Affect.AFFECT_MINOR_INVIS ) || victim.IsAffected( Affect.AFFECT_INVISIBLE ) ) return true; SocketConnection.Act( "$n&n fades out of existence.", ch, null, null, SocketConnection.MessageTarget.room ); ch.SendText( "You vanish.\r\n" ); af.Type = Affect.AffectType.song; af.Value = spell.Name; af.Duration = level / 6; af.SetBitvector( Affect.AFFECT_MINOR_INVIS ); victim.AddAffect(af); } return true; }
/// <summary> /// Bash. Usable to initiate combat and during combat. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Bash(CharData ch, string[] str) { if( ch == null ) return; int chance; /* Check player's level and class, mobs can use this skill */ if ((!ch.HasSkill("bash"))) { ch.SendText("You'd better leave that to those with more skills.\r\n"); return; } if (ch.IsBlind() && !ch.Fighting) { return; } /* Verify a target. */ CharData victim = ch.Fighting; if (str.Length != 0) { victim = ch.GetCharRoom(str[0]); if (!victim || victim.CurrentPosition == Position.dead) { ch.SendText("They aren't anywhere to be found.\r\n"); return; } } else { if (!victim || victim.CurrentPosition == Position.dead) { ch.SendText("You aren't fighting anyone.\r\n"); return; } } /* Bash self? Ok! */ // Toned down the damage cuz you can't really bash yourself // like you could with someone else. if (victim == ch) { ch.SendText("You throw yourself to the ground!\r\n"); SocketConnection.Act("$N&n knocks $mself to the ground.", ch, null, victim, SocketConnection.MessageTarget.room_vict); ch.CurrentPosition = Position.kneeling; ch.WaitState((Skill.SkillList["bash"].Delay * 8) / 10); Combat.InflictDamage(ch, ch, MUDMath.NumberRange(1, 3), "bash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); return; } /* Check size of ch vs. victim. */ /* If ch is too small. */ if (ch.CurrentSize < victim.CurrentSize) { SocketConnection.Act("$N&n is too big for you to bash!", ch, null, victim, SocketConnection.MessageTarget.character); return; } /* Ch 2 or more sizes larger than victim => bad! */ if (ch.CurrentSize - 2 > victim.CurrentSize) { SocketConnection.Act("You nearly topple over as you try to bash $N&n.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n nearly topples over as $e attempts to bash you.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n nearly topples over as $e attempts to bash $N&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict); ch.WaitState((Skill.SkillList["bash"].Delay)); ch.CurrentPosition = Position.kneeling; if (victim.Fighting == null) { Combat.SetFighting(victim, ch); } return; } /* Lag to basher from bash. Pets get more lag because pets are cheesy */ if (!ch.IsNPC()) { ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["bash"].Delay)); } else { ch.WaitState((Skill.SkillList["bash"].Delay * 6 / 5)); } /* Base chance to bash, followed by chance modifications. */ if (ch.IsNPC()) { chance = (ch.Level * 3) / 2 + 15; } else { chance = ((PC)ch).SkillAptitude["bash"] - 5; } if (victim.CurrentPosition < Position.fighting) { chance /= 5; //used to be 0 } else { chance += ch.GetCurrAgi() - victim.GetCurrAgi(); } if (chance > 95) { chance = 95; } Object obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one); if (!obj) { /* No primary item. */ if (!(obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two))) { /* No items in hand. */ if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin)) { if (!ch.IsClass(CharClass.Names.warrior)) { chance -= 25; } else { chance -= 20; } ch.SendText("You lower your shoulder and attempt to bash without a shield...\r\n"); } else { chance -= 3; // Hidden penalty for not having a shield } } else if (obj.ItemType != ObjTemplate.ObjectType.shield) { /* Secondary item isn't a shield, no primary. */ if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin)) { if (!ch.IsClass(CharClass.Names.warrior)) { chance -= 25; } else { chance -= 20; } ch.SendText("Bashing without a shield is tough, but you try anyway...\r\n"); } else { chance -= 5; // Small hidden penalty for not having a shield } } /* Secondary item is a shield, no primary. */ else if (ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin)) { chance += 3; // Small hidden bonus for having a shield } } else if (obj.ItemType != ObjTemplate.ObjectType.shield) { /* Primary item isn't a shield. */ if (!(obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two))) { /* No secondary. */ if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin)) { if (!ch.IsClass(CharClass.Names.warrior)) { chance -= 25; } else { chance -= 20; } ch.SendText("Without a shield, bashing is a wistful thought, but you try anyway...\r\n"); } else { chance -= 5; // Hidden penalty for not having a shield } } else if (obj.ItemType != ObjTemplate.ObjectType.shield) { /* Secondary item is not a shield. */ if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin)) { if (!ch.IsClass(CharClass.Names.warrior)) { chance -= 25; } else { chance -= 20; } ch.SendText("Without a shield, your shoulder bash is but wishful thinking...\r\n"); } else { chance -= 5; // Hidden penalty for not having a shield } } else if (ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin)) { /* Secondary is a shield. */ chance += 3; // Small hidden bonus for having a shield } else if (ch.IsClass(CharClass.Names.ranger)) { chance -= 8; } else if (ch.IsClass(CharClass.Names.warrior)) { chance -= 5; } } // Centaurs are awful damned hard to bash -- Xangis if (victim.GetRace() == Race.RACE_CENTAUR) { chance -= 25; } // damned high penalty for bashing blind if (ch.IsAffected(Affect.AFFECT_BLIND) && !victim.IsAffected(Affect.AFFECT_BLIND)) { chance /= 10; } if (ch.IsAffected(Affect.AFFECT_BLIND) && victim.IsAffected(Affect.AFFECT_BLIND)) { chance /= 4; } ch.PracticeSkill("bash"); /* Start a fight if not already in one. */ if (ch != victim) { if (!ch.Fighting) { Combat.SetFighting(ch, victim); } if (!victim.Fighting) { Combat.SetFighting(victim, ch); } } string lbuf = "Bash: " + ch.Name + " bashing " + victim.Name + " with " + chance + " chance."; ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf); /* Do the bash, deal the damage. */ if (MUDMath.NumberPercent() < chance) { /* Hit the bash. */ if (victim.IsAffected(Affect.AFFECT_SINGING)) { victim.RemoveAffect(Affect.AFFECT_SINGING); SocketConnection.Act("$n&n chokes on a note and falls silent as $e slams into the ground!", victim, null, null, SocketConnection.MessageTarget.room); victim.SendText("You abort your singing!\r\n"); } if (victim.IsAffected(Affect.AFFECT_CASTING)) { victim.RemoveAffect(Affect.AFFECT_CASTING); SocketConnection.Act("$n&n's eyes roll back in $s head and $e forgets all about $s spell.", victim, null, null, SocketConnection.MessageTarget.room); victim.SendText("Being knocked over so forcefully makes it hard to cast.\r\n"); } if (!Combat.CheckTumble(victim)) { victim.WaitState(((Skill.SkillList["bash"].Delay * 5) / 6)); if (victim.CurrentPosition > Position.kneeling) { victim.CurrentPosition = Position.kneeling; } victim.SendText("You are knocked to the ground!\r\n"); Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "bash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); } else { Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, (ch.Level / 3)), "bash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon); victim.SendText("You roll with the blow, finally landing on your feet.\r\n"); SocketConnection.Act("$n&n rolls with the blow, finally landing on $s feet.", victim, null, null, SocketConnection.MessageTarget.room); } } else { /* Miss the bash. */ SocketConnection.Act("As $N&n avoids your bash, you topple to the &n&+yground&n with a loud crash.", ch, null, victim, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n crashes to the &n&+yground&n as you sidestep $s bash.", ch, null, victim, SocketConnection.MessageTarget.victim); SocketConnection.Act("$n&n misses $s bash at $N&n and is driven to the &n&+yground&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict); ch.CurrentPosition = Position.kneeling; } return; }
/// <summary> /// Scanning function. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> /// <param name="text"></param> /// <param name="distance"></param> /// <param name="dir"></param> /// <returns></returns> public static int ScanRoom( CharData ch, Room room, ref string text, int distance, int dir ) { int numberFound = 0; string distanceMsg; if( dir < 0 || dir >= Limits.MAX_DIRECTION ) { Log.Error( "ScanRoom: direction {0} out of bounds!", dir ); ch.SendText( "Bug while scanning, direction out of bounds!\r\n" ); return 0; } // Not going to find anything in a room that is unscannable - Xangis if (room.HasFlag(RoomTemplate.ROOM_NO_SCAN)) { return 0; } switch( distance ) { case 1: distanceMsg = String.Format( "&n who is close by to the " ); break; case 2: distanceMsg = String.Format( "&n who is not far off to the " ); break; case 3: distanceMsg = String.Format( "&n who is a brief walk away to the " ); break; default: distanceMsg = String.Format( "&n who is an unknown distance to the " ); break; } foreach( CharData target in room.People ) { if( ch.FlightLevel == target.FlightLevel ) { Visibility visibility = Look.HowSee(ch, target); switch( visibility ) { case Visibility.sense_hidden: case Visibility.invisible: case Visibility.too_dark: default: break; case Visibility.visible: text += ( target.ShowNameTo( ch, true )); text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; case Visibility.sense_infravision: text += "&+rYou sense a being within the darkness"; text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; } } } return numberFound; }
public static void Heighten(CharData ch, string[] str) { if( ch == null ) return; Affect af = new Affect(); if (!ch.IsNPC() && !ch.HasSkill("heighten senses")) { ch.SendText("Your senses are as heightened as they're going to get.\r\n"); return; } if (ch.HasAffect( Affect.AffectType.skill, "heighten senses")) return; if (ch.CheckSkill("heighten senses")) { af.Value = "heighten senses"; af.Type = Affect.AffectType.skill; af.Duration = 24 + ch.Level; af.SetBitvector(Affect.AFFECT_DETECT_INVIS); ch.AddAffect(af); af.SetBitvector(Affect.AFFECT_SENSE_LIFE); ch.AddAffect(af); af.SetBitvector(Affect.AFFECT_INFRAVISION); ch.AddAffect(af); ch.SendText("Your senses are heightened.\r\n"); } return; }
/// <summary> /// Tracking code. /// </summary> /// <param name="ch"></param> public static void HuntVictim( CharData ch ) { if (!ch || !ch.Hunting || !ch.IsAffected(Affect.AFFECT_TRACK)) { return; } if( ch.CurrentPosition != Position.standing ) { if( ch.IsAffected( Affect.AFFECT_TRACK ) ) { ch.SendText( "You abort your tracking effort.\r\n" ); ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting( ch ); } return; } CharData tmp = null; try { /* * Make sure the victim still exists. */ bool found = false; foreach (CharData it in Database.CharList) { ch = it; if (ch.Hunting != null && ch.Hunting.Who == tmp) found = true; } if (!found || !CharData.CanSee(ch, ch.Hunting.Who)) { if (!ch.IsAffected(Affect.AFFECT_TRACK)) CommandType.Interpret(ch, "say Damn! My prey is gone!"); else { ch.SendText("The trail seems to disappear.\r\n"); ch.RemoveAffect(Affect.AFFECT_TRACK); } Combat.StopHunting(ch); return; } if (ch.InRoom == ch.Hunting.Who.InRoom) { if (ch.Fighting) { return; } FoundPrey(ch, ch.Hunting.Who); return; } ch.WaitState(Skill.SkillList["track"].Delay); Exit.Direction dir = FindPath(ch.InRoom.IndexNumber, ch.Hunting.Who.InRoom.IndexNumber, ch, -40000, true); if (dir == Exit.Direction.invalid) { if (!ch.IsAffected(Affect.AFFECT_TRACK)) { SocketConnection.Act("$n&n says 'Damn! Lost $M!'", ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.room); } else { ch.SendText("You lose the trail.\r\n"); ch.RemoveAffect(Affect.AFFECT_TRACK); Combat.StopHunting(ch); } return; } /* * Give a random direction if the mob misses the die roll. */ if (MUDMath.NumberPercent() > 75) /* @ 25% */ { do { dir = Database.RandomDoor(); } while (!(ch.InRoom.ExitData[(int)dir]) || !(ch.InRoom.ExitData[(int)dir].TargetRoom)); } if (ch.InRoom.ExitData[(int)dir].HasFlag(Exit.ExitFlag.closed)) { CommandType.Interpret(ch, "open " + dir.ToString()); return; } ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, String.Format("{0}&n leaves room {1} to the {2}.", ch.ShortDescription, ch.InRoom.IndexNumber, dir.ToString())); if (ch.IsAffected(Affect.AFFECT_TRACK)) { SocketConnection.Act(String.Format("You sense $N&n's trail {0} from here...", dir.ToString()), ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.character); } ch.Move(dir); if (ch.IsAffected(Affect.AFFECT_TRACK)) SocketConnection.Act("$n&n peers around looking for tracks.", ch, null, null, SocketConnection.MessageTarget.room); if (!ch.Hunting) { if (!ch.InRoom) { string text = String.Empty; text = String.Format("Hunt_victim: no ch.in_room! Mob #{0}, _name: {1}. Placing mob in limbo (ch.AddToRoom()).", ch.MobileTemplate.IndexNumber, ch.Name); Log.Error(text, 0); ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO"))); text = String.Format("{0}&n has gone to limbo while hunting {1}.", ch.ShortDescription, ch.Hunting.Name); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, text); return; } CommandType.Interpret(ch, "say Damn! Lost my prey!"); return; } if (ch.InRoom == ch.Hunting.Who.InRoom) { FoundPrey(ch, ch.Hunting.Who); } return; } catch (Exception ex) { Log.Error("Exception in HuntVictim: " + ex.ToString()); } }
/// <summary> /// Checks the help files for the requested help entry and displays it if available. Checks for exact /// matches before trying to match the first keyword. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void HelpCommand(CharData ch, string[] str) { if( ch == null ) return; bool found = false; String query = String.Join(" ", str); if (ch == null) { Log.Error("Help: Called with null ch.", 0); return; } if (str.Length < 1 || str[0] == "commands") { Commands(ch, new [] { String.Empty } ); return; } // Try for exact matches first. foreach (Help help in Database.HelpList) { if (query.Equals(help.Keyword, StringComparison.CurrentCultureIgnoreCase)) { ch.SendText(help.ToString()); return; } } // Try for partial matches next. foreach (Help help in Database.HelpList) { if (help.MinimumLevel > ch.GetTrust()) { continue; } string[] keywords = help.Keyword.Split(' '); foreach( string key in keywords ) { if (key.StartsWith(str[0], StringComparison.CurrentCultureIgnoreCase)) { if (found) { ch.SendText("----------------------------------------------------------------------------\r\n"); } ch.SendText(help.ToString()); found = true; break; } } } if (!found) { string message = String.Format("Could not find help on '{0}'. You can ask us to create a help entry for that topic by typing 'requesthelp {0}'.\r\n", str[0]); ch.SendText(message + "\r\n"); } return; }
/// <summary> /// This is meant for long-form edit mode - description editing and the like. /// /// TODO: Make this work. /// </summary> /// <param name="ch"></param> /// <param name="pString"></param> public static void StringAppend( CharData ch, ref string pString ) { ch.SendText( "Begin entering your text now (.h = help .s = show .c = clear @ = save)\r\n" ); ch.SendText( "-----------------------------------------------------------------------\r\n" ); ch.SendText( "* * String Editing Is Temporarily Disabled * *\r\n" ); return; }
public static void Glance(CharData ch, string[] str) { if( ch == null ) return; if (str.Length == 0) { ch.SendText("&nGlance at whom?\r\n"); return; } CharData victim = ch.GetCharRoom(str[0]); if (!victim) { ch.SendText("&nThey're not here.\r\n"); return; } string msg = String.Format("&nYou glance at $N&n.\r\n$N&n is {0}.", SocketConnection.ConditionString(victim)); SocketConnection.Act(msg, ch, null, victim, SocketConnection.MessageTarget.character); Look.ShowAffectLines(ch, victim); return; }