Exemplo n.º 1
0
        public static void HandleCharacterCreate(WorldSession session, ClientCharacterCreate characterCreate)
        {
            try
            {
                // TODO: validate name and path

                CharacterCreationEntry creationEntry = GameTableManager.CharacterCreation.GetEntry(characterCreate.CharacterCreationId);
                if (creationEntry == null)
                {
                    throw new InvalidPacketValueException();
                }

                if (creationEntry.EntitlementIdRequired != 0u)
                {
                    // TODO: Aurin engineer has this
                }

                var character = new Character
                {
                    AccountId  = session.Account.Id,
                    Id         = AssetManager.NextCharacterId,
                    Name       = characterCreate.Name,
                    Race       = (byte)creationEntry.RaceId,
                    Sex        = (byte)creationEntry.Sex,
                    Class      = (byte)creationEntry.ClassId,
                    Level      = 1,
                    FactionId  = (ushort)creationEntry.FactionId,
                    ActivePath = characterCreate.Path
                };

                for (Path path = Path.Soldier; path <= Path.Explorer; path++)
                {
                    character.CharacterPath.Add(new CharacterPath
                    {
                        Path     = (byte)path,
                        Unlocked = Convert.ToByte(characterCreate.Path == (byte)path)
                    });
                }

                // merge seperate label and value lists into a single dictonary
                Dictionary <uint, uint> customisations = characterCreate.Labels
                                                         .Zip(characterCreate.Values, (l, v) => new { l, v })
                                                         .ToDictionary(p => p.l, p => p.v);

                foreach ((uint label, uint value) in customisations)
                {
                    character.CharacterCustomisation.Add(new CharacterCustomisation
                    {
                        Label = label,
                        Value = value
                    });

                    CharacterCustomizationEntry entry = GetCharacterCustomisation(customisations, creationEntry.RaceId, creationEntry.Sex, label, value);
                    if (entry == null)
                    {
                        continue;
                    }

                    character.CharacterAppearance.Add(new CharacterAppearance
                    {
                        Slot      = (byte)entry.ItemSlotId,
                        DisplayId = (ushort)entry.ItemDisplayId
                    });
                }

                for (int i = 0; i < characterCreate.Bones.Count; ++i)
                {
                    character.CharacterBone.Add(new CharacterBone
                    {
                        BoneIndex = (byte)(i),
                        Bone      = characterCreate.Bones[i]
                    });
                }
                //TODO: handle starting locations per race
                character.LocationX = -7683.809f;
                character.LocationY = -942.5914f;
                character.LocationZ = -666.6343f;
                character.WorldId   = 870;

                // create a temporary inventory to create starting gear
                var inventory = new Inventory(character.Id, creationEntry);
                var items     = inventory
                                .SelectMany(b => b)
                                .Select(i => i);

                // TODO: actually error check this
                session.EnqueueEvent(new TaskEvent(CharacterDatabase.CreateCharacter(character, items),
                                                   () =>
                {
                    session.Characters.Add(character);
                    session.EnqueueMessageEncrypted(new ServerCharacterCreate
                    {
                        CharacterId = character.Id,
                        WorldId     = character.WorldId,
                        Result      = 3
                    });
                }));
            }
            catch
            {
                session.EnqueueMessageEncrypted(new ServerCharacterCreate
                {
                    Result = 0
                });

                throw;
            }

            CharacterCustomizationEntry GetCharacterCustomisation(Dictionary <uint, uint> customisations, uint race, uint sex, uint primaryLabel, uint primaryValue)
            {
                ImmutableList <CharacterCustomizationEntry> entries = AssetManager.GetPrimaryCharacterCustomisation(race, sex, primaryLabel, primaryValue);

                if (entries == null)
                {
                    return(null);
                }
                if (entries.Count == 1)
                {
                    return(entries[0]);
                }

                // customisation has multiple results, filter with secondary label and value
                uint secondaryLabel = entries.First(e => e.CharacterCustomizationLabelId01 != 0).CharacterCustomizationLabelId01;
                uint secondaryValue = customisations[secondaryLabel];

                CharacterCustomizationEntry entry = entries.SingleOrDefault(e => e.CharacterCustomizationLabelId01 == secondaryLabel && e.Value01 == secondaryValue);

                return(entry ?? entries.Single(e => e.CharacterCustomizationLabelId01 == 0 && e.Value01 == 0));
            }
        }
