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); }
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); }
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); }
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); }
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; } } }
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; }