public static ICharacter InstantiateMobSpawn( DBMobSpawn mob, DBMobSpawnStat[] stats, IController npccontroller, IPlayfield playfield) { if (playfield != null) { Identity mobId = new Identity() { Type = IdentityType.CanbeAffected, Instance = mob.Id }; if (Pool.Instance.GetObject(playfield.Identity, mobId) != null) { throw new Exception("Object " + mobId.ToString(true) + " already exists!!"); } Character cmob = new Character(playfield.Identity, mobId, npccontroller); cmob.Read(); cmob.Playfield = playfield; cmob.Coordinates(new Coordinate() { x = mob.X, y = mob.Y, z = mob.Z }); cmob.RawHeading = new Quaternion(mob.HeadingX, mob.HeadingY, mob.HeadingZ, mob.HeadingW); cmob.Name = mob.Name; cmob.FirstName = ""; cmob.LastName = ""; foreach (DBMobSpawnStat stat in stats) { cmob.Stats.SetBaseValueWithoutTriggering(stat.Stat, (uint)stat.Value); } cmob.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, cmob.Stats[StatIds.profession].BaseValue); // initiate affected stats calculation int temp = cmob.Stats[StatIds.level].Value; temp = cmob.Stats[StatIds.agility].Value; temp = cmob.Stats[StatIds.headmesh].Value; cmob.MeshLayer.AddMesh(0, cmob.Stats[StatIds.headmesh].Value, 0, 4); cmob.SocialMeshLayer.AddMesh(0, cmob.Stats[StatIds.headmesh].Value, 0, 4); List<MobSpawnWaypoint> waypoints = MessagePackZip.DeserializeData<MobSpawnWaypoint>(mob.Waypoints.ToArray()); foreach (MobSpawnWaypoint wp in waypoints) { Waypoint mobwp = new Waypoint(); mobwp.Position.x = wp.X; mobwp.Position.y = wp.Y; mobwp.Position.z = wp.Z; mobwp.Running = wp.WalkMode == 1; cmob.Waypoints.Add(mobwp); } npccontroller.Character = cmob; if (cmob.Waypoints.Count > 2) { cmob.Controller.State = CharacterState.Patrolling; } cmob.DoNotDoTimers = false; return cmob; } return null; }
private static Character CreateMob( DBMobTemplate mob, Identity playfieldIdentity, Coordinate coord, Quaternion heading, IController controller, int level) { IPlayfield playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity); if (playfield != null) { int newInstanceId = Pool.Instance.GetFreeInstance<Character>(1000000, IdentityType.CanbeAffected); Identity newIdentity = new Identity() { Type = IdentityType.CanbeAffected, Instance = newInstanceId }; Character mobCharacter = new Character(playfield.Identity, newIdentity, controller); mobCharacter.Read(); mobCharacter.Coordinates(coord); mobCharacter.Playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity); mobCharacter.RawHeading = new Quaternion(heading.xf, heading.yf, heading.zf, heading.wf); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.life, (uint)mob.Health); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.level, (uint)level); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.npcfamily, (uint)mob.NPCFamily); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.side, (uint)mob.Side); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.fatness, (uint)mob.Fatness); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.breed, (uint)mob.Breed); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.sex, (uint)mob.Sex); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.race, (uint)mob.Race); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.flags, (uint)mob.Flags); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterdata, (uint)mob.MonsterData); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterscale, (uint)mob.MonsterScale); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.profession, 15); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.accountflags, 0); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.expansion, 0); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.runspeed, 513); mobCharacter.Stats[StatIds.headmesh].BaseValue = (uint)mob.HeadMesh; mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.losheight, 15); mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, 15); /* // For testing only, blue trousers and a helmet IItem trousers = new Item(1, ItemLoader.ItemList[27350].GetLowId(1),ItemLoader.ItemList[27350].GetLowId(1)); IItem helmet = new Item(1, ItemLoader.ItemList[85534].GetLowId(1), ItemLoader.ItemList[85534].GetHighId(1)); mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Legs + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, trousers); mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Head + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, helmet); */ // Set the MeshLayers correctly ( Head mesh!! ) /!\ // TODO: This needs to be in StatHeadmesh.cs (somehow) mobCharacter.MeshLayer.AddMesh(0, mob.HeadMesh, 0, 4); mobCharacter.SocialMeshLayer.AddMesh(0, mob.HeadMesh, 0, 4); mobCharacter.Name = mob.Name; mobCharacter.FirstName = ""; mobCharacter.LastName = ""; controller.Character = mobCharacter; return mobCharacter; } return null; }
/// <summary> /// </summary> /// <param name="character"> /// </param> /// <returns> /// </returns> public static SimpleCharFullUpdateMessage ConstructMessage(Character character) { // No need to set packet flags here, its all done in the SimpleCharFullUpdateSerializer.cs // - Algorithman // Character Variables bool socialonly; bool showsocial; int charPlayfield; Coordinate charCoord; Identity charId; Quaternion charHeading; uint sideValue; uint fatValue; uint breedValue; uint sexValue; uint raceValue; string charName; int charFlagsValue; int accFlagsValue; int expansionValue; int currentNano; int currentHealth; uint strengthBaseValue; uint staminaBaseValue; uint agilityBaseValue; uint senseBaseValue; uint intelligenceBaseValue; uint psychicBaseValue; string firstName; string lastName; int orgNameLength; string orgName; int levelValue; int healthValue; int losHeight; int monsterData; int monsterScale; int visualFlags; int currentMovementMode; uint runSpeedBaseValue; int texturesCount; int headMeshValue; // NPC Values int NPCFamily; var socialTab = new Dictionary<int, int>(); var textures = new List<AOTextures>(); List<AOMeshs> meshs; var nanos = new List<AONano>(); lock (character) { socialonly = (character.Stats[StatIds.visualflags].Value & 0x40) > 0; showsocial = (character.Stats[StatIds.visualflags].Value & 0x20) > 0; charPlayfield = character.Playfield.Identity.Instance; charCoord = character.Coordinates(); charId = character.Identity; charHeading = character.Heading; sideValue = character.Stats[StatIds.side].BaseValue; fatValue = character.Stats[StatIds.fatness].BaseValue; breedValue = character.Stats[StatIds.breed].BaseValue; sexValue = character.Stats[StatIds.sex].BaseValue; raceValue = character.Stats[StatIds.race].BaseValue; charName = character.Name; charFlagsValue = character.Stats[StatIds.flags].Value; accFlagsValue = character.Stats[StatIds.accountflags].Value; expansionValue = character.Stats[StatIds.expansion].Value; currentNano = character.Stats[StatIds.currentnano].Value; strengthBaseValue = character.Stats[StatIds.strength].BaseValue; staminaBaseValue = character.Stats[StatIds.stamina].BaseValue; agilityBaseValue = character.Stats[StatIds.agility].BaseValue; senseBaseValue = character.Stats[StatIds.sense].BaseValue; intelligenceBaseValue = character.Stats[StatIds.intelligence].BaseValue; psychicBaseValue = character.Stats[StatIds.psychic].BaseValue; firstName = character.FirstName; lastName = character.LastName; orgNameLength = character.OrganizationName.Length; orgName = character.OrganizationName; levelValue = character.Stats[StatIds.level].Value; healthValue = character.Stats[StatIds.life].Value; monsterData = character.Stats[StatIds.monsterdata].Value; monsterScale = character.Stats[StatIds.monsterscale].Value; visualFlags = character.Stats[StatIds.visualflags].Value; currentMovementMode = character.Stats[StatIds.currentmovementmode].Value; runSpeedBaseValue = character.Stats[StatIds.runspeed].BaseValue; texturesCount = character.Textures.Count; headMeshValue = character.Stats[StatIds.headmesh].Value; foreach (int num in character.SocialTab.Keys) { socialTab.Add(num, character.SocialTab[num]); } foreach (AOTextures at in character.Textures) { textures.Add(new AOTextures(at.place, at.Texture)); } meshs = MeshLayers.GetMeshs(character, showsocial, socialonly); foreach (KeyValuePair<int, IActiveNano> kv in character.ActiveNanos) { var tempNano = new AONano(); tempNano.ID = kv.Value.ID; tempNano.Instance = kv.Value.Instance; tempNano.NanoStrain = kv.Key; tempNano.Nanotype = kv.Value.Nanotype; tempNano.TickCounter = kv.Value.TickCounter; tempNano.TickInterval = kv.Value.TickInterval; tempNano.Value3 = kv.Value.Value3; nanos.Add(tempNano); } losHeight = character.Stats[StatIds.losheight].Value; NPCFamily = character.Stats[StatIds.npcfamily].Value; currentHealth = character.Stats[StatIds.health].Value; } var scfu = new SimpleCharFullUpdateMessage(); // affected identity scfu.Identity = charId; scfu.Version = 57; // SCFU packet version (57/0x39) scfu.PlayfieldId = charPlayfield; // playfield if (character.FightingTarget.Instance != 0) { scfu.FightingTarget = new Identity { Type = character.FightingTarget.Type, Instance = character.FightingTarget.Instance }; } // Coordinates scfu.Coordinates = new Vector3 { X = charCoord.x, Y = charCoord.y, Z = charCoord.z }; // Heading Data scfu.Heading = new SmokeLounge.AOtomation.Messaging.GameData.Quaternion { W = charHeading.wf, X = charHeading.xf, Y = charHeading.yf, Z = charHeading.zf }; // Race scfu.Appearance = new Appearance { Side = (Side)sideValue, Fatness = (Fatness)fatValue, Breed = (Breed)breedValue, Gender = (Gender)sexValue, Race = raceValue }; // appearance // Name scfu.Name = charName; scfu.CharacterFlags = (CharacterFlags)charFlagsValue; // Flags scfu.AccountFlags = (short)accFlagsValue; scfu.Expansions = (short)expansionValue; bool isNpc = (NPCFamily != 1234567890) && (NPCFamily != 0); if (isNpc) { var snpc = new SimpleNpcInfo { Family = (short)NPCFamily, LosHeight = (short)losHeight }; scfu.CharacterInfo = snpc; } else { // Are we a player? var spc = new SimplePcInfo(); spc.CurrentNano = (uint)currentNano; // CurrentNano spc.Team = 0; // team? spc.Swim = 5; // swim? // The checks here are to prevent the client doing weird things if the character has really large or small base attributes spc.StrengthBase = (short)Math.Min(strengthBaseValue, short.MaxValue); // Strength spc.AgilityBase = (short)Math.Min(agilityBaseValue, short.MaxValue); // Agility spc.StaminaBase = (short)Math.Min(staminaBaseValue, short.MaxValue); // Stamina spc.IntelligenceBase = (short)Math.Min(intelligenceBaseValue, short.MaxValue); // Intelligence spc.SenseBase = (short)Math.Min(senseBaseValue, short.MaxValue); // Sense spc.PsychicBase = (short)Math.Min(psychicBaseValue, short.MaxValue); // Psychic if (scfu.CharacterFlags.HasFlag(CharacterFlags.HasVisibleName)) { // has visible names? (Flags) spc.FirstName = firstName; spc.LastName = lastName; } if (orgNameLength != 0) { spc.OrgName = orgName; } scfu.CharacterInfo = spc; } // Level scfu.Level = (short)levelValue; // Health scfu.Health = healthValue; scfu.HealthDamage = healthValue - currentHealth; // If player is in grid or fixer grid // make him/her/it a nice upside down pyramid if ((charPlayfield == 152) || (charPlayfield == 4107)) { scfu.MonsterData = 99902; } else { scfu.MonsterData = (uint)monsterData; // Monsterdata } scfu.MonsterScale = (short)monsterScale; // Monsterscale scfu.VisualFlags = (short)visualFlags; // VisualFlags scfu.VisibleTitle = 0; // visible title? // 42 bytes long // For PlayerCharacters that is // NPC's have a shorter one? scfu.Unknown1 = new byte[] { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, (byte)currentMovementMode, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // NPC Unknown1 if ((NPCFamily != 0) && (NPCFamily != 1234567890)) { scfu.Unknown1 = new byte[] { // Knubot values?? 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)currentMovementMode, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 }; } if (headMeshValue != 0) { scfu.HeadMesh = (uint?)headMeshValue; // Headmesh } // Runspeed scfu.RunSpeedBase = (short)runSpeedBaseValue; scfu.ActiveNanos = (from nano in nanos select new ActiveNano { NanoId = nano.ID, NanoInstance = nano.Instance, Time1 = nano.TickCounter, Time2 = nano.TickInterval }).ToArray(); // Texture/Cloth Data var scfuTextures = new List<Texture>(); var aotemp = new AOTextures(0, 0); for (int c = 0; c < 5; c++) { aotemp.Texture = 0; aotemp.place = c; for (int c2 = 0; c2 < texturesCount; c2++) { if (textures[c2].place != c) { continue; } aotemp.Texture = textures[c2].Texture; break; } if (showsocial) { if (socialonly) { aotemp.Texture = socialTab[c]; } else { if (socialTab[c] != 0) { aotemp.Texture = socialTab[c]; } } } scfuTextures.Add(new Texture { Place = aotemp.place, Id = aotemp.Texture, Unknown = 0 }); } scfu.Textures = scfuTextures.ToArray(); // End Textures // ############ // # Meshs // ############ scfu.Meshes = (from aoMesh in meshs select new Mesh { Position = (byte)aoMesh.Position, Id = (uint)aoMesh.Mesh, OverrideTextureId = aoMesh.OverrideTexture, Layer = (byte)aoMesh.Layer }).ToArray(); // End Meshs scfu.Flags2 = 0; // packetFlags2 scfu.Unknown2 = 0; return scfu; }