Server LuaCsForBarotrauma
JobPrefab.cs
2 using Microsoft.Xna.Framework;
3 using System;
4 using System.Collections.Generic;
5 using System.Collections.Immutable;
6 using System.Linq;
7 using System.Xml.Linq;
8 
9 namespace Barotrauma
10 {
11  public class AutonomousObjective
12  {
13  public readonly Identifier Identifier;
14  public readonly Identifier Option;
15  public readonly float PriorityModifier;
19  public readonly bool IgnoreAtOutpost;
23  public readonly bool IgnoreAtNonOutpost;
24 
25  public AutonomousObjective(XElement element)
26  {
27  Identifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
28 
29  //backwards compatibility
30  if (Identifier == Identifier.Empty)
31  {
32  Identifier = element.GetAttributeIdentifier("aitag", Identifier.Empty);
33  }
34 
35  Option = element.GetAttributeIdentifier("option", Identifier.Empty);
36  PriorityModifier = element.GetAttributeFloat("prioritymodifier", 1);
37  PriorityModifier = MathHelper.Max(PriorityModifier, 0);
38  IgnoreAtOutpost = element.GetAttributeBool("ignoreatoutpost", false);
39  IgnoreAtNonOutpost = element.GetAttributeBool("ignoreatnonoutpost", false);
40  }
41  }
42 
44  {
46 
47  public readonly float Priority;
48 
49  public ItemRepairPriority(XElement element, JobsFile file) : base(file, element.GetAttributeIdentifier("tag", Identifier.Empty))
50  {
51  Priority = element.GetAttributeFloat("priority", -1f);
52  if (Priority < 0)
53  {
54  DebugConsole.AddWarning($"The 'priority' attribute is missing from the the item repair priorities definition in {element} of {file.Path}.",
56  }
57  }
58 
59  public override void Dispose() { }
60  }
61 
62  internal class JobVariant
63  {
64  public JobPrefab Prefab;
65  public int Variant;
66  public JobVariant(JobPrefab prefab, int variant)
67  {
68  Prefab = prefab;
69  Variant = variant;
70  }
71  }
72 
74  {
76 
77  public override void Dispose() { }
78 
79  private static readonly Dictionary<Identifier, float> _itemRepairPriorities = new Dictionary<Identifier, float>();
83  public static IReadOnlyDictionary<Identifier, float> ItemRepairPriorities => _itemRepairPriorities;
84 
85  public static JobPrefab Get(Identifier identifier)
86  {
87  if (Prefabs.ContainsKey(identifier))
88  {
89  return Prefabs[identifier];
90  }
91  else
92  {
93  DebugConsole.ThrowError("Couldn't find a job prefab with the given identifier: " + identifier);
94  return null;
95  }
96  }
97 
98  public class JobItem
99  {
100  public enum GameModeType
101  {
102  Any, PvP, PvE
103  }
104 
105  public readonly Identifier ItemIdentifier;
107  public readonly bool ShowPreview;
108  public readonly bool Equip;
109  public readonly bool Outfit;
110  public readonly int Amount = 1;
111 
112  public readonly JobItem ParentItem;
113 
114  public readonly GameModeType GameMode;
115 
116  public JobItem(ContentXElement element, JobItem parentItem)
117  {
118  ItemIdentifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
119  ItemIdentifierTeam2 = element.GetAttributeIdentifier("identifierteam2", Identifier.Empty);
120  ShowPreview = element.GetAttributeBool("showpreview", true);
121  GameMode = element.GetAttributeEnum("gamemode", parentItem?.GameMode ?? GameModeType.Any);
122  Amount = element.GetAttributeInt("amount", 1);
123  Equip = element.GetAttributeBool("equip", false);
124  Outfit = element.GetAttributeBool("outfit", false);
125  ParentItem = parentItem;
126  }
127 
128  public Identifier GetItemIdentifier(CharacterTeamType team, bool isPvPMode)
129  {
130  switch (GameMode)
131  {
132  case GameModeType.PvP:
133  if (!isPvPMode) { return Identifier.Empty; }
134  break;
135  case GameModeType.PvE:
136  if (isPvPMode) { return Identifier.Empty; }
137  break;
138  }
139 
140  return
141  team == CharacterTeamType.Team2 && !ItemIdentifierTeam2.IsEmpty ?
144  }
145  }
146 
150  public readonly ImmutableDictionary<int, ImmutableArray<JobItem>> JobItems;
151  public readonly List<SkillPrefab> Skills = new List<SkillPrefab>();
152  public readonly List<AutonomousObjective> AutonomousObjectives = new List<AutonomousObjective>();
153  public readonly List<Identifier> AppropriateOrders = new List<Identifier>();
154 
155  [Serialize("1,1,1,1", IsPropertySaveable.No)]
156  public Color UIColor
157  {
158  get;
159  private set;
160  }
161 
162  public readonly LocalizedString Name;
163 
164  [Serialize(AIObjectiveIdle.BehaviorType.Passive, IsPropertySaveable.No, description: "How should the character behave when idling (not doing any particular task)?")]
166  {
167  get;
168  private set;
169  }
170 
171  public readonly LocalizedString Description;
172 
173  [Serialize(false, IsPropertySaveable.No, description: "Can the character speak any random lines, or just ones specifically meant for the job?")]
175  {
176  get;
177  private set;
178  }
179 
180  [Serialize(0, IsPropertySaveable.No, description: "The number of these characters in the crew the player starts with in the single player campaign.")]
181  public int InitialCount
182  {
183  get;
184  private set;
185  }
186 
187  [Serialize(false, IsPropertySaveable.No, description: "If set to true, a client that has chosen this as their preferred job will get it regardless of the maximum number or the amount of spawnpoints in the sub.")]
188  public bool AllowAlways
189  {
190  get;
191  private set;
192  }
193 
194  [Serialize(100, IsPropertySaveable.No, description: "How many crew members can have the job (e.g. only one captain etc).")]
195  public int MaxNumber
196  {
197  get;
198  private set;
199  }
200 
201  [Serialize(0, IsPropertySaveable.No, description: "How many crew members are required to have the job. I.e. if one captain is required, one captain is chosen even if all the players have set captain to lowest preference.")]
202  public int MinNumber
203  {
204  get;
205  private set;
206  }
207 
208  [Serialize(0.0f, IsPropertySaveable.No, description: "Minimum amount of karma a player must have to get assigned this job.")]
209  public float MinKarma
210  {
211  get;
212  private set;
213  }
214 
215  [Serialize(1.0f, IsPropertySaveable.No, description: "Multiplier on the base hiring cost when hiring the character from an outpost.")]
216  public float PriceMultiplier
217  {
218  get;
219  private set;
220  }
221 
222  [Serialize(0.0f, IsPropertySaveable.No, description: "How much the vitality of the character is increased/reduced from the default value (e.g. 10 = 110 total vitality if the default vitality is 100.).")]
223  public float VitalityModifier
224  {
225  get;
226  private set;
227  }
228 
229  [Serialize(false, IsPropertySaveable.No, description: "Hidden jobs are not selectable by players, but can be used by e.g. outpost NPCs.")]
230  public bool HiddenJob
231  {
232  get;
233  private set;
234  }
235 
236  public Sprite Icon;
238 
239  public SkillPrefab PrimarySkill => Skills?.FirstOrDefault(s => s.IsPrimarySkill);
240 
241  public ContentXElement Element { get; private set; }
242 
243  public int Variants { get; private set; }
244 
245  public JobPrefab(ContentXElement element, JobsFile file) : base(file, element.GetAttributeIdentifier("identifier", ""))
246  {
248 
249  Name = TextManager.Get("JobName." + Identifier);
250  Description = TextManager.Get("JobDescription." + Identifier);
251  Element = element;
252 
253  var jobItems = new Dictionary<int, List<JobItem>>();
254 
255  int variant = 0;
256  foreach (var subElement in element.Elements())
257  {
258  switch (subElement.Name.ToString().ToLowerInvariant())
259  {
260  case "itemset":
261  jobItems[variant] = new List<JobItem>();
262  loadJobItems(subElement, variant, parentItem: null);
263  variant++;
264  break;
265  case "skills":
266  foreach (var skillElement in subElement.Elements())
267  {
268  Skills.Add(new SkillPrefab(skillElement));
269  }
270  break;
271  case "autonomousobjectives":
272  subElement.Elements().ForEach(order => AutonomousObjectives.Add(new AutonomousObjective(order)));
273  break;
274  case "appropriateobjectives":
275  case "appropriateorders":
276  subElement.Elements().ForEach(order => AppropriateOrders.Add(order.GetAttributeIdentifier("identifier", "")));
277  break;
278  case "jobicon":
279  Icon = new Sprite(subElement.FirstElement());
280  break;
281  case "jobiconsmall":
282  IconSmall = new Sprite(subElement.FirstElement());
283  break;
284  }
285  }
286 
287  void loadJobItems(ContentXElement parentElement, int variant, JobItem parentItem)
288  {
289  foreach (ContentXElement itemElement in parentElement.GetChildElements("Item"))
290  {
291  if (itemElement.GetAttribute("name") != null)
292  {
293  DebugConsole.ThrowErrorLocalized("Error in job config \"" + Name + "\" - use identifiers instead of names to configure the items.",
294  contentPackage: parentElement.ContentPackage);
295  continue;
296  }
297 
298  Identifier itemIdentifier = itemElement.GetAttributeIdentifier("identifier", Identifier.Empty);
299  JobItem jobItem = null;
300  if (itemIdentifier.IsEmpty)
301  {
302  DebugConsole.ThrowErrorLocalized("Error in job config \"" + Name + "\" - item with no identifier.",
303  contentPackage: parentElement.ContentPackage);
304  }
305  else
306  {
307  jobItem = new JobItem(itemElement, parentItem);
308  jobItems[variant].Add(jobItem);
309  }
310  loadJobItems(itemElement, variant, parentItem: jobItem);
311  }
312  }
313 
314  JobItems = jobItems.Select(kvp => (kvp.Key, kvp.Value.ToImmutableArray()))
315  .ToImmutableDictionary();
316 
317  Variants = variant;
318 
319  Skills.Sort((x,y) => y.GetLevelRange(isPvP: false).Start.CompareTo(x.GetLevelRange(isPvP: false).Start));
320  }
321 
322  public static JobPrefab Random(Rand.RandSync sync, Func<JobPrefab, bool> predicate = null) => Prefabs.GetRandom(p => !p.HiddenJob && (predicate == null || predicate(p)), sync);
323  }
324 }
readonly bool IgnoreAtNonOutpost
The order is ignored in "normal" non-outpost levels
Definition: JobPrefab.cs:23
AutonomousObjective(XElement element)
Definition: JobPrefab.cs:25
readonly float PriorityModifier
Definition: JobPrefab.cs:15
readonly bool IgnoreAtOutpost
The order is ignored in outpost levels. Doesn't apply to outpost NPCs.
Definition: JobPrefab.cs:19
readonly Identifier Identifier
Definition: JobPrefab.cs:13
readonly Identifier Option
Definition: JobPrefab.cs:14
ContentPackage? ContentPackage
IEnumerable< ContentXElement > GetChildElements(string name)
bool GetAttributeBool(string key, bool def)
int GetAttributeInt(string key, int def)
XAttribute? GetAttribute(string name)
Identifier GetAttributeIdentifier(string key, string def)
static readonly PrefabCollection< ItemRepairPriority > Prefabs
Definition: JobPrefab.cs:45
override void Dispose()
Definition: JobPrefab.cs:59
ItemRepairPriority(XElement element, JobsFile file)
Definition: JobPrefab.cs:49
readonly JobItem ParentItem
Definition: JobPrefab.cs:112
Identifier GetItemIdentifier(CharacterTeamType team, bool isPvPMode)
Definition: JobPrefab.cs:128
readonly GameModeType GameMode
Definition: JobPrefab.cs:114
readonly Identifier ItemIdentifierTeam2
Definition: JobPrefab.cs:106
JobItem(ContentXElement element, JobItem parentItem)
Definition: JobPrefab.cs:116
readonly Identifier ItemIdentifier
Definition: JobPrefab.cs:105
AIObjectiveIdle.BehaviorType IdleBehavior
Definition: JobPrefab.cs:166
JobPrefab(ContentXElement element, JobsFile file)
Definition: JobPrefab.cs:245
readonly LocalizedString Name
Definition: JobPrefab.cs:162
ContentXElement Element
Definition: JobPrefab.cs:241
SkillPrefab PrimarySkill
Definition: JobPrefab.cs:239
readonly List< AutonomousObjective > AutonomousObjectives
Definition: JobPrefab.cs:152
static IReadOnlyDictionary< Identifier, float > ItemRepairPriorities
Tag -> priority.
Definition: JobPrefab.cs:83
readonly ImmutableDictionary< int, ImmutableArray< JobItem > > JobItems
The items the character can get when spawning. The key is the index of the job variant.
Definition: JobPrefab.cs:150
readonly LocalizedString Description
Definition: JobPrefab.cs:171
override void Dispose()
Definition: JobPrefab.cs:77
static JobPrefab Random(Rand.RandSync sync, Func< JobPrefab, bool > predicate=null)
static readonly PrefabCollection< JobPrefab > Prefabs
Definition: JobPrefab.cs:75
static JobPrefab Get(Identifier identifier)
Definition: JobPrefab.cs:85
readonly List< Identifier > AppropriateOrders
Definition: JobPrefab.cs:153
readonly List< SkillPrefab > Skills
Definition: JobPrefab.cs:151
readonly Identifier Identifier
Definition: Prefab.cs:34
Prefab that has a property serves as a deterministic hash of a prefab's identifier....
static Dictionary< Identifier, SerializableProperty > DeserializeProperties(object obj, XElement element=null)