Exemplo n.º 2
0
        public static void HandleCharacterCreate(WorldSession session, ClientCharacterCreate characterCreate)
        {
            try
            {
                // TODO: validate name and path
                if (DatabaseManager.Instance.CharacterDatabase.CharacterNameExists(characterCreate.Name))
                {
                    session.EnqueueMessageEncrypted(new ServerCharacterCreate
                    {
                        Result = CharacterModifyResult.CreateFailed_UniqueName
                    });

                    return;
                }

                CharacterCreationEntry creationEntry = GameTableManager.Instance.CharacterCreation.GetEntry(characterCreate.CharacterCreationId);
                if (creationEntry == null)
                {
                    throw new InvalidPacketValueException();
                }

                if (creationEntry.EntitlementIdRequired != 0u)
                {
                    // TODO: Aurin engineer has this
                }

                var character = new CharacterModel
                {
                    AccountId  = session.Account.Id,
                    Id         = AssetManager.Instance.NextCharacterId,
                    Name       = characterCreate.Name,
                    Race       = (byte)creationEntry.RaceId,
                    Sex        = (byte)creationEntry.Sex,
                    Class      = (byte)creationEntry.ClassId,
                    FactionId  = (ushort)creationEntry.FactionId,
                    ActivePath = characterCreate.Path
                };

                for (Path path = Path.Soldier; path <= Path.Explorer; path++)
                {
                    character.Path.Add(new CharacterPathModel
                    {
                        Path     = (byte)path,
                        Unlocked = Convert.ToByte(characterCreate.Path == (byte)path)
                    });
                }

                // merge seperate label and value lists into a single dictonary
                Dictionary <uint, uint> customisations = characterCreate.Labels
                                                         .Zip(characterCreate.Values, (l, v) => new { l, v })
                                                         .ToDictionary(p => p.l, p => p.v);

                foreach ((uint label, uint value) in customisations)
                {
                    character.Customisation.Add(new CharacterCustomisationModel
                    {
                        Label = label,
                        Value = value
                    });

                    CharacterCustomizationEntry entry = GetCharacterCustomisation(customisations, creationEntry.RaceId, creationEntry.Sex, label, value);
                    if (entry == null)
                    {
                        continue;
                    }

                    character.Appearance.Add(new CharacterAppearanceModel
                    {
                        Slot      = (byte)entry.ItemSlotId,
                        DisplayId = (ushort)entry.ItemDisplayId
                    });
                }

                for (int i = 0; i < characterCreate.Bones.Count; ++i)
                {
                    character.Bone.Add(new CharacterBoneModel
                    {
                        BoneIndex = (byte)(i),
                        Bone      = characterCreate.Bones[i]
                    });
                }

                //TODO: handle starting locations per race
                character.LocationX = -7683.809f;
                character.LocationY = -942.5914f;
                character.LocationZ = -666.6343f;
                character.WorldId   = 870;

                character.ActiveSpec = 0;

                // create initial LAS abilities
                UILocation location = 0;
                foreach (SpellLevelEntry spellLevelEntry in GameTableManager.Instance.SpellLevel.Entries
                         .Where(s => s.ClassId == character.Class && s.CharacterLevel == 1))
                {
                    Spell4Entry spell4Entry = GameTableManager.Instance.Spell4.GetEntry(spellLevelEntry.Spell4Id);
                    if (spell4Entry == null)
                    {
                        continue;
                    }

                    character.Spell.Add(new CharacterSpellModel
                    {
                        Id           = character.Id,
                        Spell4BaseId = spell4Entry.Spell4BaseIdBaseSpell,
                        Tier         = 1
                    });

                    character.ActionSetShortcut.Add(new CharacterActionSetShortcutModel
                    {
                        Id           = character.Id,
                        SpecIndex    = 0,
                        Location     = (ushort)location,
                        ShortcutType = (byte)ShortcutType.Spell,
                        ObjectId     = spell4Entry.Spell4BaseIdBaseSpell,
                        Tier         = 1
                    });

                    location++;
                }

                // create a temporary inventory to create starting gear
                var inventory            = new Inventory(character.Id, creationEntry);
                IEnumerable <Item> items = inventory
                                           .SelectMany(b => b)
                                           .Select(i => i);

                //TODO: handle starting stats per class/race
                character.Stat.Add(new CharacterStatModel
                {
                    Id    = character.Id,
                    Stat  = (byte)Stat.Health,
                    Value = 800
                });
                character.Stat.Add(new CharacterStatModel
                {
                    Id    = character.Id,
                    Stat  = (byte)Stat.Shield,
                    Value = 450
                });
                character.Stat.Add(new CharacterStatModel
                {
                    Id    = character.Id,
                    Stat  = (byte)Stat.Dash,
                    Value = 200
                });
                character.Stat.Add(new CharacterStatModel
                {
                    Id    = character.Id,
                    Stat  = (byte)Stat.Level,
                    Value = 1
                });
                character.Stat.Add(new CharacterStatModel
                {
                    Id    = character.Id,
                    Stat  = (byte)Stat.StandState,
                    Value = 3
                });

                // TODO: actually error check this
                session.EnqueueEvent(new TaskEvent(DatabaseManager.Instance.CharacterDatabase.Save(c =>
                {
                    c.Character.Add(character);
                    foreach (Item item in items)
                    {
                        item.Save(c);
                    }
                }),
                                                   () =>
                {
                    session.Characters.Add(character);
                    session.EnqueueMessageEncrypted(new ServerCharacterCreate
                    {
                        CharacterId = character.Id,
                        WorldId     = character.WorldId,
                        Result      = CharacterModifyResult.CreateOk
                    });
                }));
            }
            catch
            {
                session.EnqueueMessageEncrypted(new ServerCharacterCreate
                {
                    Result = CharacterModifyResult.CreateFailed
                });

                throw;
            }

            CharacterCustomizationEntry GetCharacterCustomisation(Dictionary <uint, uint> customisations, uint race, uint sex, uint primaryLabel, uint primaryValue)
            {
                ImmutableList <CharacterCustomizationEntry> entries = AssetManager.Instance.GetPrimaryCharacterCustomisation(race, sex, primaryLabel, primaryValue);

                if (entries == null)
                {
                    return(null);
                }
                if (entries.Count == 1)
                {
                    return(entries[0]);
                }

                // customisation has multiple results, filter with secondary label and value
                uint secondaryLabel = entries.First(e => e.CharacterCustomizationLabelId01 != 0).CharacterCustomizationLabelId01;
                uint secondaryValue = customisations[secondaryLabel];

                CharacterCustomizationEntry entry = entries.SingleOrDefault(e => e.CharacterCustomizationLabelId01 == secondaryLabel && e.Value01 == secondaryValue);

                return(entry ?? entries.Single(e => e.CharacterCustomizationLabelId01 == 0 && e.Value01 == 0));
            }
        }