Exemple #1
0
        dynamic AddQuestNpc(dynamic quest, Saint.ENpc sNpc)
        {
            if (Hacks.IsNpcSkipped(sNpc))
            {
                return(null);
            }

            var npc = _builder.Db.NpcsById[sNpc.Key];

            if (npc.quests == null)
            {
                npc.quests = new JArray();
            }

            var    questId = (int)quest.id;
            JArray quests  = npc.quests;

            if (!quests.Any(id => ((int)id) == questId))
            {
                quests.Add(questId);
                _builder.Db.AddReference(npc, "quest", questId, false);
                _builder.Db.AddReference(quest, "npc", (int)npc.id, false);
            }

            return(npc);
        }
Exemple #2
0
        dynamic AddQuestNpc(dynamic quest, Saint.ENpc sNpc)
        {
            var questId = (int)quest.id;

            var npc = _builder.GetOrCreateNpc(sNpc);

            if (npc == null)
            {
                return(null);
            }

            if (npc.quests == null)
            {
                npc.quests = new JArray();
            }

            JArray quests = npc.quests;

            if (!quests.Any(id => ((int)id) == questId))
            {
                quests.Add(questId);
                _builder.Db.AddReference(npc, "quest", questId, false);
                _builder.Db.AddReference(quest, "npc", (int)npc.id, false);
            }

            return(npc);
        }
