/// <summary> /// Default constructor. /// </summary> public Object() { ++_numObjects; _createdBy = null; _itemType = ObjTemplate.ObjectType.trash; _material = 0; _size = 0; _volume = 0; _craftsmanship = 0; _wearLocation = 0; _weight = 0; _cost = 0; _level = 1; _timer = -1; _condition = 100; _flyLevel = CharData.FlyLevel.ground; int count; for( count = 0; count < Limits.NUM_ITEM_EXTRA_VECTORS; ++count ) _extraFlags[ count ] = 0; for (count = 0; count < Limits.NUM_USE_FLAGS_VECTORS; ++count) _antiFlags[count] = 0; for (count = 0; count < Limits.NUM_WEAR_FLAGS_VECTORS; ++count) _wearFlags[count] = 0; for (count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count) _affectedBy[ count ] = 0; for( count = 0; count < 8; ++count ) _values[ count ] = 0; }
/// <summary> /// Finds an exit based on a keyword. Use FindDoor if you are looking for a door. /// </summary> /// <param name="ch"></param> /// <param name="arg"></param> /// <returns></returns> public static Exit.Direction FindExit( CharData ch, string arg ) { Exit exit; Exit.Direction door = Exit.DoorLookup(arg); if( door == Exit.Direction.invalid ) { for (int doornum = 0; doornum < Limits.MAX_DIRECTION; doornum++) { if ((exit = ch.InRoom.ExitData[doornum]) && exit.HasFlag(Exit.ExitFlag.is_door) && !(ch.Level < Limits.LEVEL_AVATAR && exit.ExitFlags != 0 && (exit.HasFlag(Exit.ExitFlag.secret) || exit.HasFlag(Exit.ExitFlag.blocked))) && exit.Keyword.Length != 0 && ("door".Equals(arg, StringComparison.CurrentCultureIgnoreCase) || MUDString.NameContainedIn(arg, exit.Keyword))) { return (Exit.Direction)doornum; } } SocketConnection.Act( "I see no $T here.", ch, null, arg, SocketConnection.MessageTarget.character ); return Exit.Direction.invalid; } if( !( exit = ch.InRoom.ExitData[ (int)door ] ) ) { SocketConnection.Act( "I see no door $T here.", ch, null, arg, SocketConnection.MessageTarget.character ); return Exit.Direction.invalid; } return door; }
/// <summary> /// Song of chaos. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongChaos( CharData ch, Spell spell, int level, Target target ) { foreach( CharData victim in ch.InRoom.People ) { } return true; }
/// <summary> /// Finds a door based on a keyword or direction. Use FindExit if you only need to get an exit, /// no door required. This should _not_ tell the character anything; it is an internal function. /// </summary> /// <param name="ch"></param> /// <param name="arg"></param> /// <returns></returns> public static Exit.Direction FindDoor( CharData ch, string arg ) { Exit exit; Exit.Direction door = Exit.DoorLookup(arg); if (door == Exit.Direction.invalid) { for( int doornum = 0; doornum < Limits.MAX_DIRECTION; doornum++ ) { if ((exit = ch.InRoom.ExitData[doornum]) && exit.HasFlag(Exit.ExitFlag.is_door) && !(ch.Level < Limits.LEVEL_AVATAR && exit.ExitFlags != 0 && (exit.HasFlag(Exit.ExitFlag.secret) || exit.HasFlag(Exit.ExitFlag.blocked))) && exit.Keyword.Length != 0 && ("door".Equals(arg, StringComparison.CurrentCultureIgnoreCase) || MUDString.NameContainedIn(arg, exit.Keyword))) { return (Exit.Direction)doornum; } } return Exit.Direction.invalid; } exit = ch.InRoom.GetExit(door); if( !exit ) { return Exit.Direction.invalid; } if (!exit.HasFlag(Exit.ExitFlag.is_door)) { return Exit.Direction.invalid; } return door; }
/// <summary> /// Song of calming. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="target"></param> /// <returns></returns> public static bool SongCalming( CharData ch, Spell spell, int level, Target target ) { foreach( CharData victim in ch.InRoom.People ) { Combat.StopFighting( victim, false ); victim.WaitState( 2 ); } return true; }
/// <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> /// 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; }
/// <summary> /// Shout for one's minions to come and attack the victim. /// </summary> /// <param name="mob"></param> /// <param name="victim"></param> /// <param name="msg"></param> /// <param name="helpers"></param> /// <returns></returns> static bool ShoutAndHunt( System.Object mob, CharData victim, string msg, int[] helpers ) { if (mob == null) return false; int count = 0; CharData ch = (CharData)mob; // Send the shout message string buf = String.Format( msg, victim.Name ); CommandType.Interpret(ch, "shout " + buf); if (helpers[0] == 0) { return false; } // Loop through all chars foreach (CharData worldChar in Database.CharList) { if( !worldChar.InRoom ) continue; if( !worldChar.MobileTemplate ) continue; if( !worldChar.IsNPC() || worldChar.InRoom.Area != ch.InRoom.Area ) continue; bool isHelper = false; int i; for( i = 0; helpers[ i ] > 0; i++ ) { if (worldChar.MobileTemplate.IndexNumber == helpers[i]) { isHelper = true; } } if (!isHelper) { continue; } Combat.StartGrudge( worldChar, victim, true ); ++count; } if (count > 0) { return true; } return false; }
// Keep in mind that any healing spells that give affects to the mob // will only be able to be cast if they are not affected by them because // the CheckSpellup _function checks to see if they are affected by // that spell, so a heal spell that heals *and* blesses will not work // properly and we'll need to write a new _function for it -- Xangis static bool HealSelf( CharData ch ) { if (ch == null) return false; if (CheckSpellup(ch, "heal", 75)) return true; return false; }
// This _function should prevent a mob from spamming // spellups on itself if it is already affected by the spell. // in the Spellup() _function, checks for Affect.AFFECT_WHATEVER // still need to be done. - Xangis static bool CheckSpellup( CharData ch, string name, int percent ) { if (ch == null) return false; if (String.IsNullOrEmpty(name)) return false; Spell spell = Spell.SpellList[name]; if (spell == null) { return false; } // Keep mobs from casting spells they are affected by if( ch.HasAffect( Affect.AffectType.spell, spell ) ) return false; if( ( ch.HasSpell( name ) ) && ( MUDMath.NumberPercent() < percent ) ) { if (spell.ValidTargets != TargetType.singleCharacterDefensive && spell.ValidTargets != TargetType.self) Log.Error( "CheckSpellup: Mob casting spell {0} which is neither TargetType.self nor TargetType.defensive.", spell ); SocketConnection.Act( "$n&n starts casting...", ch, null, null, SocketConnection.MessageTarget.room ); ch.SetAffectBit( Affect.AFFECT_CASTING ); CastData caster = new CastData(); caster.Who = ch; caster.Eventdata = Event.CreateEvent(Event.EventType.spell_cast, spell.CastingTime, ch, ch, spell); Database.CastList.Add( caster ); return true; } return false; }
/* * If a spell casting mob is hating someone, try to summon them. * * Xangis - Need to add code to also gate to the person if they can't be summoned */ static void SummonIfHating( CharData ch ) { string name = String.Empty; string buf = String.Empty; if( ch.Fighting || ch.Fearing || ch.Hating.Count == 0 || ch.InRoom.HasFlag( RoomTemplate.ROOM_SAFE ) ) return; /* If summoner is busy hunting someone aleady, don't summon. */ if( ch.Hunting ) return; CharData victim = ch.GetRandomHateTarget( false ); // Pretty stupid to summon someone who's in the same room. if( !victim || ch.InRoom == victim.InRoom ) return; if( ( ch.HasSpell( "relocate" ) )) { if( !victim.IsNPC() ) buf += "relocate 0." + name; else buf += "relocate " + name; } else if( ch.HasSpell( "summon" ) ) { if( !victim.IsNPC() ) buf += "summon 0." + name; else buf += "summon " + name; } else if ((ch.Level * 4 - 3) >= Spell.SpellList["spirit jump"].SpellCircle[(int)ch.CharacterClass.ClassNumber]) { if( !victim.IsNPC() ) buf += "'spirit jump' 0." + name; else buf += "'spirit jump' " + name; } CommandType.Interpret(ch, "cast " + buf); return; }
static bool SpellupOthers( CharData ch ) { if (ch == null) return false; if (ch.InRoom.HasFlag(RoomTemplate.ROOM_NO_MAGIC)) return false; if( !ch.IsAwake() || ch.Fighting ) return false; if( !ch.CanSpeak() ) return false; CharData victim = null; foreach( CharData ivictim in ch.InRoom.People ) { if (ivictim != ch && CharData.CanSee(ch, ivictim) && MUDMath.NumberBits(1) == 0 && ivictim.IsNPC()) { victim = ivictim; break; } } if( !victim ) return false; if( victim.Hitpoints < ( victim.GetMaxHit() - 10 ) ) { if( CheckDefensive( ch, victim, "full heal", 75 ) ) return true; if( CheckDefensive( ch, victim, "aid", 60 ) ) return true; if( CheckDefensive( ch, victim, "heal", 75 ) ) return true; if( CheckDefensive( ch, victim, "mending", 75 ) ) return true; } if (!victim.IsAffected(Affect.AFFECT_HASTE)) if( CheckDefensive( ch, victim, "haste", 45 ) ) return true; return false; }
static bool SpecGrumbarShout( System.Object mob, int cmd ) { if (mob == null) return false; int[] helpers = new[] {9500, 9501, 9502, 9503, 9504, 9505, 9506, 9507, 9508, 9509, 9510, 0}; if( cmd == PROC_DEATH ) return false; CharData ch = (CharData)mob; if( !ch || !ch.IsAwake() ) return false; if( !ch.Fighting ) { _wasFighting = null; return false; } if( ch.Fighting == _wasFighting ) return false; _wasFighting = ch.Fighting; return ShoutAndHunt( ch, ch.Fighting, "&+LDenizens of the Earth plane, {0} has trespassed upon us!", helpers ); }
public static Exit.Direction FindPath( int inRoomIndexNumber, int outRoomIndexNumber, CharData ch, int depth, bool inZone ) { RoomTemplate herep; RoomTemplate startp; Exit exitp; RoomQ tmp_q; RoomQ q_head; RoomQ q_tail; HashHeader x_room = null; bool throughDoors; int i; int tmp_room; int count = 0; // TODO: Re-enable this. return Exit.Direction.invalid; if (depth < 0) { throughDoors = true; depth = -depth; } else { throughDoors = false; } startp = Room.GetRoom(inRoomIndexNumber); InitHashTable(x_room, sizeof(int), 2048); //HashEnter(x_room, inRoomIndexNumber, null); /* initialize queue */ q_head = new RoomQ(); q_tail = q_head; q_tail.RoomNR = inRoomIndexNumber; q_tail.NextQ = null; while (q_head != null) { herep = Room.GetRoom(q_head.RoomNR); /* for each room test all directions */ if (herep.Area == startp.Area || inZone == false) { /* * only look in this zone... * saves cpu time and makes world safer for players */ for (i = 0; i < Limits.MAX_DIRECTION; i++) { exitp = herep.ExitData[i]; if (ExitOk(exitp) != 0 && (throughDoors ? GO_OK_SMARTER : Macros.IsSet((int)Room.GetRoom(q_head.RoomNR).ExitData[i].ExitFlags, (int)Exit.ExitFlag.closed))) { /* next room */ tmp_room = herep.ExitData[i].TargetRoom.IndexNumber; if (tmp_room != outRoomIndexNumber) { /* * shall we add room to queue ? * count determines total breadth and depth */ if (!hash_find(x_room, tmp_room) && (count < depth)) /* && !IS_SET( RM_FLAGS(tmp_room), DEATH ) ) */ { ++count; /* mark room as visted and put on queue */ tmp_q = new RoomQ(); tmp_q.RoomNR = tmp_room; tmp_q.NextQ = null; q_tail.NextQ = tmp_q; q_tail = tmp_q; /* Ancestor for first layer is the direction */ /*HashEnter(x_room, tmp_room, ((long)hash_find(x_room, q_head.RoomNR) == -1) ? (Object)(i + 1) : hash_find(x_room, q_head.RoomNR));*/ } } else { /* have reached our goal so free queue */ tmp_room = q_head.RoomNR; for (; q_head != null; q_head = tmp_q) { tmp_q = q_head.NextQ; q_head = null; } /* return direction if first layer */ /*if ((long)hash_find(x_room, tmp_room) == -1) { if (x_room.Buckets) { // junk left over from a previous track DestroyHashTable(x_room, null); } return (i);*/ //} //else { /* else return the Ancestor */ //long j; /*j = (long)hash_find(x_room, tmp_room); if (x_room.Buckets) { // junk left over from a previous track DestroyHashTable(x_room, null); } return (-1 + j);*/ } } } } } /* free queue head and point to next entry */ tmp_q = q_head.NextQ; q_head = null; q_head = tmp_q; } /* couldn't find path */ /*if (x_room.Buckets) { // junk left over from a previous track DestroyHashTable(x_room, null); }*/ return Exit.Direction.invalid; }
/// <summary> /// Check for use of Direct targeted spells (TargetType.singleCharacterOffensive) /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> /// <param name="spell"></param> /// <param name="percent"></param> /// <returns></returns> public static bool CheckOffensive( CharData ch, CharData victim, Spell spell, int percent ) { if (ch == null) return false; string buf = String.Format("CheckOffensive: spell ({0})'{1}'", spell, spell.Name); Log.Trace( buf ); if( spell == null ) return false; if( ch.HasSpell(spell) && ( MUDMath.NumberPercent() < percent ) ) { if (spell.ValidTargets != TargetType.singleCharacterOffensive && spell.ValidTargets != TargetType.none && spell.ValidTargets != TargetType.singleCharacterRanged) Log.Error( "Check_spellup: Mob casting spell {0} which is neither _targetType offensive nor ignore.a", spell ); SocketConnection.Act( "$n&n starts casting...", ch, null, null, SocketConnection.MessageTarget.room ); ch.SetAffectBit( Affect.AFFECT_CASTING ); CastData caster = new CastData(); caster.Who = ch; caster.Eventdata = Event.CreateEvent(Event.EventType.spell_cast, spell.CastingTime, ch, victim, spell); Database.CastList.Add( caster ); return true; } return false; }
/// <summary> /// Check for casting of vigorize spells. /// </summary> /// <param name="ch"></param> /// <returns></returns> public static bool CheckVigorize( CharData ch ) { if (ch == null) return false; if (ch.CurrentMoves > 30) return false; if( CheckSpellup( ch, "stamina", 35 ) ) return true; return false; }
/// <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()); } }
// Checks for a mob spelling itself up. Certain spells have higher // priority and percentage chances. // // The spell_lookup _function is horribly inefficient and anywhere possible // should be replaced with _skillNumber's (Spell.SpellNumber_armor and whatever) - Xangis // // The commented out spells have not been written yet. // // The CheckSpellup _function automatically checks to see whether they // are effected by the particular spell, so unless the spell has an // associated bitvector, there is no need for extra logic. // // Spells with associated bitvectors will need the "CharData.IsAffected" stuff // before the if( CheckSpellup( ... ) ) for the particular spell static bool Spellup( CharData ch ) { if (ch == null) return false; if (ch.IsAffected(Affect.AFFECT_BLIND)) { if( CheckSpellup( ch, "purify spirit", 35 ) ) return true; } if( !ch.IsAffected( Affect.AFFECT_BLUR ) ) if( CheckSpellup( ch, "blur", 45 ) ) return true; /* Fireshield and Frostshield cancel eachother! So, we don't want * that to happen. Easiest way is to give a chance to try either. * Odds are, if they only have one of the two, that they'll take twice * as long to cast it on themselves. Yes, this is a quick fix. */ if( !ch.IsAffected( Affect.AFFECT_FIRESHIELD ) && !ch.IsAffected( Affect.AFFECT_COLDSHIELD ) ) { if( MUDMath.NumberPercent() < 50 ) { if( CheckSpellup( ch, "fireshield", 30 ) ) return true; } else if( CheckSpellup( ch, "coldshield", 30 ) ) return true; } if( CheckSpellup( ch, "vitality", 55 ) ) return true; return false; }
public static void ReturnToLoad( CharData ch ) { if( !ch || !ch.InRoom ) return; if( ch.InRoom.Area != Room.GetRoom( ch.LoadRoomIndexNumber ).Area ) return; Exit.Direction dir = FindPath( ch.InRoom.IndexNumber, ch.LoadRoomIndexNumber, ch, -40000, true ); if( dir == Exit.Direction.invalid ) { return; } if( ch.InRoom.ExitData[ (int)dir ].HasFlag( Exit.ExitFlag.closed ) && !ch.IsAffected( Affect.AFFECT_PASS_DOOR ) && !ch.HasInnate( Race.RACE_PASSDOOR ) ) { CommandType.Interpret(ch, "unlock " + dir.ToString()); CommandType.Interpret(ch, "open " + dir.ToString()); return; } ch.Move( dir ); if( !ch.InRoom ) { string text = "Return_to_load: no ch._inRoom! Mob #" + ch.MobileTemplate.IndexNumber + ", _name: " + ch.Name + ". Placing mob in limbo (mob.AddToRoom())."; Log.Error( text, 0 ); ch.AddToRoom( Room.GetRoom( StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO") ) ); ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_SPAM, 0, text); return; } return; }
static bool AreaOffensive( CharData ch, CharData victim ) { if (ch == null) return false; if (ch.IsOutside()) { if( CheckOffensive( ch, victim, "meteor swarm", 50 ) ) return true; if( !ch.IsUnderground() ) if( CheckOffensive( ch, victim, "earthen rain", 55 ) ) return true; } if( CheckOffensive( ch, victim, "incendiary cloud", 45 ) ) return true; if( CheckOffensive( ch, victim, "ice storm", 25 ) ) return true; if( CheckOffensive( ch, victim, "earthquake", 50 ) ) return true; return false; }
/// <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; }
static CharData TransformMob( CharData ch, int indexNumber, string msg ) { CharData wasFighting = null; if( ch.Fighting ) { wasFighting = ch.Fighting; Combat.StopFighting( ch, false ); } CharData newCh = Database.CreateMobile( Database.GetMobTemplate( indexNumber ) ); if( !newCh ) { Log.Trace( "assert: mob load failed in TransformMob()" ); return null; } newCh.AddToRoom( ch.InRoom ); foreach( Object item in ch.Carrying ) { item.RemoveFromChar(); item.ObjToChar( newCh ); } foreach (ObjTemplate.WearLocation pos in Enum.GetValues(typeof(ObjTemplate.WearLocation))) { Object item = Object.GetEquipmentOnCharacter( ch, pos ); if( !item ) continue; ch.UnequipObject( item ); item.RemoveFromChar(); item.ObjToChar( newCh ); newCh.EquipObject( ref item, pos ); } newCh.CurrentPosition = ch.CurrentPosition; newCh.ActionFlags = ch.ActionFlags; newCh.RemoveActionBit(PC.PLAYER_WIZINVIS); newCh.Hating = ch.Hating; ch.Hating = null; newCh.Hunting = ch.Hunting; ch.Hunting = null; newCh.Fearing = ch.Fearing; ch.Fearing = null; if( msg.Length > 0 ) SocketConnection.Act( msg, ch, null, newCh, SocketConnection.MessageTarget.room ); else SocketConnection.Act( "$n&n suddenly changes into $N!&n", ch, null, newCh, SocketConnection.MessageTarget.room ); if( wasFighting != null ) Combat.SetFighting( newCh, wasFighting ); return newCh; }
/// <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; }
// Checks melee combat skills for mobs - Xangis static bool CombatSkillCheck( CharData ch ) { if (ch == null) return false; if (ch.HasSkill("kick") && MUDMath.NumberPercent() < 60) { CommandType.Interpret(ch, "kick"); return true; } if( ch.HasSkill( "bash" ) && MUDMath.NumberPercent() < 40 && ( ch.Fighting != null ) && ( ch.CurrentSize >= ch.Fighting.CurrentSize && ch.CurrentSize - 2 <= ch.Fighting.CurrentSize ) ) { CommandType.Interpret(ch, "bash"); return true; } if( ch.HasSkill( "springleap" ) && MUDMath.NumberPercent() < 50 ) { CommandType.Interpret(ch, "springleap"); return true; } if( ch.HasSkill( "headbutt" ) && MUDMath.NumberPercent() < 40 ) { CommandType.Interpret(ch, "headbutt"); return true; } if( ch.HasSkill( "circle" ) && MUDMath.NumberPercent() < 40 ) { CommandType.Interpret(ch, "circle"); return true; } if( ch.HasSkill( "trip" ) && MUDMath.NumberPercent() < 35 ) { CommandType.Interpret(ch, "trip"); return true; } if( ch.HasSkill( "dirt toss" ) && MUDMath.NumberPercent() < 60 ) { CommandType.Interpret(ch, "dirt"); return true; } return false; }
/// <summary> /// Gets a character's carry load as a string. /// </summary> /// <param name="ch"></param> /// <returns></returns> public static string WeightString( CharData ch ) { int value = ( ch.CarryWeight * 100 ) / ch.MaxCarryWeight(); if( value > 100 ) return "&+ROVERLOADED&n"; if( value == 100 ) return "&+YFully Loaded&n"; if( value > 90 ) return "&+YExtremely Heavy&n"; if( value > 80 ) return "&+rReally Heavy&n"; if( value > 70 ) return "&+mHeavy&n"; if( value > 60 ) return "&+mModerately Heavy&n"; if( value > 50 ) return "&+yModerate&n"; if( value > 40 ) return "&+bModerately Light&n"; if( value > 30 ) return "&+bLight&n"; if( value > 20 ) return "&+BReally Light&n"; if( value > 10 ) return "&+cExtremely Light&n"; if( value > 00 ) return "&+CAlmost Nothing&n"; if( value == 0 ) return "&+WNothing&n"; return "&+Rbuggy - too light&n"; }
static bool OffensiveSpell( CharData ch, CharData victim ) { if (ch == null) return false; if (CheckOffensive(ch, victim, "fireball", 60)) return true; return false; }
/// <summary> /// Gets a character's alignment string. /// </summary> /// <param name="ch"></param> /// <returns></returns> public static string AlignmentString( CharData ch ) { return AlignmentString(ch.Alignment); }
static CharData _wasFighting; // grumbar shout #endregion Fields #region Methods /// <summary> /// Check an offensive spell based on its _name. If the spell doesn't exist we don't bother. /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> /// <param name="spellName"></param> /// <param name="percent"></param> /// <returns></returns> public static bool CheckOffensive(CharData ch, CharData victim, string spellName, int percent) { if (ch == null) return false; Spell spell = Spell.SpellList[spellName]; if (spell != null) { return CheckOffensive(ch, victim, spell, percent); } return false; }
/// <summary> /// Gets progress to next experience level as a string. /// </summary> /// <param name="ch"></param> /// <returns></returns> public static string ExperienceString( CharData ch ) { int exp = ( 100 * ch.ExperiencePoints ) / ExperienceTable.Table[ ch.Level ].LevelExperience; if( exp < 10 ) return "You have just begun the trek to your next level!"; if( exp < 20 ) return "You are still a very long way from your next level."; if( exp < 30 ) return "You have gained some progress but still have a long way to your next level."; if( exp < 40 ) return "You have gained some progress and are nearing the halfway point."; if( exp < 47 ) return "You are close to the halfway point in the journey to your next level."; if( exp < 53 ) return "You are at the halfway point."; if( exp < 60 ) return "You have just passed the halfway point."; if( exp < 70 ) return "You are well on your way to the next level."; if( exp < 80 ) return "You are three quarters the way to your next level."; if( exp < 90 ) return "You are almost ready to attain your next level."; return "You should level anytime now!"; }