public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
        {
            ushort infoID              = inc.ReadUInt16();
            string newName             = inc.ReadString();
            int    gender              = inc.ReadByte();
            int    race                = inc.ReadByte();
            int    headSpriteID        = inc.ReadByte();
            int    hairIndex           = inc.ReadByte();
            int    beardIndex          = inc.ReadByte();
            int    moustacheIndex      = inc.ReadByte();
            int    faceAttachmentIndex = inc.ReadByte();
            string ragdollFile         = inc.ReadString();

            string jobIdentifier = inc.ReadString();
            int    variant       = inc.ReadByte();

            JobPrefab jobPrefab = null;
            Dictionary <string, float> skillLevels = new Dictionary <string, float>();

            if (!string.IsNullOrEmpty(jobIdentifier))
            {
                jobPrefab = JobPrefab.Get(jobIdentifier);
                byte skillCount = inc.ReadByte();
                for (int i = 0; i < skillCount; i++)
                {
                    string skillIdentifier = inc.ReadString();
                    float  skillLevel      = inc.ReadSingle();
                    skillLevels.Add(skillIdentifier, skillLevel);
                }
            }

            // TODO: animations
            CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile, variant)
            {
                ID = infoID,
            };

            ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
            if (ch.Job != null)
            {
                foreach (KeyValuePair <string, float> skill in skillLevels)
                {
                    Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
                    if (matchingSkill == null)
                    {
                        ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
                        continue;
                    }
                    matchingSkill.Level = skill.Value;
                }
                ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
            }
            return(ch);
        }
Пример #2
0
        public static WayPoint Load(XElement element, Submarine submarine)
        {
            Rectangle rect = new Rectangle(
                int.Parse(element.Attribute("x").Value),
                int.Parse(element.Attribute("y").Value),
                (int)Submarine.GridSize.X, (int)Submarine.GridSize.Y);


            Enum.TryParse(element.GetAttributeString("spawn", "Path"), out SpawnType spawnType);
            WayPoint w = new WayPoint(MapEntityPrefab.Find(null, spawnType == SpawnType.Path ? "waypoint" : "spawnpoint"), rect, submarine)
            {
                ID = (ushort)int.Parse(element.Attribute("ID").Value)
            };

            w.spawnType = spawnType;

            string idCardDescString = element.GetAttributeString("idcarddesc", "");

            if (!string.IsNullOrWhiteSpace(idCardDescString))
            {
                w.IdCardDesc = idCardDescString;
            }
            string idCardTagString = element.GetAttributeString("idcardtags", "");

            if (!string.IsNullOrWhiteSpace(idCardTagString))
            {
                w.IdCardTags = idCardTagString.Split(',');
            }

            string jobIdentifier = element.GetAttributeString("job", "").ToLowerInvariant();

            if (!string.IsNullOrWhiteSpace(jobIdentifier))
            {
                w.assignedJob =
                    JobPrefab.Get(jobIdentifier) ??
                    JobPrefab.Prefabs.Find(jp => jp.Name.Equals(jobIdentifier, StringComparison.OrdinalIgnoreCase));
            }

            w.ladderId = (ushort)element.GetAttributeInt("ladders", 0);
            w.gapId    = (ushort)element.GetAttributeInt("gap", 0);

            w.linkedToID = new List <ushort>();
            int i = 0;

            while (element.Attribute("linkedto" + i) != null)
            {
                w.linkedToID.Add((ushort)int.Parse(element.Attribute("linkedto" + i).Value));
                i += 1;
            }
            return(w);
        }
Пример #3
0
        private Character SpawnWatchman(Submarine outpost)
        {
            WayPoint watchmanSpawnpoint = WayPoint.WayPointList.Find(wp => wp.Submarine == outpost);

            if (watchmanSpawnpoint == null)
            {
                DebugConsole.ThrowError("Failed to spawn a watchman at the outpost. No spawnpoints found inside the outpost.");
                return(null);
            }

            string seed = outpost == Level.Loaded.StartOutpost ? map.SelectedLocation.Name : map.CurrentLocation.Name;

            Rand.SetSyncedSeed(ToolBox.StringToInt(seed));

            JobPrefab     watchmanJob      = JobPrefab.Get("watchman");
            var           variant          = Rand.Range(0, watchmanJob.Variants, Rand.RandSync.Server);
            CharacterInfo characterInfo    = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: watchmanJob, variant: variant);
            var           spawnedCharacter = Character.Create(characterInfo, watchmanSpawnpoint.WorldPosition,
                                                              Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));

            InitializeWatchman(spawnedCharacter);
            var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager;

            if (objectiveManager != null)
            {
                var moveOrder = new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false);
                moveOrder.Completed += () =>
                {
                    // Turn towards the center of the sub. Doesn't work in all possible cases, but this is the simplest solution for now.
                    spawnedCharacter.AnimController.TargetDir = spawnedCharacter.Submarine.WorldPosition.X > spawnedCharacter.WorldPosition.X ? Direction.Right : Direction.Left;
                };
                objectiveManager.SetOrder(moveOrder);
            }
            if (watchmanJob != null)
            {
                spawnedCharacter.GiveJobItems();
            }
            return(spawnedCharacter);
        }
