/// <summary> /// Makes a string look drunk. /// </summary> /// <param name="inputString"></param> /// <param name="ch"></param> /// <returns></returns> public static string MakeDrunk( string inputString, CharData ch ) { int drunklevel = 0; if (!ch.IsNPC()) { drunklevel = ((PC)ch).Drunk; } // Nothing to do here. if (drunklevel == 0) { return inputString; } string output = String.Empty; // Check how drunk a person is... for (int pos = 0; pos < inputString.Length; pos++) { char temp = inputString[pos]; if ((char.ToUpper(temp) >= 'A') && (char.ToUpper(temp) <= 'Z')) { int drunkpos = char.ToUpper(temp) - 'A'; if (drunklevel > _drunkSubstitution[drunkpos]._minDrunkLevel) { int randomnum = MUDMath.NumberRange(0, _drunkSubstitution[drunkpos]._numReplacements); output += _drunkSubstitution[drunkpos]._replacement[randomnum]; } else { output += temp; } } else { if (drunklevel < 4) { output += MUDMath.FuzzyNumber(temp); } else if ((temp >= '0') && (temp <= '9')) { output += MUDMath.NumberRange(0, 9).ToString(); } else { output += temp; } } } return ( output ); }
/// <summary> /// Appends a string to a file. /// </summary> /// <param name="ch"></param> /// <param name="file"></param> /// <param name="str"></param> public static void AppendFile( CharData ch, string file, string str ) { if( ch == null || String.IsNullOrEmpty(file) || String.IsNullOrEmpty(str) || ch.IsNPC() ) { return; } FileStream fp = File.OpenWrite( file ); StreamWriter sw = new StreamWriter( fp ); sw.WriteLine( "[{0}] {1}: {2}\n", ch.InRoom ? MUDString.PadInt(ch.InRoom.IndexNumber,5) : MUDString.PadInt(0,5), ch.Name, str ); sw.Flush(); sw.Close(); 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> /// 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> /// 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> /// 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> /// 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> /// Immortal command to ban a site from the game. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Ban(CharData ch, string[] str) { if( ch == null ) return; BanData ban; if (ch.IsNPC()) { return; } CharData realChar = ch.GetChar(); if (!realChar.Authorized("ban")) { return; } if (str.Length == 0) { string text = "Banned sites:\r\n"; foreach (BanData it in Database.BanList) { ban = it; text += ban.Name; text += "\r\n"; } ch.SendText(text); return; } foreach (BanData it in Database.BanList) { ban = it; if (!MUDString.StringsNotEqual(str[0], ban.Name)) { ch.SendText("That site is already banned!\r\n"); return; } } ban = new BanData(); ban.Name = str[0]; Database.BanList.Add(ban); ch.SendText("Done.\r\n"); Event.UpdateBans(); return; }
public static void Endurance(CharData ch, string[] str) { if( ch == null ) return; string arg = String.Empty; int amount; if (ch.IsNPC() || ((PC)ch).SkillAptitude["endurance"] == 0) { ch.SendText("Try all you will, but you're still your plain self.\r\n"); return; } if (!MUDString.StringsNotEqual(arg, "off")) { if (ch.HasAffect( Affect.AffectType.skill, "endurance")) { //strip the affect ch.AffectStrip( Affect.AffectType.skill, "endurance"); } else { ch.SendText("You are not using endurance.\r\n"); } return; } if (((PC)ch).SkillAptitude["endurance"] >= 95) amount = 15; else if (((PC)ch).SkillAptitude["endurance"] >= 60) amount = 10; else amount = 5; Affect af = new Affect(Affect.AffectType.skill, "endurance", 5 * ch.Level, Affect.Apply.move, amount, Affect.AFFECT_MOVEMENT_INCREASED); ch.AddAffect(af); ch.SendText("You feel the endurance of the mountains in your muscles!\r\n"); }
/// <summary> /// Emote - act like you've just performed an action. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Emote(CharData ch, string[] str) { if( ch == null ) return; if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_NO_EMOTE)) { ch.SendText("You are unable to emote.\r\n"); return; } if (ch.CurrentPosition == Position.fighting || ch.Fighting) { ch.SendText("You can't emote in combat.\r\n"); return; } if (str.Length == 0) { ch.SendText("Emote what?\r\n"); return; } string text = String.Join(" ", str ); if (text[(text.Length - 1)] != '.') { text += "."; } foreach (CharData roomChar in ch.InRoom.People) { if (roomChar == ch) continue; SocketConnection.Act("$n $t", ch, SocketConnection.TranslateText(text, ch, roomChar), roomChar, SocketConnection.MessageTarget.victim); } // MOBtrigger = false; SocketConnection.Act("$n $T", ch, null, text, SocketConnection.MessageTarget.character); return; }
/// <summary> /// Shows a character's attribute screen. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Attributes(CharData ch, string[] str) { if( ch == null ) return; string buf1 = String.Empty; if (ch.IsNPC()) { ch.SendText("&nYour attributes are as would be expected for an NPC.\r\n"); return; } if (ch.IsImmortal() && str.Length != 0) { CharData worldChar = ch.GetCharWorld(str[0]); if (!worldChar) { ch.SendText("No such person.\r\n"); return; } if (worldChar.IsNPC()) { ch.SendText("NPCs don't have skills!\r\n"); return; } } string buf = String.Format( "&+WName: &+G{0}&n &+WLevel: {1}&n\r\n", MUDString.PadStr(ch.Name, 17), ch.Level); buf1 += buf; buf = String.Format( "&+WRace:&n {0} &+WClass:&n {1} &n&+WSex:&n {2}\r\n", MUDString.PadStr(Race.RaceList[ch.GetRace()].ColorName, 16), MUDString.PadStr(ch.CharacterClass.WholistName, 16), System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(ch.GetSexString())); buf1 += buf; // Break a player's size into strings when we get around to it // -- Xangis if (!ch.IsNPC()) { buf = String.Format( "&+WHeight:&n {0} inches &+WWeight:&n {1} pounds &+WSize:&n {2}\r\n", MUDString.PadInt(((PC)ch).Height, 3), MUDString.PadInt(((PC)ch).Weight, 5), Race.SizeString(ch.CurrentSize)); } else { buf = String.Format("&+WSize:&n {0}\r\n", ch.CurrentSize); } buf1 += buf; TimeSpan time = TimeSpan.FromTicks(ch.TimePlayed.Ticks) + (DateTime.Now - ch.LogonTime); int days = (int)time.TotalHours / 24; time = (time - TimeSpan.FromDays(days)); int hours = (int)time.TotalHours; time = (time - TimeSpan.FromHours(hours)); int minutes = (int)time.TotalMinutes; // Age is a hack until we get it coded - Xangis buf = String.Format( "\r\n&+BAge:&n {0} years. &+BPlaying Time:&n {1} days {2} hours {3} minutes.\r\n", MUDString.PadInt(ch.GetAge(), 3), days, hours, minutes); buf1 += buf; // Need to create a function to display character status strings buf = String.Format("&+BStatus:&n {0}", System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(Position.PositionString(ch.CurrentPosition))); if (!ch.IsNPC() && ch.IsAffected(Affect.AFFECT_BERZERK)) { buf += ", &+Rberzerk&n"; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { buf += ", Memorizing"; } if (ch.IsAffected(Affect.AFFECT_CASTING)) { buf += ", Casting"; } if (ch.IsAffected(Affect.AFFECT_SINGING)) { buf += ", Singing"; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEDITATING)) { buf += ", Meditating"; } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_CAMPING)) { /* This is ugly and should be moved to its own function */ buf += ", Camping"; } buf += ".\r\n\r\n"; buf1 += buf; // We want players to see the same stats for levels 1-50. // Should create string converters so that we have no decimals displayed // below this point. buf = String.Format(" &+cSTR:&n {0} &+cArmor Class:&n {1}.\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrStr()), 15), ch.GetAC()); buf1 += buf; buf = String.Format(" &+cAGI:&n {0} &+cHitroll:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrAgi()), 15), StringConversion.BonusString(ch.GetHitroll(ObjTemplate.WearLocation.hand_one))); buf1 += buf; buf = String.Format(" &+cDEX:&n {0} &+cDamroll:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrDex()), 15), StringConversion.BonusString(ch.GetDamroll(ObjTemplate.WearLocation.hand_one))); buf1 += buf; buf = String.Format(" &+cCON:&n {0} &+cAlignment:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrCon()), 15), StringConversion.AlignmentString(ch)); buf1 += buf; buf = String.Format(" &n&+cINT:&n {0}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrInt()), 15)); buf1 += buf; buf = String.Format(" &+cWIS:&n {0} &+BSaving Throws&n\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrWis()), 15)); buf1 += buf; buf = String.Format(" &+cPOW:&n {0} &+cParalysis:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrPow()), 15), StringConversion.BonusString(-ch.SavingThrows[0])); buf1 += buf; buf = String.Format(" &+cCHA:&n {0} &+cRod:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrCha()), 15), StringConversion.BonusString(-ch.SavingThrows[1])); buf1 += buf; buf = String.Format(" &+cLUK:&n {0} &+cPetrify:&n {1}\r\n", MUDString.PadStr(StringConversion.AbilityScoreString(ch.GetCurrLuck()), 15), StringConversion.BonusString(-ch.SavingThrows[2])); buf1 += buf; buf = String.Format(" &+cBreath:&n {0}\r\n", StringConversion.BonusString(-ch.SavingThrows[3])); buf1 += buf; buf = String.Format("&+BWimpy: &n{0} &+cSpell:&n {1}\r\n", MUDString.PadInt(ch.Wimpy, 4), StringConversion.BonusString(-ch.SavingThrows[4])); buf1 += buf; buf = String.Format("&+BLoad Carried: &n{0} pounds ({1})\r\n", MUDString.PadInt(ch.CarryWeight, 3), StringConversion.WeightString(ch)); buf1 += buf; ch.SendText(buf1); return; }
/// <summary> /// Immortal command to echo content to the whole MUD. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Echo(CharData ch, string[] str) { if( ch == null ) return; CharData realChar = ch.GetChar(); if (!realChar.Authorized("echo")) { return; } if (str.Length == 0 || String.IsNullOrEmpty(str[0])) { ch.SendText("Echo what?\r\n"); return; } string colorCode = String.Empty; if (!ch.IsNPC() && ((PC)ch).ImmortalData != null) colorCode = ((PC)ch).ImmortalData.ImmortalColor; string content = colorCode + String.Join(" ", str) + "&n\r\n"; SocketConnection.SendToAllChar(content); 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> /// 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> /// Ingest a liquid. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Drink(CharData ch, string[] str) { if( ch == null ) return; Object obj = null; if (ch.IsBlind()) { return; } if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("You can't drink while you're fighting!\r\n"); return; } if (str.Length == 0 && ch.InRoom != null) { foreach (Object iobj in ch.InRoom.Contents) { if (iobj.ItemType == ObjTemplate.ObjectType.drink_container) { obj = iobj; break; } } if (!obj) { ch.SendText("Drink what?\r\n"); return; } } else { if (!(obj = ch.GetObjHere(str[0]))) { ch.SendText("You can't find it.\r\n"); return; } } // Allow bards to get twice as drunk as other classes - Xangis if (!ch.IsNPC() && !ch.IsImmortal() && ((PC)ch).Drunk > 15 && ch.IsClass(CharClass.Names.bard) && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk) { ch.SendText("You fail to reach your mouth. *Hic*\r\n"); return; } if (!ch.IsNPC() && !ch.IsImmortal() && ((PC)ch).Drunk > 25 && ch.IsClass(CharClass.Names.bard) && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk) { ch.SendText("You fail to reach your mouth. *Hic*\r\n"); return; } switch (obj.ItemType) { default: ch.SendText("You can't drink from that.\r\n"); break; case ObjTemplate.ObjectType.drink_container: // -1 Means a container never goes empty. if (obj.Values[1] <= 0 && obj.Values[1] != -1) { ch.SendText("It is already &+Lempty&n.\r\n"); return; } /* No drinking if you're full */ if ((!ch.IsImmortal()) && ( (!ch.IsNPC() && ((PC)ch).Thirst > 40) || (!ch.IsNPC() && ((PC)ch).Hunger > 50))) { ch.SendText("You couldn't possibly drink any more.\r\n"); return; } int liquid; if ((liquid = obj.Values[2]) >= Liquid.Table.Length) { Log.Error("Drink: bad liquid number {0}.", liquid); liquid = obj.Values[2] = 0; } SocketConnection.Act("You drink $T from $p&n.", ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.character); SocketConnection.Act("$n&n drinks $T from $p&n.", ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.room); int amount = MUDMath.NumberRange(3, 10); if (obj.Values[0] != -1) { amount = Math.Min(amount, obj.Values[1]); } ch.AdjustDrunk(amount * Liquid.Table[liquid].DrunkValue); if (!ch.IsUndead()) { ch.AdjustHunger(amount * Liquid.Table[liquid].HungerValue); if (ch.IsAffected(Affect.AFFECT_THIRST)) { ch.AdjustThirst((amount * Liquid.Table[liquid].ThirstValue) / 12); ch.SendText("That doesn't taste as &+bwet&n as it used to.\r\n"); } else { ch.AdjustThirst(amount * Liquid.Table[liquid].ThirstValue); } } else { /* If blood */ if (Liquid.Table[liquid].Name == "blood") { ch.AdjustHunger(amount * 2); ch.AdjustThirst(amount); } } if (!ch.IsNPC() && ((PC)ch).Drunk > 10) { ch.SendText("You feel &n&+gdrunk&n.\r\n"); } if (!ch.IsNPC() && ((PC)ch).Hunger > 20) { ch.SendText("You are &n&+yfull&n.\r\n"); } if (!ch.IsNPC() && ((PC)ch).Thirst > 20) { ch.SendText("You do not feel &n&+cth&+Ci&n&+cr&+Cst&n&+cy&n.\r\n"); } if (obj.Values[3] != 0 && !CharData.CheckImmune(ch, Race.DamageType.poison)) { /* The shit was poisoned ! */ Affect af = new Affect(); ch.SendText("You choke and gag.\r\n"); SocketConnection.Act("$n chokes and gags.", ch, null, null, SocketConnection.MessageTarget.room); af.Type = Affect.AffectType.spell; af.Value = "poison"; af.Duration = 3 * amount; af.AddModifier(Affect.Apply.strength, -(obj.Level / 7 + 1)); af.SetBitvector(Affect.AFFECT_POISON); ch.CombineAffect(af); } /* HOLY_WATER and UNHOLY_WATER effects */ if ((ch.IsGood() && obj.Values[2] == 27) || (ch.IsEvil() && obj.Values[2] == 28)) { int heal = MUDMath.Dice(1, 8); if (ch.Hitpoints < ch.GetMaxHit()) { ch.Hitpoints = Math.Min(ch.Hitpoints + heal, ch.GetMaxHit()); ch.UpdatePosition(); ch.SendText("You feel a little better!\r\n"); } } if ((ch.IsEvil() && obj.Values[2] == 27) || (ch.IsGood() && obj.Values[2] == 28)) { int harm = MUDMath.Dice(1, 10); ch.Hitpoints = Math.Max(ch.Hitpoints - harm, -10); ch.SendText("You choke and feel as if you'd swallowed boiling oil!\r\n"); ch.UpdatePosition(); } /* End (UN)HOLY_WATER effects */ // -1 Means a container never goes empty. if (obj.Values[1] != -1) { obj.Values[1] -= amount; if (obj.Values[1] <= 0) { ch.SendText("The container is now &+Lempty&n.\r\n"); obj.Values[1] = 0; } } break; } return; }
/// <summary> /// Command to forget a spell. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Forget(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (str.Length == 0) { ch.SendText("Looks like your forgot what you were going to forget.\r\n"); return; } if (((PC)ch).Memorized.Count == 0) { ch.SendText("You don't have anything to forget.\r\n"); return; } if (!MUDString.StringsNotEqual(str[0], "all")) { Magic.ForgetAllSpells(ch); ch.SendText("You forget everything.\r\n"); return; } Spell spell = StringLookup.SpellLookup(str[0]); if (spell == null) { ch.SendText("Forget what?\r\n"); return; } foreach (MemorizeData mem in ((PC)ch).Memorized) { if (mem.Name == spell.Name) { string buf = String.Format("You forget {0}.\r\n", spell.Name); ch.SendText(buf); // Remove the memorization data from the player. if (!((PC)ch).Memorized.Remove(mem)) { Log.Error("Unable to remove memorization data from player", 0); } return; } } ch.SendText("You do not have that spell memorized.\r\n"); return; }
public static void Fortitude(CharData ch, string[] str) { if( ch == null ) return; string arg = String.Empty; int amount; if (ch.IsNPC() || ((PC)ch).SkillAptitude["fortitude"] == 0) { ch.SendText("Try all you will, but you're still your plain self.\r\n"); return; } if (!MUDString.StringsNotEqual(arg, "off")) { if (ch.HasAffect( Affect.AffectType.skill, "fortitude")) { //strip the affect ch.AffectStrip( Affect.AffectType.skill, "fortitude"); } else { ch.SendText("You are not using fortitude.\r\n"); } return; } if (((PC)ch).SkillAptitude["fortitude"] >= 95) amount = 15; else if (((PC)ch).SkillAptitude["fortitude"] >= 60) amount = 10; else amount = 5; Affect af = new Affect(Affect.AffectType.skill, "fortitude", 5 * ch.Level, Affect.Apply.constitution, amount, Affect.AFFECT_NONE); ch.AddAffect(af); ch.SendText("You feel more fortified.\r\n"); }
/// <summary> /// Shows items currently worn. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Equipment(CharData ch, string[] str) { if (ch == null) return; Object obj = null; String equipmentOpen = String.Empty; String equipmentClose = String.Empty; String separator = String.Empty; if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { equipmentOpen = "<equipment>"; equipmentClose = "</equipment>"; separator = ":"; } else { equipmentOpen = "&nYou are using:\r\n"; separator = "\r\n"; } ch.SendText(equipmentOpen); bool found = false; foreach (ObjTemplate.WearLocation iWear in ObjTemplate.TopDownEquipment) { obj = Object.GetEquipmentOnCharacter(ch, iWear); if (!obj) continue; // Added wielding if (obj.ItemType == ObjTemplate.ObjectType.weapon && (iWear == ObjTemplate.WearLocation.hand_one || iWear == ObjTemplate.WearLocation.hand_four || iWear == ObjTemplate.WearLocation.hand_three || iWear == ObjTemplate.WearLocation.hand_two) && obj.HasWearFlag(ObjTemplate.WEARABLE_WIELD)) { if (obj.HasFlag(ObjTemplate.ITEM_TWOHANDED) && !ch.HasInnate(Race.RACE_EXTRA_STRONG_WIELD)) { if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText(((int)iWear).ToString() + ","); } else { ch.SendText("&+y(wielding twohanded) &n"); } } else { if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText(((int)iWear).ToString() + ","); } else { ch.SendText("&+y(wielding) &n"); } } } else { if (obj.ItemType == ObjTemplate.ObjectType.shield && (iWear == ObjTemplate.WearLocation.hand_one || iWear == ObjTemplate.WearLocation.hand_four || iWear == ObjTemplate.WearLocation.hand_three || iWear == ObjTemplate.WearLocation.hand_two) && obj.HasWearFlag(ObjTemplate.WEARABLE_SHIELD)) { if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText(((int)iWear).ToString() + ","); } else { ch.SendText("&+y(worn as shield) &n"); } } else { if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED) { ch.SendText(((int)iWear).ToString() + ","); } else { ch.SendText(StringConversion.EquipmentLocationDisplay[(int)iWear]); } } } if (CharData.CanSeeObj(ch, obj)) { ch.SendText(Look.FormatObjectToCharacter(obj, ch, true)); ch.SendText(separator); } else { ch.SendText("&nsomething.\r\n"); } found = true; } if (!found) ch.SendText("&nNothing.\r\n"); ch.SendText(equipmentClose); return; }
public static void GodMode(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (!ch.Authorized("godmode")) return; if (ch.HasActionBit(PC.PLAYER_GODMODE)) { ch.RemoveActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode off.\r\n"); } else { ch.SetActionBit(PC.PLAYER_GODMODE); ch.SendText("God mode on.\r\n"); } return; }
/// <summary> /// Shows available room exits. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Exits(CharData ch, string[] str) { if( ch == null ) return; Exit exit; int door; bool auto = (str.Length != 0 && !MUDString.StringsNotEqual(str[0], "auto")); if (ch.IsBlind() || !ch.InRoom) { return; } string text; if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED && auto) { text = "<exits>"; } else { text = auto ? "&+cExits: &n" : "&+cVisible exits:&n\r\n"; } bool found = false; // Show the direction with an asterisk if it // has a closed door, and in exits command it shows up as a // closed <whatever>. for (door = 0; door < Limits.MAX_DIRECTION; ++door) { exit = ch.InRoom.ExitData[door]; if (exit && exit.TargetRoom) { if (exit.HasFlag(Exit.ExitFlag.secret)) { /* Mortals do not see secret exits. */ if (ch.Level < Limits.LEVEL_AVATAR) continue; /* Mark secret exits for immortals. */ text += "&+LS&n&+c"; } if (exit.HasFlag(Exit.ExitFlag.blocked)) { /* Mortals do not see secret exits. */ if (ch.Level < Limits.LEVEL_AVATAR) continue; /* Mark secret exits for immortals. */ text += "&+yB&n&+c"; } found = true; if (auto) { if (exit.HasFlag(Exit.ExitFlag.walled) && exit.HasFlag(Exit.ExitFlag.illusion)) continue; if (exit.HasFlag(Exit.ExitFlag.closed)) text += "&n&+y#&n&+c"; // Don't show exits to impassable rooms. // Show a yellow exclamation point to those with holylight on though. if (exit.TargetRoom && exit.TargetRoom.TerrainType == TerrainType.underground_impassable) { if (!ch.HasActionBit(PC.PLAYER_GODMODE)) { continue; } text += "&+Y!&n"; } text += door.ToString(); text += " "; } else { if (exit.HasFlag(Exit.ExitFlag.walled)) { text += String.Format("&n{0} - (Walled)&n\r\n", MUDString.PadStr(door.ToString().ToUpper(), 5)); } else if (!exit.HasFlag(Exit.ExitFlag.closed)) { // gods with holylight on can go to useless exits. if (exit.TargetRoom && exit.TargetRoom.TerrainType == TerrainType.underground_impassable) { if (!ch.HasActionBit(PC.PLAYER_GODMODE)) { continue; } text += "&+Y!&n"; } text += String.Format("&n {0} - {1}&n\r\n", MUDString.PadStr(door.ToString().ToUpper(), 5), (!ch.HasInnate(Race.RACE_ULTRAVISION) && Room.GetRoom(exit.IndexNumber).IsDark()) ? "&nToo dark to tell" : exit.TargetRoom.Title); } else { text += String.Format("&+y#&n{0} - Closed {1}\r\n", MUDString.PadStr(door.ToString().ToUpper(), 5), exit.Keyword); } } } } if (!found) { text += auto ? " none" : "&nNone.\r\n"; } if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED && auto) { text += "&n</exits>"; } else if (auto) { text += "&n\r\n"; } ch.SendText(text); 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; }
public static void Finger(CharData ch, string[] str) { if( ch == null ) return; CharData victim; SocketConnection victDD; bool loggedIn; if (ch.IsNPC()) return; if (str.Length == 0) { ch.SendText("Finger whom?\r\n"); return; } /* Look for the character logged in. */ if ((victim = ch.GetCharWorld(str[0]))) { if (victim.IsNPC()) { ch.SendText("Don't finger mobs.\r\n"); return; } if (!victim.Socket) { ch.SendText("Character is linkdead.\r\n"); if (!CharData.LoadPlayer((victDD = new SocketConnection()), str[0])) { /* If not in save files, they don't exist. */ ch.SendText("This character does not exist.\r\n"); return; } loggedIn = false; } else { loggedIn = true; ch.SendText("This character is logged in.\r\n"); victDD = victim.Socket; } } /* If not, then load from save files. */ else { loggedIn = false; if (!(CharData.LoadPlayer((victDD = new SocketConnection()), str[0].ToUpper()))) { /* If not in save files, they don't exist. */ ch.SendText("This character does not exist.\r\n"); return; } else ch.SendText("This character is not logged in.\r\n"); victim = victDD.Original ? victDD.Original : victDD.Character; } /* Display general character info. */ string buf = String.Format("Name: {0}. Title: {1}&n.\r\n", victDD.Original ? victDD.Original.Name : victDD.Character ? victDD.Character.Name : "(none)", (!victim.IsNPC() && ((PC)victim).Title.Length != 0) ? ((PC)victim).Title : "(none)"); ch.SendText(buf); buf = String.Format("Guild: {0}&n. Level: {1}&n.\r\n", (!victim.IsNPC() && ((PC)victim).GuildMembership != null) ? ((PC)victim).GuildMembership.Name : "(none)", victim.Level); ch.SendText(buf); buf = String.Format("Class: {0}&n. Room: {1}&n. Race: {2}&n.\r\n", (victim.CharacterClass != null ? victim.CharacterClass.WholistName : "(Undefined)"), victim.InRoom ? victim.InRoom.IndexNumber : -1, (victim.GetRace() < Race.RaceList.Length && victim.GetRace() >= 0) ? Race.RaceList[victim.GetRace()].ColorName : "(Undefined)"); ch.SendText(buf); /* Messages specific to whether a player is logged in. */ if (loggedIn) { if (victim.InRoom) { buf = String.Format("In room: {0}&n ({1}).\r\n", victim.InRoom.Title.Length != 0 ? victim.InRoom.Title : "(none)", victim.InRoom.IndexNumber); ch.SendText(buf); } buf = String.Format("On since: {0}", victim.LogonTime); } else buf = String.Format("Created: {0} Birthdate: {1}", ((PC)victim).Created, ((PC)victim).Birthdate); ch.SendText(buf); if (loggedIn) { buf = String.Format("Last save: {0}", victim.SaveTime); ch.SendText(buf); } else { buf = String.Format("Last logged in: {0}", victim.SaveTime); ch.SendText(buf); } /* Close rented chars pfile (w/out saving!). */ if (!loggedIn) victDD = null; 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> /// A basic bandage self command, usable once per day. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void FirstAid(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) return; if (ch.Fighting || ch.CurrentPosition == Position.fighting) { ch.SendText("You can't do that while fighting!\r\n"); return; } if (((PC)ch).FirstaidTimer > 0) { ch.SendText("You can only first aid once per day.\r\n"); return; } if (ch.Hitpoints < ch.GetMaxHit()) { ch.Hitpoints += MUDMath.Dice(3, (ch.Level / 2)) + 1; if (((PC)ch).SkillAptitude["bandage"] > 9) { ch.Hitpoints += ((PC)ch).SkillAptitude["bandage"] / 8; ch.PracticeSkill("bandage"); } if (ch.Hitpoints > ch.GetMaxHit()) { ch.Hitpoints = ch.GetMaxHit(); } } ((PC)ch).FirstaidTimer = 24; ch.SendText("You attempt to render first aid unto yourself.\r\n"); return; }
/* * 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> /// Flee: Attempt to run away from combat. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Flee(CharData ch, string[] str) { if( ch == null ) return; int attempt; int chances; if (ch.CurrentPosition < Position.reclining || ch.Wait > 0) { return; } // Remove memorization and meditation bits - Xangis if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEDITATING)) { SocketConnection.Act("$N&n is disrupted from meditation.", ch, null, null, SocketConnection.MessageTarget.room); SocketConnection.Act("Your meditation is disrupted.", ch, null, null, SocketConnection.MessageTarget.character); ch.RemoveActionBit(PC.PLAYER_MEDITATING); } if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_MEMORIZING)) { SocketConnection.Act("$N&n abandons $S studies.", ch, null, null, SocketConnection.MessageTarget.room); SocketConnection.Act("You abandon your studies.", ch, null, null, SocketConnection.MessageTarget.character); ch.RemoveActionBit(PC.PLAYER_MEMORIZING); } if (ch.CurrentPosition < Position.fighting) { ch.SendText("You scramble madly to your feet!\r\n"); SocketConnection.Act("$n&n scrambles madly to $s feet!", ch, null, null, SocketConnection.MessageTarget.room); ch.CurrentPosition = Position.standing; return; } if (!ch.InRoom) { ch.SendText("You give up when you realize there's nowhere to flee to.\r\n"); } // Panicked people can flee when not fighting. CharData victim = ch.Fighting; if (!victim) { if (ch.CurrentPosition == Position.fighting) { ch.CurrentPosition = Position.standing; } } if (ch.IsAffected(Affect.AFFECT_BERZERK)) { ch.SendText("You can't flee, you're in a &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n!!\r\n"); return; } if (ch.IsAffected( Affect.AFFECT_BOUND)) { ch.SendText("You are bound! You can't move!\r\n"); SocketConnection.Act("$n&n tries to flee, but is tied up!", ch, null, null, SocketConnection.MessageTarget.room); return; } if (ch.IsAffected( Affect.AFFECT_HOLD) || ch.IsAffected( Affect.AFFECT_MINOR_PARA)) { ch.SendText("You can't move!\r\n"); SocketConnection.Act("$n&n tries to flee, but $e can't move!", ch, null, null, SocketConnection.MessageTarget.room); return; } // You should almost always be able to flee when not fighting. if (ch.CurrentPosition == Position.standing) { chances = 30; } else { chances = 6; } Room wasIn = ch.InRoom; for (attempt = 0; attempt < chances; attempt++) { Exit exit; Exit.Direction door = Database.RandomDoor(); if ((exit = wasIn.GetExit(door)) == null || !exit.TargetRoom || exit.TargetRoom == wasIn || exit.HasFlag(Exit.ExitFlag.closed) || (ch.IsNPC() && (Room.GetRoom(exit.IndexNumber).HasFlag(RoomTemplate.ROOM_NO_MOB) || (ch.HasActionBit(MobTemplate.ACT_STAY_AREA) && exit.TargetRoom.Area != ch.InRoom.Area)))) { continue; } if (ch.Riding && ch.Riding.Fighting) { Combat.StopFighting(ch.Riding, true); } // Just to keep the damned messages from being wacky... ch.SetAffectBit(Affect.AFFECT_IS_FLEEING); ch.Move(door); ch.RemoveAffect(Affect.AFFECT_IS_FLEEING); if (ch.InRoom == wasIn) { break; } Room nowIn = ch.InRoom; ch.InRoom = wasIn; SocketConnection.Act("$n&n panics and attempts to flee...", ch, null, null, SocketConnection.MessageTarget.room, true); string text; if (ch.CheckSneak()) { SocketConnection.Act("$n&n has fled!", ch, null, null, SocketConnection.MessageTarget.room); } else { text = String.Format("$n&n flees {0}ward.", door.ToString()); SocketConnection.Act(text, ch, null, null, SocketConnection.MessageTarget.room, true); } ch.InRoom = nowIn; text = String.Format("You flee {0}ward!\r\n", door.ToString()); ch.SendText(text); Combat.StopFighting(ch, true); return; } SocketConnection.Act("$n&n tries to flee but can't make it out of here!", ch, null, null, SocketConnection.MessageTarget.room, true); ch.SendText("&+WYour escape is blocked!\r\n"); return; }
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; }
public static void Aware(CharData ch, string[] str) { if( ch == null ) return; Affect af = new Affect(); if (ch.IsNPC()) return; if (!ch.HasSkill("awareness")) { ch.SendText("Your general obliviousness prevents your use of this skill.\r\n"); return; } if (ch.IsAffected(Affect.AFFECT_SKL_AWARE)) { ch.SendText("You are already about as tense as you can get.\r\n"); return; } ch.SendText("You try to become more aware of your surroundings.\r\n"); ch.PracticeSkill("awareness"); af.Value = "awareness"; af.Type = Affect.AffectType.skill; af.Duration = (ch.Level / 3) + 3; af.SetBitvector(Affect.AFFECT_SKL_AWARE); ch.AddAffect(af); 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> /// Fog: Immortal command to turn combat vulnerability on or off. /// </summary> /// <param name="ch"></param> /// <param name="str"></param> public static void Fog(CharData ch, string[] str) { if( ch == null ) return; if (ch.IsNPC()) { return; } if (!ch.Authorized("fog")) { return; } ch.ToggleActionBit(PC.PLAYER_FOG); if (ch.HasActionBit(PC.PLAYER_FOG)) { ch.SendText("Fog is now on.\r\n"); } else { ch.SendText("Fog is now off.\r\n"); } return; }