Exemple #3
0
        void BuildAppearanceData(dynamic npc, Saint.ENpc sNpc)
        {
            var race = (Saint.Race)sNpc.Base["Race"];

            if (race == null || race.Key == 0)
            {
                return; // Unique or beast NPCs, can't do appearance now.
            }
            dynamic appearance = new JObject();

            npc.appearance = appearance;

            var gender = (byte)sNpc.Base["Gender"];
            var isMale = gender == 0;

            appearance.gender = isMale ? "Male" : "Female";

            appearance.race = isMale ? race.Masculine.ToString() : race.Feminine.ToString();

            var tribe = (Saint.Tribe)sNpc.Base["Tribe"];

            appearance.tribe = isMale ? tribe.Masculine.ToString() : tribe.Feminine.ToString();

            appearance.height = sNpc.Base["Height"];

            var bodyType = (byte)sNpc.Base["BodyType"];

            if (bodyType != 1)
            {
                appearance.bodyType = GetBodyType(bodyType);
            }

            // Faces
            var baseFace = (byte)sNpc.Base["Face"];
            var face     = baseFace % 100; // Value matches the asset number, % 100 approximate face # nicely.

            appearance.face = face;

            var isValidFace  = face < 8;
            var isCustomFace = baseFace > 7;

            if (isCustomFace)
            {
                appearance.customFace = 1;
            }

            appearance.jaw = 1 + (byte)sNpc.Base["Jaw"];

            appearance.eyebrows = 1 + (byte)sNpc.Base["Eyebrows"];

            appearance.nose = 1 + (byte)sNpc.Base["Nose"];

            appearance.skinColor     = FormatColorCoordinates((byte)sNpc.Base["SkinColor"]);
            appearance.skinColorCode = FormatColor((byte)sNpc.Base["SkinColor"], GetSkinColorMapIndex(tribe.Key, isMale));

            // Bust & Muscles - flex fields.
            if (race.Key == 5 || race.Key == 1)
            {
                // Roegadyn & Hyur
                appearance.muscle = (byte)sNpc.Base["BustOrTone1"];
                if (!isMale)
                {
                    appearance.bust = (byte)sNpc.Base["ExtraFeature2OrBust"];
                }
            }
            else if (race.Key == 6 && isMale)
            {
                // Au Ra male muscles
                appearance.muscle = (byte)sNpc.Base["BustOrTone1"];
            }
            else if (!isMale)
            {
                // Other female bust sizes
                appearance.bust = (byte)sNpc.Base["BustOrTone1"];
            }

            // Hair & Highlights
            var hairstyle     = (byte)sNpc.Base["HairStyle"];
            var hairstyleIcon = CustomizeIcon(GetHairstyleCustomizeIndex(tribe.Key, isMale), 100, hairstyle, npc, appearance);

            if (hairstyleIcon > 0)
            {
                appearance.hairStyle = hairstyleIcon;
            }

            appearance.hairColor     = FormatColorCoordinates((byte)sNpc.Base["HairColor"]);
            appearance.hairColorCode = FormatColor((byte)sNpc.Base["HairColor"], GetHairColorMapIndex(tribe.Key, isMale));

            var highlights = Unpack2((byte)sNpc.Base["HairHighlight"]);

            if (highlights.Item1 == 1)
            {
                appearance.highlightColor     = FormatColorCoordinates((byte)sNpc.Base["HairHighlightColor"]);
                appearance.highlightColorCode = FormatColor((byte)sNpc.Base["HairHighlightColor"], HairHighlightColorOffset);
            }

            // Eyes & Heterochromia
            var eyeShape = Unpack2((byte)sNpc.Base["EyeShape"]);

            appearance.eyeSize  = eyeShape.Item1 == 1 ? "Small" : "Large";
            appearance.eyeShape = 1 + eyeShape.Item2;

            var eyeColor = (byte)sNpc.Base["EyeColor"];

            appearance.eyeColor     = FormatColorCoordinates(eyeColor);
            appearance.eyeColorCode = FormatColor(eyeColor, EyeColorOffset);

            var heterochromia = (byte)sNpc.Base["EyeHeterochromia"];

            if (heterochromia != eyeColor)
            {
                appearance.heterochromia     = FormatColorCoordinates(heterochromia);
                appearance.heterochromiaCode = FormatColor(heterochromia, EyeColorOffset);
            }

            // Mouth & Lips
            var mouth = Unpack2((byte)sNpc.Base["Mouth"]);

            appearance.mouth = 1 + mouth.Item2;

            if (mouth.Item1 == 1)
            {
                var lipColor = Unpack2((byte)sNpc.Base["LipColor"]);
                appearance.lipShade     = lipColor.Item1 == 1 ? "Light" : "Dark";
                appearance.lipColor     = FormatColorCoordinates(lipColor.Item2);
                appearance.lipColorCode = FormatColor(lipColor.Item2, lipColor.Item1 == 1 ? LightLipFacePaintColorOffset : DarkLipFacePaintColorOffset);
            }

            // Extra Features
            var extraFeatureName = ExtraFeatureName(race.Key);

            if (extraFeatureName != null)
            {
                appearance.extraFeatureName = extraFeatureName;

                appearance.extraFeatureShape = (byte)sNpc.Base["ExtraFeature1"];
                appearance.extraFeatureSize  = (byte)sNpc.Base["ExtraFeature2OrBust"];
            }

            // Facepaint
            var facepaint     = Unpack2((byte)sNpc.Base["FacePaint"]);
            var facepaintIcon = CustomizeIcon(GetFacePaintCustomizeIndex(tribe.Key, isMale), 50, facepaint.Item2, npc, appearance);

            if (facepaintIcon > 0)
            {
                appearance.facepaint = facepaintIcon;

                if (facepaint.Item1 == 1)
                {
                    appearance.facepaintReverse = 1;
                }

                var facepaintColor = Unpack2((byte)sNpc.Base["FacePaintColor"]);
                appearance.facepaintShade     = facepaintColor.Item1 == 1 ? "Light" : "Dark";
                appearance.facepaintColor     = FormatColorCoordinates(facepaintColor.Item2);
                appearance.facepaintColorCode = FormatColor(facepaintColor.Item2, facepaintColor.Item1 == 1 ? LightLipFacePaintColorOffset : DarkLipFacePaintColorOffset);
            }

            // Facial Features
            var facialfeature = (byte)sNpc.Base["FacialFeature"];

            if (facialfeature != 0 && isValidFace)
            {
                var type = CharaMakeTypeRow(tribe.Key, gender);

                appearance.facialfeatures = new JArray();

                // There are only 7 groups of facial features at the moment.
                var facialfeatures = new System.Collections.BitArray(new byte[] { facialfeature });
                for (var i = 0; i < 7; i++)
                {
                    if (!facialfeatures[i])
                    {
                        continue;
                    }

                    var iconIndex = face;
                    // If it's not hrotgar, shift to -1
                    if (race.Key != 7)
                    {
                        iconIndex--;
                    }

                    var column = "FacialFeatureOption[" + iconIndex + "][" + i + "]";

                    var icon = (ImageFile)type[column];
                    if (icon == null)
                    {
                        continue; // Nothing to show.
                    }
                    appearance.facialfeatures.Add(IconDatabase.EnsureEntry("customize", icon));
                }

                appearance.facialfeatureColor     = FormatColorCoordinates((byte)sNpc.Base["FacialFeatureColor"]);
                appearance.facialfeatureColorCode = FormatColor((byte)sNpc.Base["FacialFeatureColor"], 0);
            }

            // todo: CharaMakeType ExtraFeatureData for faces, extra feature icons.
        }
        public dynamic GetOrCreateNpc(Saint.ENpc sNpc)
        {
            if (_db.NpcsById.TryGetValue(sNpc.Key, out var npc))
            {
                return(npc);
            }

            if (string.IsNullOrWhiteSpace(sNpc.Singular))
            {
                return(null); // Bad or unreferenced NPC.
            }
            npc    = new JObject();
            npc.id = sNpc.Key;
            Localize.Column((JObject)npc, sNpc.Resident, "Singular", "name", Utils.CapitalizeWords);
            string name = npc.en.name;

            npc.patch = PatchDatabase.Get("npc", sNpc.Key);

            // Set base information.
            if (!_db.NpcAlternatesByName.TryGetValue(name, out var alts))
            {
                alts = new List <dynamic>();
                _db.NpcAlternatesByName[name] = alts;
            }
            alts.Add(npc);

            var title = sNpc.Title.ToString();

            if (!string.IsNullOrEmpty(title))
            {
                npc.title = title;
            }

            // Map and coordinates.
            if (LevelByNpcObjectKey.TryGetValue(sNpc.Key, out var level) && LocationInfoByMapId.TryGetValue(level.Map.Key, out var locationInfo))
            {
                npc.zoneid = locationInfo.PlaceName.Key;
                npc.coords = GetCoords(level);
                _db.AddLocationReference(locationInfo.PlaceName.Key);
            }
            else
            {
                if (_db.NpcZoneByNpcId.ContainsKey(sNpc.Key))
                {
                    var zoneid = _db.NpcZoneByNpcId[sNpc.Key];
                    npc.zoneid = zoneid;
                    _db.AddLocationReference(zoneid);
                }

                if (_libraNpcIndex.TryGetValue(sNpc.Key, out var lNpc))
                {
                    dynamic data = JsonConvert.DeserializeObject((string)lNpc.data);
                    var     zone = Utils.GetPair(data.coordinate);
                    npc.coords = Utils.GetFirst(zone.Value);
                    npc.approx = 1;
                }
            }

            // Closest map marker.
            if (level != null)
            {
                var marker = MapMarker.FindClosest(this, level.Map, level.MapX, level.MapY);
                if (marker != null)
                {
                    npc.areaid = marker.PlaceName.Key;
                    _db.AddLocationReference(marker.PlaceName.Key);
                }
            }

            _db.Npcs.Add(npc);
            _db.NpcsById[sNpc.Key] = npc;
            return(npc);
        }