Пример #4
0
        public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
        {
            ushort infoID              = inc.ReadUInt16();
            string newName             = inc.ReadString();
            string originalName        = inc.ReadString();
            int    gender              = inc.ReadByte();
            int    race                = inc.ReadByte();
            int    headSpriteID        = inc.ReadByte();
            int    hairIndex           = inc.ReadByte();
            int    beardIndex          = inc.ReadByte();
            int    moustacheIndex      = inc.ReadByte();
            int    faceAttachmentIndex = inc.ReadByte();
            Color  skinColor           = inc.ReadColorR8G8B8();
            Color  hairColor           = inc.ReadColorR8G8B8();
            Color  facialHairColor     = inc.ReadColorR8G8B8();
            string ragdollFile         = inc.ReadString();

            string jobIdentifier = inc.ReadString();
            int    variant       = inc.ReadByte();

            JobPrefab jobPrefab = null;
            Dictionary <string, float> skillLevels = new Dictionary <string, float>();

            if (!string.IsNullOrEmpty(jobIdentifier))
            {
                jobPrefab = JobPrefab.Get(jobIdentifier);
                byte skillCount = inc.ReadByte();
                for (int i = 0; i < skillCount; i++)
                {
                    string skillIdentifier = inc.ReadString();
                    float  skillLevel      = inc.ReadSingle();
                    skillLevels.Add(skillIdentifier, skillLevel);
                }
            }

            // TODO: animations
            CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant)
            {
                ID = infoID,
            };

            ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
            ch.SkinColor       = skinColor;
            ch.HairColor       = hairColor;
            ch.FacialHairColor = facialHairColor;
            if (ch.Job != null)
            {
                foreach (KeyValuePair <string, float> skill in skillLevels)
                {
                    Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
                    if (matchingSkill == null)
                    {
                        ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
                        continue;
                    }
                    matchingSkill.Level = skill.Value;
                }
                ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
            }

            byte savedStatValueCount = inc.ReadByte();

            for (int i = 0; i < savedStatValueCount; i++)
            {
                int    statType       = inc.ReadByte();
                string statIdentifier = inc.ReadString();
                float  statValue      = inc.ReadSingle();
                bool   removeOnDeath  = inc.ReadBoolean();
                ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
            }
            ch.ExperiencePoints       = inc.ReadUInt16();
            ch.AdditionalTalentPoints = inc.ReadUInt16();
            return(ch);
        }
Пример #5
0
        private LocationType(XElement element)
        {
            Identifier    = element.GetAttributeString("identifier", element.Name.ToString());
            Name          = TextManager.Get("LocationName." + Identifier, fallBackTag: "unknown");
            nameFormats   = TextManager.GetAll("LocationNameFormat." + Identifier);
            UseInMainMenu = element.GetAttributeBool("useinmainmenu", false);
            HasOutpost    = element.GetAttributeBool("hasoutpost", true);

            string nameFile = element.GetAttributeString("namefile", "Content/Map/locationNames.txt");

            try
            {
                names = File.ReadAllLines(nameFile).ToList();
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Failed to read name file for location type \"" + Identifier + "\"!", e);
                names = new List <string>()
                {
                    "Name file not found"
                };
            }

            string[] commonnessPerZoneStrs = element.GetAttributeStringArray("commonnessperzone", new string[] { "" });
            foreach (string commonnessPerZoneStr in commonnessPerZoneStrs)
            {
                string[] splitCommonnessPerZone = commonnessPerZoneStr.Split(':');
                if (splitCommonnessPerZone.Length != 2 ||
                    !int.TryParse(splitCommonnessPerZone[0].Trim(), out int zoneIndex) ||
                    !float.TryParse(splitCommonnessPerZone[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out float zoneCommonness))
                {
                    DebugConsole.ThrowError("Failed to read commonness values for location type \"" + Identifier + "\" - commonness should be given in the format \"zone0index: zone0commonness, zone1index: zone1commonness\"");
                    break;
                }
                CommonnessPerZone[zoneIndex] = zoneCommonness;
            }

            hireableJobs = new List <Tuple <JobPrefab, float> >();
            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "hireable":
                    string    jobIdentifier = subElement.GetAttributeString("identifier", "");
                    JobPrefab jobPrefab     = null;
                    if (jobIdentifier == "")
                    {
                        DebugConsole.ThrowError("Error in location type \"" + Identifier + "\" - hireable jobs should be configured using identifiers instead of names.");
                    }
                    else
                    {
                        jobPrefab = JobPrefab.Get(jobIdentifier.ToLowerInvariant());
                    }
                    if (jobPrefab == null)
                    {
                        DebugConsole.ThrowError("Error in  in location type " + Identifier + " - could not find a job with the identifier \"" + jobIdentifier + "\".");
                        continue;
                    }
                    float jobCommonness = subElement.GetAttributeFloat("commonness", 1.0f);
                    totalHireableWeight += jobCommonness;
                    Tuple <JobPrefab, float> hireableJob = new Tuple <JobPrefab, float>(jobPrefab, jobCommonness);
                    hireableJobs.Add(hireableJob);
                    break;

                case "symbol":
                    symbolSprite = new Sprite(subElement, lazyLoad: true);
                    SpriteColor  = subElement.GetAttributeColor("color", Color.White);
                    break;

                case "changeto":
                    CanChangeTo.Add(new LocationTypeChange(Identifier, subElement));
                    break;

                case "portrait":
                    var portrait = new Sprite(subElement, lazyLoad: true);
                    if (portrait != null)
                    {
                        portraits.Add(portrait);
                    }
                    break;
                }
            }
        }
