/// <summary> /// Create an instance of a mobile from the provided template. /// </summary> /// <param name="mobTemplate"></param> /// <returns></returns> public static CharData CreateMobile( MobTemplate mobTemplate ) { int count; if( !mobTemplate ) { Log.Error("CreateMobile: null MobTemplate.", 0); throw new NullReferenceException(); } CharData mob = new CharData(); mob.MobileTemplate = mobTemplate; mob.Followers = null; mob.Name = mobTemplate.PlayerName; mob.ShortDescription = mobTemplate.ShortDescription; mob.FullDescription = mobTemplate.FullDescription; mob.Description = mobTemplate.Description; mob.SpecialFunction = mobTemplate.SpecFun; mob.SpecialFunctionNames = mobTemplate.SpecFunNames; mob.CharacterClass = mobTemplate.CharacterClass; mob.Level = MUDMath.FuzzyNumber( mobTemplate.Level ); mob.ActionFlags = mobTemplate.ActionFlags; mob.CurrentPosition = mobTemplate.DefaultPosition; mob.ChatterBotName = mobTemplate.ChatterBotName; // TODO: Look up the chatter bot name and load a runtime bot into the variable. mob.ChatBot = null; for( count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count ) { mob.AffectedBy[ count ] = mobTemplate.AffectedBy[ count ]; } mob.Alignment = mobTemplate.Alignment; mob.Gender = mobTemplate.Gender; mob.SetPermRace( mobTemplate.Race ); mob.CurrentSize = Race.RaceList[ mob.GetRace() ].DefaultSize; if (mob.HasActionBit(MobTemplate.ACT_SIZEMINUS)) mob.CurrentSize--; if (mob.HasActionBit(MobTemplate.ACT_SIZEPLUS)) mob.CurrentSize++; mob.CastingSpell = 0; mob.CastingTime = 0; mob.PermStrength = MUDMath.Dice( 2, 46 ) + 8; mob.PermIntelligence = MUDMath.Dice( 2, 46 ) + 8; mob.PermWisdom = MUDMath.Dice( 2, 46 ) + 8; mob.PermDexterity = MUDMath.Dice( 2, 46 ) + 8; mob.PermConstitution = MUDMath.Dice( 2, 46 ) + 7; mob.PermAgility = MUDMath.Dice( 2, 46 ) + 8; mob.PermCharisma = MUDMath.Dice( 2, 46 ) + 8; mob.PermPower = MUDMath.Dice( 2, 46 ) + 8; mob.PermLuck = MUDMath.Dice( 2, 46 ) + 8; mob.ModifiedStrength = 0; mob.ModifiedIntelligence = 0; mob.ModifiedWisdom = 0; mob.ModifiedDexterity = 0; mob.ModifiedConstitution = 0; mob.ModifiedAgility = 0; mob.ModifiedCharisma = 0; mob.ModifiedPower = 0; mob.ModifiedLuck = 0; mob.Resistant = mobTemplate.Resistant; mob.Immune = mobTemplate.Immune; mob.Susceptible = mobTemplate.Susceptible; mob.Vulnerable = mobTemplate.Vulnerable; mob.MaxMana = mob.Level * 10; if( Race.RaceList[mobTemplate.Race].Coins ) { int level = mobTemplate.Level; mob.ReceiveCopper( MUDMath.Dice( 12, level ) / 32 ); mob.ReceiveSilver( MUDMath.Dice( 9, level ) / 32 ); mob.ReceiveGold( MUDMath.Dice( 5, level ) / 32 ); mob.ReceivePlatinum( MUDMath.Dice( 2, level ) / 32 ); } else { mob.SetCoins( 0, 0, 0, 0 ); } mob.ArmorPoints = MUDMath.Interpolate( mob.Level, 100, -100 ); // * MOB HITPOINTS * // // Was level d 8, upped it to level d 13 // considering mobs *still* won't have as many hitpoints as some players until // at least level 10, this shouldn't be too big an upgrade. // // Mob hitpoints are not based on constitution *unless* they have a // constitution modifier from an item, spell, or other affect // In light of recent player dissatisfaction with the // mob hitpoints, I'm implementing a log curve, using // hp = exp( 2.15135 + level*0.151231) // This will will result in the following hp matrix: // Level Hitpoints // 20 175 // 30 803 // 40 3643 // 50 16528 // 55 35207 // 60 75000 mob.MaxHitpoints = MUDMath.Dice( mob.Level, 13 ) + 1; // Mob hps are non-linear above level 10. if( mob.Level > 20 ) { int upper = (int)Math.Exp( 1.85 + mob.Level * 0.151231 ); int lower = (int)Math.Exp( 1.80 + mob.Level * 0.151231 ); mob.MaxHitpoints += MUDMath.NumberRange( lower, upper ); } else if (mob.Level > 10) { mob.MaxHitpoints += MUDMath.NumberRange(mob.Level * 2, ((mob.Level - 8) ^ 2 * mob.Level) / 2); } // Demons/devils/dragons gain an extra 30 hitpoints per level (+1500 at lvl 50). if (mob.GetRace() == Race.RACE_DEMON || mob.GetRace() == Race.RACE_DEVIL || mob.GetRace() == Race.RACE_DRAGON) { mob.MaxHitpoints += (mob.Level * 30); } mob.Hitpoints = mob.GetMaxHit(); // Horses get more moves, necessary for mounts. if(Race.RaceList[ mob.GetRace() ].Name.Equals( "Horse", StringComparison.CurrentCultureIgnoreCase )) { mob.MaxMoves = 290 + MUDMath.Dice( 4, 5 ); mob.CurrentMoves = mob.MaxMoves; } mob.LoadRoomIndexNumber = 0; // Insert in list. CharList.Add( mob ); // Increment count of in-game instances of mob. mobTemplate.NumActive++; return mob; }
/// <summary> /// Creates a duplicate of a mobile minus its inventory. /// </summary> /// <param name="parent"></param> /// <param name="clone"></param> public static void CloneMobile( CharData parent, CharData clone ) { int i; if( parent == null || clone == null || !parent.IsNPC() ) return; // Fix values. clone.Name = parent.Name; clone.ShortDescription = parent.ShortDescription; clone.FullDescription = parent.FullDescription; clone.Description = parent.Description; clone.Gender = parent.Gender; clone.CharacterClass = parent.CharacterClass; clone.SetPermRace( parent.GetRace() ); clone.Level = parent.Level; clone.TrustLevel = 0; clone.SpecialFunction = parent.SpecialFunction; clone.SpecialFunctionNames = parent.SpecialFunctionNames; clone.Timer = parent.Timer; clone.Wait = parent.Wait; clone.Hitpoints = parent.Hitpoints; clone.MaxHitpoints = parent.MaxHitpoints; clone.CurrentMana = parent.CurrentMana; clone.MaxMana = parent.MaxMana; clone.CurrentMoves = parent.CurrentMoves; clone.MaxMoves = parent.MaxMoves; clone.SetCoins( parent.GetCopper(), parent.GetSilver(), parent.GetGold(), parent.GetPlatinum() ); clone.ExperiencePoints = parent.ExperiencePoints; clone.ActionFlags = parent.ActionFlags; clone.Affected = parent.Affected; clone.CurrentPosition = parent.CurrentPosition; clone.Alignment = parent.Alignment; clone.Hitroll = parent.Hitroll; clone.Damroll = parent.Damroll; clone.Wimpy = parent.Wimpy; clone.Deaf = parent.Deaf; clone.Hunting = parent.Hunting; clone.Hating = parent.Hating; clone.Fearing = parent.Fearing; clone.Resistant = parent.Resistant; clone.Immune = parent.Immune; clone.Susceptible = parent.Susceptible; clone.CurrentSize = parent.CurrentSize; clone.PermStrength = parent.PermStrength; clone.PermIntelligence = parent.PermIntelligence; clone.PermWisdom = parent.PermWisdom; clone.PermDexterity = parent.PermDexterity; clone.PermConstitution = parent.PermConstitution; clone.PermAgility = parent.PermAgility; clone.PermCharisma = parent.PermCharisma; clone.PermPower = parent.PermPower; clone.PermLuck = parent.PermLuck; clone.ModifiedStrength = parent.ModifiedStrength; clone.ModifiedIntelligence = parent.ModifiedIntelligence; clone.ModifiedWisdom = parent.ModifiedWisdom; clone.ModifiedDexterity = parent.ModifiedDexterity; clone.ModifiedConstitution = parent.ModifiedConstitution; clone.ModifiedAgility = parent.ModifiedAgility; clone.ModifiedCharisma = parent.ModifiedCharisma; clone.ModifiedPower = parent.ModifiedPower; clone.ModifiedLuck = parent.ModifiedLuck; clone.ArmorPoints = parent.ArmorPoints; //clone._mpactnum = parent._mpactnum; for (i = 0; i < 6; i++) { clone.SavingThrows[i] = parent.SavingThrows[i]; } // Now add the affects. foreach (Affect affect in parent.Affected) { clone.AddAffect(affect); } }
/// <summary> /// Deliver a killing blow to the victim. /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> public static void KillingBlow( CharData ch, CharData victim ) { Event eventdata; Room room; bool noCorpse = false; StopFighting( victim, true ); if( victim.GroupLeader || victim.NextInGroup ) { victim.RemoveFromGroup( victim ); } if( ch != victim ) { if( victim.IsNPC() && victim.MobileTemplate.DeathFun.Count > 0 ) { victim.MobileTemplate.DeathFun[0].SpecFunction( victim, MobFun.PROC_NORMAL ); } // prog_death_trigger( victim ); } if( victim.IsNPC() && victim.DeathFunction != null ) { noCorpse = victim.DeathFunction.SpecFunction( victim, MobFun.PROC_DEATH ); } if( !noCorpse ) { MakeCorpse( victim ); } /* Strip all event-spells from victim! */ for( int i = (Database.EventList.Count - 1); i >= 0; i-- ) { eventdata = Database.EventList[i]; if( eventdata.Type == Event.EventType.immolate || eventdata.Type == Event.EventType.acid_arrow ) { if( (CharData)eventdata.Target2 == victim ) { Database.EventList.Remove( eventdata ); } } } if( victim.Rider ) { SocketConnection.Act( "$n&n dies suddenly, and you topple to the &n&+yground&n.", victim, null, victim.Rider, SocketConnection.MessageTarget.victim ); victim.Rider.Riding = null; victim.Rider.CurrentPosition = Position.resting; victim.Rider = null; } if( victim.Riding ) { SocketConnection.Act( "$n&n topples from you, &+Ldead&n.", victim, null, victim.Riding, SocketConnection.MessageTarget.victim ); victim.Riding.Rider = null; victim.Riding = null; } if (!victim.IsNPC() && victim.IsAffected(Affect.AFFECT_VAMP_BITE)) { victim.SetPermRace( Race.RACE_VAMPIRE ); } for (int i = (victim.Affected.Count - 1); i >= 0; i--) { /* Keep the ghoul affect */ if (!victim.IsNPC() && victim.IsAffected(Affect.AFFECT_WRAITHFORM)) { continue; } victim.RemoveAffect(victim.Affected[i]); } if( victim.IsNPC() ) { victim.MobileTemplate.NumberKilled++; // This may invalidate the char list. CharData.ExtractChar( victim, true ); return; } CharData.ExtractChar( victim, false ); //save corpses, don't wait til next save_corpse event Database.CorpseList.Save(); // Character has died in combat, extract them to repop point and put // them at the menu. /* * Pardon crimes once justice system is complete */ // This is where we send them to the menu. victim.DieFollower( victim.Name ); if( victim.InRoom ) { room = victim.InRoom; } else { List<RepopulationPoint> repoplist = victim.GetAvailableRepops(); if( repoplist.Count < 1 ) { victim.SendText( "There is no RepopPoint entry for your race and class. Sending you to limbo.\r\n" ); room = Room.GetRoom( StaticRooms.GetRoomNumber("ROOM_NUMBER_START") ); } else { // Drop them at the first repop point in the list. We may want to be fancier about this later, such as dropping them // at the repop for class none if their particular class isn't found. room = Room.GetRoom(repoplist[0].Room); if( !room ) { victim.SendText( "The repop point for your race/class does not exist. Please bug this. Sending you to limbo.\r\n" ); room = Room.GetRoom( StaticRooms.GetRoomNumber("ROOM_NUMBER_START") ); } if( !victim.IsNPC() && Room.GetRoom( ( (PC)victim ).CurrentHome ) ) { room = Room.GetRoom( ( (PC)victim ).CurrentHome ); } } } victim.RemoveFromRoom(); if( room ) { victim.InRoom = room; } // Put them in the correct body if( victim.Socket && victim.Socket.Original ) { CommandType.Interpret(victim, "return"); } // Reset reply pointers - handled by CharData.ExtractChar. CharData.SavePlayer( victim ); // Remove from char list: handled by CharData.ExtractChar. victim.Socket.ShowScreen(ModernMUD.Screen.MainMenuScreen); if( victim.Socket != null ) { victim.Socket.ConnectionStatus = SocketConnection.ConnectionState.menu; } // Just died flag used for safe time after re-login. victim.SetActionBit( PC.PLAYER_JUST_DIED ); return; }
/// <summary> /// Sends a damage message to a player. /// </summary> /// <param name="ch"></param> /// <param name="victim"></param> /// <param name="damage"></param> /// <param name="skill"></param> /// <param name="weapon"></param> /// <param name="immune"></param> static void SendDamageMessage( CharData ch, CharData victim, int damage, string skill, ObjTemplate.WearLocation weapon, bool immune ) { if( victim.CurrentPosition == Position.sleeping ) { SocketConnection.Act( "$n&n has a rude awakening!", victim, null, null, SocketConnection.MessageTarget.room ); victim.CurrentPosition = Position.resting; SetFighting( victim, ch ); } if (skill == "bash") { SocketConnection.Act( "You send $N&n crashing to the &n&+yground&n with your powerful bash.", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n's powerful bash sends you sprawling!", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n sends $N&n sprawling with a powerful bash!", ch, null, victim, SocketConnection.MessageTarget.room_vict ); return; } if (skill == "headbutt") { if( ch != victim && damage > victim.Hitpoints + 10 ) { // a killing blow needs some nice verbage SocketConnection.Act( "You swiftly split $N&n's skull with your forehead, sending &+Rblood&n&+r and brains&n flying!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n rears back and splits $N&n's skull with $s forehead!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim ); SocketConnection.Act( "&+RBlood&n&+r and brains&n splatter everywhere as $N&n goes limp and collapses.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim ); SocketConnection.Act( "$n&n's forehead smashes into you, crushing your skull and bringing on a wave of &+Lblackness&n.", ch, null, victim, SocketConnection.MessageTarget.victim ); //deal some decent damage } else if( ch != victim && damage > 100 ) { // a pretty nasty headbutt SocketConnection.Act( "Your headbutt smashes into $N&n's skull.", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n's headbutt smashes into $N&n's skull.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim ); SocketConnection.Act( "$n&n's head smashes into you, sending you reeling.", ch, null, victim, SocketConnection.MessageTarget.victim ); //deal some decent damage } else if( ch != victim ) { SocketConnection.Act( "$n&n's headbutt leaves a red welt on $N&n's forehead.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim ); SocketConnection.Act( "Your headbutt leaves a red welt on $N&n's forehead.", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n's headbutt leaves a red welt on your forehead.", ch, null, victim, SocketConnection.MessageTarget.victim ); } /* left the damage to self messages in the Command.Headbutt() function * because they are a little too tricky to implement through * this function */ return; } if (skill == "bodyslam" && ch != victim) { SocketConnection.Act( "You bodyslam $N&n!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n bodyslams you!\r\nYou are stunned!", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n bodyslams $N&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict ); } if (skill == "instant kill") { switch( MUDMath.NumberRange( 1, 3 ) ) { case 1: case 2: SocketConnection.Act( "You place your weapon in the back of $N&n, resulting in some strange noises, some blood, and a corpse!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "You realize you should have kept your vital organs somewhere safe as $n&n stabs you to death.", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n places $s weapon in the back of $N&n, resulting in some strange noises, some blood, and a corpse!", ch, null, victim, SocketConnection.MessageTarget.room_vict ); break; case 3: SocketConnection.Act( "You place your weapon in the back of $N&n with such force that it comes out the other side!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n ends your life with a well-placed backstab.", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n places $s weapon in the back of $N&n with such force that it comes out the other side!", ch, null, victim, SocketConnection.MessageTarget.room_vict ); break; } return; } // Multiple backstab messages, feel free to add more. if (skill == "backstab" && damage > 0) { switch( MUDMath.NumberRange( 1, 4 ) ) { case 1: SocketConnection.Act( "$N&n howls in agony as you pierce $S backbone!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "You howl in agony as you feel &+rpain&n in your back!", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$N&N howls in agony as $n&n pierces $S backbone!", ch, null, victim, SocketConnection.MessageTarget.room_vict ); break; case 2: SocketConnection.Act( "You place your $p&n silently and skillfully through the spine of $N&n.", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "Your spine feels $p&n neatly slicing through it.", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n places $s $p&n into $N&n's back!", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.room_vict ); break; case 3: SocketConnection.Act( "Blood flies everywhere as you stab $N&n in the back!", ch, null, victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "You feel a sharp stabbing sensation in your back!", ch, null, victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "Blood flies everywhere as $n&n places $s $p&n into $N&n's back!", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.room_vict ); break; case 4: SocketConnection.Act( "You smile with perverse pleasure as your $p&n plunges through $N&n's soft tissue, piercing vital organs.", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.character ); SocketConnection.Act( "$n&n smiles with perverse pleasure as $s $p&n plunges through $N&n's soft tissue, piercing vital organs.", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.victim ); SocketConnection.Act( "$n&n smile with perverse pleasure as $s $p&n plunges through $N&n's soft tissue, piercing vital organs.", ch, Object.GetEquipmentOnCharacter( ch, weapon ), victim, SocketConnection.MessageTarget.room_vict ); break; } return; } if (skill == "poison weapon" || skill == "poison" || skill == "poison bite") return; string vp1; string attack; string buf1; string buf2; string buf3; string buf4; string buf5; // Adjectives based on amount of damage done. string adjective = String.Empty; if( damage > 100 ) { adjective = " godly"; } else if( damage > 75 ) { adjective = " devastating"; } else if( damage > 55 ) { adjective = " mighty"; } else if( damage > 40 ) { adjective = " awesome"; } else if( damage > 25 ) { adjective = " powerful"; } else if( damage > 4 ) { adjective = String.Empty; } // no message modifier for normal hits else if( damage > 2 ) { adjective = " mediocre"; } else if( damage > 0 ) { adjective = " feeble"; } string vp2 = String.Empty; if( damage == 0 ) { vp1 = "misses"; vp2 = String.Empty; } else { damage *= 100; if( victim.Hitpoints > 0 ) damage /= victim.Hitpoints; if( damage <= 1 ) { vp1 = "scratches"; } else if( damage <= 2 ) { vp1 = "grazes"; } else if( damage <= 3 ) { vp1 = "hits"; } else if( damage <= 4 ) { vp1 = "hits"; vp2 = " hard"; } else if( damage <= 5 ) { vp1 = "hits"; vp2 = " very hard"; } else if( damage <= 10 ) { vp1 = "mauls"; } else if( damage <= 15 ) { vp1 = "decimates"; } else if( damage <= 20 ) { vp1 = "makes"; vp2 = " stagger in pain"; } else if( damage <= 25 ) { vp1 = "maims"; } else if( damage <= 30 ) { vp1 = "mutilates"; } else if( damage <= 40 ) { vp1 = "disembowels"; } else if( damage <= 50 ) { vp1 = "eviscerates"; } else if( damage <= 75 ) { vp1 = "enshrouds"; vp2 = " in a mist of blood"; } else { vp1 = "beats the crap out of"; } } string punct = ( damage <= 40 ) ? "." : "!"; if (skill == "barehanded fighting") { if( ch.GetRace() >= Race.RaceList.Length ) { Log.Error( "SendDamageMessage: {0} invalid race", ch.GetRace() ); ch.SetPermRace( 0 ); } attack = Race.RaceList[ ch.GetRace() ].DamageMessage; buf1 = String.Format( "Your{0} {1} {2} $N&n{3}{4}", adjective, attack, vp1, vp2, punct ); buf2 = String.Format("$n&n's{0} {1} {2} you{3}{4}", adjective, attack, vp1, vp2, punct); buf3 = String.Format("$n&n's{0} {1} {2} $N&n{3}{4}", adjective, attack, vp1, vp2, punct); buf4 = String.Format("You{0} {1} {2} yourself{3}{4}", adjective, attack, vp1, vp2, punct); buf5 = String.Format("$n&n's{0} {1} {2} $m{3}{4}", adjective, attack, vp1, vp2, punct); } else { if (!String.IsNullOrEmpty(skill)) attack = Skill.SkillList[skill].DamageText; else { string buf = String.Format( "SendDamageMessage: bad damage type {0} for {1} damage caused by {2} to {3} with weapon {4}.", skill, damage, ch.Name, victim.Name, weapon ); Log.Error( buf, 0 ); skill = "barehanded fighting"; attack = AttackType.Table[ 0 ].Name; } if( immune ) { buf1 = String.Format("$N&n seems unaffected by your {0}!", attack); buf2 = String.Format("$n&n's {0} seems powerless against you.", attack); buf3 = String.Format("$N&n seems unaffected by $n&n's {0}!", attack); buf4 = String.Format("Luckily, you seem immune to {0}.", attack); buf5 = String.Format("$n&n seems unaffected by $s own {0}.", attack); } else { if (skill != "barehanded fighting" && IsWieldingPoisoned(ch, weapon)) { buf1 = String.Format("Your poisoned {0} {1} $N&n{2}{3}", attack, vp1, vp2, punct); buf2 = String.Format("$n&n's poisoned {0} {1} you{2}{3}", attack, vp1, vp2, punct); buf3 = String.Format("$n&n's poisoned {0} {1} $N&n{2}{3}", attack, vp1, vp2, punct); buf4 = String.Format("Your poisoned {0} {1} you{2}{3}", attack, vp1, vp2, punct); buf5 = String.Format("$n&n's poisoned {0} {1} $m{2}{3}", attack, vp1, vp2, punct); } else { buf1 = String.Format("Your{0} {1} {2} $N&n{3}{4}", adjective, attack, vp1, vp2, punct); buf2 = String.Format("$n&n's{0} {1} {2} you{3}{4}", adjective, attack, vp1, vp2, punct); buf3 = String.Format("$n&n's{0} {1} {2} $N&n{3}{4}", adjective, attack, vp1, vp2, punct); buf4 = String.Format("You{0} {1} {2} yourself{3}{4}", adjective, attack, vp1, vp2, punct); buf5 = String.Format("$n&n's{0} {1} {2} $m{3}{4}", adjective, attack, vp1, vp2, punct); } } } if( victim != ch ) { SocketConnection.Act( buf1, ch, null, victim, SocketConnection.MessageTarget.character, true ); SocketConnection.Act( buf2, ch, null, victim, SocketConnection.MessageTarget.victim, true ); SocketConnection.Act( buf3, ch, null, victim, SocketConnection.MessageTarget.room_vict, true ); } else { SocketConnection.Act( buf4, ch, null, victim, SocketConnection.MessageTarget.character, true ); SocketConnection.Act( buf5, ch, null, victim, SocketConnection.MessageTarget.room, true ); } return; }
/// <summary> /// Creates a character based on an object. Used for animate-object-type spells. /// </summary> /// <param name="obj"></param> /// <returns></returns> public CharData CreateCharacterFromObject( ref Object obj ) { int count; MobTemplate mobTemplate = Database.GetMobTemplate( StaticMobs.MOB_NUMBER_OBJECT ); if( !mobTemplate ) { Log.Error( "CreateCharacterFromObject: null object template.", 0 ); return null; } CharData mob = new CharData(); mob.MobileTemplate = mobTemplate; mob.Name = obj._name; mob.ShortDescription = obj._shortDescription; mob.FullDescription = obj._fullDescription; mob.Description = obj._fullDescription; mob.CharacterClass = mobTemplate.CharacterClass; mob.Level = Math.Max( obj._level, 1 ); mob.ActionFlags = mobTemplate.ActionFlags; mob.CurrentPosition = mobTemplate.DefaultPosition; for( count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count ) { mob.AffectedBy[ count ] = mobTemplate.AffectedBy[ count ]; } mob.Alignment = mobTemplate.Alignment; mob.Gender = mobTemplate.Gender; mob.SetPermRace( mobTemplate.Race ); mob.CurrentSize = Race.RaceList[ mob.GetRace() ].DefaultSize; if (mob.HasActionBit(MobTemplate.ACT_SIZEMINUS)) mob.CurrentSize--; if (mob.HasActionBit(MobTemplate.ACT_SIZEPLUS)) mob.CurrentSize++; mob.CastingSpell = 0; mob.CastingTime = 0; mob.PermStrength = 55; mob.PermIntelligence = 55; mob.PermWisdom = 55; mob.PermDexterity = 55; mob.PermConstitution = 55; mob.PermAgility = 55; mob.PermCharisma = 55; mob.PermPower = 55; mob.PermLuck = 55; mob.ModifiedStrength = 0; mob.ModifiedIntelligence = 0; mob.ModifiedWisdom = 0; mob.ModifiedDexterity = 0; mob.ModifiedConstitution = 0; mob.ModifiedAgility = 0; mob.ModifiedCharisma = 0; mob.ModifiedPower = 0; mob.ModifiedLuck = 0; mob.Resistant = mobTemplate.Resistant; mob.Immune = mobTemplate.Immune; mob.Susceptible = mobTemplate.Susceptible; mob.Vulnerable = mobTemplate.Vulnerable; mob.SetCoins( 0, 0, 0, 0 ); mob.ArmorPoints = MUDMath.Interpolate( mob.Level, 100, -100 ); // * MOB HITPOINTS * // // Was level d 8, upped it to level d 13 // considering mobs *still* won't have as many hitpoints as some players until // at least lvl 10, this shouldn't be too big an upgrade. // // Mob hitpoints are not based on constitution *unless* they have a // constitution modifier from an item, spell, or other affect mob.MaxHitpoints = mob.Level * 100; mob.Hitpoints = mob.GetMaxHit(); /* * Insert in list. */ Database.CharList.Add( mob ); // Increment in-game count of mob. mobTemplate.NumActive++; mob.AddToRoom( obj._inRoom ); return mob; }