Пример #6
0
        private void GetDisguisedSprites(IdCard idCard)
        {
            if (idCard.Item.Tags == string.Empty)
            {
                return;
            }

            if (idCard.StoredJobPrefab == null || idCard.StoredPortrait == null)
            {
                string[] readTags = idCard.Item.Tags.Split(',');

                if (readTags.Length == 0)
                {
                    return;
                }

                if (idCard.StoredJobPrefab == null)
                {
                    string jobIdTag = readTags.FirstOrDefault(s => s.StartsWith("jobid:"));

                    if (jobIdTag != null && jobIdTag.Length > 6)
                    {
                        string jobId = jobIdTag.Substring(6);
                        if (jobId != string.Empty)
                        {
                            idCard.StoredJobPrefab = JobPrefab.Get(jobId);
                        }
                    }
                }

                if (idCard.StoredPortrait == null)
                {
                    string disguisedGender              = string.Empty;
                    string disguisedRace                = string.Empty;
                    string disguisedHeadSpriteId        = string.Empty;
                    int    disguisedHairIndex           = -1;
                    int    disguisedBeardIndex          = -1;
                    int    disguisedMoustacheIndex      = -1;
                    int    disguisedFaceAttachmentIndex = -1;

                    foreach (string tag in readTags)
                    {
                        string[] s = tag.Split(':');

                        switch (s[0])
                        {
                        case "gender":
                            disguisedGender = s[1];
                            break;

                        case "race":
                            disguisedRace = s[1];
                            break;

                        case "headspriteid":
                            disguisedHeadSpriteId = s[1];
                            break;

                        case "hairindex":
                            disguisedHairIndex = int.Parse(s[1]);
                            break;

                        case "beardindex":
                            disguisedBeardIndex = int.Parse(s[1]);
                            break;

                        case "moustacheindex":
                            disguisedMoustacheIndex = int.Parse(s[1]);
                            break;

                        case "faceattachmentindex":
                            disguisedFaceAttachmentIndex = int.Parse(s[1]);
                            break;

                        case "sheetindex":
                            string[] vectorValues = s[1].Split(";");
                            idCard.StoredSheetIndex = new Vector2(float.Parse(vectorValues[0]), float.Parse(vectorValues[1]));
                            break;
                        }
                    }

                    if (disguisedGender == string.Empty || disguisedRace == string.Empty || disguisedHeadSpriteId == string.Empty)
                    {
                        idCard.StoredPortrait    = null;
                        idCard.StoredAttachments = null;
                        return;
                    }

                    foreach (XElement limbElement in Ragdoll.MainElement.Elements())
                    {
                        if (!limbElement.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        XElement spriteElement = limbElement.Element("sprite");
                        if (spriteElement == null)
                        {
                            continue;
                        }

                        string spritePath = spriteElement.Attribute("texture").Value;

                        spritePath = spritePath.Replace("[GENDER]", disguisedGender);
                        spritePath = spritePath.Replace("[RACE]", disguisedRace.ToLowerInvariant());
                        spritePath = spritePath.Replace("[HEADID]", disguisedHeadSpriteId);

                        string fileName = Path.GetFileNameWithoutExtension(spritePath);

                        //go through the files in the directory to find a matching sprite
                        foreach (string file in Directory.GetFiles(Path.GetDirectoryName(spritePath)))
                        {
                            if (!file.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
                            {
                                continue;
                            }
                            string fileWithoutTags = Path.GetFileNameWithoutExtension(file);
                            fileWithoutTags = fileWithoutTags.Split('[', ']').First();
                            if (fileWithoutTags != fileName)
                            {
                                continue;
                            }
                            idCard.StoredPortrait = new Sprite(spriteElement, "", file)
                            {
                                RelativeOrigin = Vector2.Zero
                            };
                            break;
                        }

                        break;
                    }

                    if (Wearables != null)
                    {
                        XElement        disguisedHairElement, disguisedBeardElement, disguisedMoustacheElement, disguisedFaceAttachmentElement;
                        List <XElement> disguisedHairs, disguisedBeards, disguisedMoustaches, disguisedFaceAttachments;

                        Gender disguisedGenderEnum = disguisedGender == "female" ? Gender.Female : Gender.Male;
                        Race   disguisedRaceEnum   = (Race)Enum.Parse(typeof(Race), disguisedRace);
                        int    headSpriteId        = int.Parse(disguisedHeadSpriteId);

                        float commonness = disguisedGenderEnum == Gender.Female ? 0.05f : 0.2f;
                        disguisedHairs           = AddEmpty(FilterByTypeAndHeadID(FilterElementsByGenderAndRace(wearables, disguisedGenderEnum, disguisedRaceEnum), WearableType.Hair, headSpriteId), WearableType.Hair, commonness);
                        disguisedBeards          = AddEmpty(FilterByTypeAndHeadID(FilterElementsByGenderAndRace(wearables, disguisedGenderEnum, disguisedRaceEnum), WearableType.Beard, headSpriteId), WearableType.Beard);
                        disguisedMoustaches      = AddEmpty(FilterByTypeAndHeadID(FilterElementsByGenderAndRace(wearables, disguisedGenderEnum, disguisedRaceEnum), WearableType.Moustache, headSpriteId), WearableType.Moustache);
                        disguisedFaceAttachments = AddEmpty(FilterByTypeAndHeadID(FilterElementsByGenderAndRace(wearables, disguisedGenderEnum, disguisedRaceEnum), WearableType.FaceAttachment, headSpriteId), WearableType.FaceAttachment);

                        if (IsValidIndex(disguisedHairIndex, disguisedHairs))
                        {
                            disguisedHairElement = disguisedHairs[disguisedHairIndex];
                        }
                        else
                        {
                            disguisedHairElement = GetRandomElement(disguisedHairs);
                        }
                        if (IsValidIndex(disguisedBeardIndex, disguisedBeards))
                        {
                            disguisedBeardElement = disguisedBeards[disguisedBeardIndex];
                        }
                        else
                        {
                            disguisedBeardElement = GetRandomElement(disguisedBeards);
                        }

                        if (IsValidIndex(disguisedMoustacheIndex, disguisedMoustaches))
                        {
                            disguisedMoustacheElement = disguisedMoustaches[disguisedMoustacheIndex];
                        }
                        else
                        {
                            disguisedMoustacheElement = GetRandomElement(disguisedMoustaches);
                        }
                        if (IsValidIndex(disguisedFaceAttachmentIndex, disguisedFaceAttachments))
                        {
                            disguisedFaceAttachmentElement = disguisedFaceAttachments[disguisedFaceAttachmentIndex];
                        }
                        else
                        {
                            disguisedFaceAttachmentElement = GetRandomElement(disguisedFaceAttachments);
                        }

                        idCard.StoredAttachments = new List <WearableSprite>();

                        disguisedFaceAttachmentElement?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.FaceAttachment)));
                        disguisedBeardElement?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.Beard)));
                        disguisedMoustacheElement?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.Moustache)));
                        disguisedHairElement?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.Hair)));

                        if (OmitJobInPortraitClothing)
                        {
                            JobPrefab.NoJobElement?.Element("PortraitClothing")?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.JobIndicator)));
                        }
                        else
                        {
                            idCard.StoredJobPrefab?.ClothingElement?.Elements("sprite").ForEach(s => idCard.StoredAttachments.Add(new WearableSprite(s, WearableType.JobIndicator)));
                        }
                    }
                }
            }

            if (idCard.StoredJobPrefab != null)
            {
                disguisedJobIcon  = idCard.StoredJobPrefab.Icon;
                disguisedJobColor = idCard.StoredJobPrefab.UIColor;
            }

            disguisedPortrait          = idCard.StoredPortrait;
            disguisedSheetIndex        = idCard.StoredSheetIndex;
            disguisedAttachmentSprites = idCard.StoredAttachments;
        }