Client LuaCsForBarotrauma
NPCChangeTeamAction.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 
5 namespace Barotrauma
6 {
11  {
12  [Serialize("", IsPropertySaveable.Yes, description: "Tag of the NPC(s) whose team to change.")]
13  public Identifier NPCTag { get; set; }
14 
15  [Serialize(CharacterTeamType.None, IsPropertySaveable.Yes, description: "The team to move the NPC to. None = unspecified, Team1 = player crew, Team2 = the team opposing Team1 (= hostile to player crew), FriendlyNPC = friendly to all other teams.")]
16  public CharacterTeamType TeamID { get; set; }
17 
18  [Serialize(false, IsPropertySaveable.Yes, description: "Should the NPC be added to the player crew?")]
19  public bool AddToCrew { get; set; }
20 
21  [Serialize(false, IsPropertySaveable.Yes, description: "Should the NPC be removed from the player crew?")]
22  public bool RemoveFromCrew { get; set; }
23 
24  private bool isFinished = false;
25 
26  public NPCChangeTeamAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
27  {
28  //backwards compatibility
29  TeamID = element.GetAttributeEnum("teamtag", element.GetAttributeEnum<CharacterTeamType>("team", TeamID));
30 
31  var enums = Enum.GetValues(typeof(CharacterTeamType)).Cast<CharacterTeamType>();
32  if (!enums.Contains(TeamID))
33  {
34  DebugConsole.ThrowError($"Error in {nameof(NPCChangeTeamAction)} in the event {ParentEvent.Prefab.Identifier}. \"{TeamID}\" is not a valid Team ID. Valid values are {string.Join(',', Enum.GetNames(typeof(CharacterTeamType)))}.",
35  contentPackage: element.ContentPackage);
36  }
37  }
38 
39  private List<Character> affectedNpcs = null;
40 
41  public override void Update(float deltaTime)
42  {
43  if (isFinished) { return; }
44 
45  bool isPlayerTeam = TeamID is CharacterTeamType.Team1 or CharacterTeamType.Team2;
46 
47  affectedNpcs = ParentEvent.GetTargets(NPCTag).OfType<Character>().ToList();
48  foreach (Character npc in affectedNpcs)
49  {
50  // characters will still remain on friendlyNPC team for rest of the tick
52  foreach (Item item in npc.Inventory.AllItems)
53  {
54  var idCard = item.GetComponent<Items.Components.IdCard>();
55  if (idCard != null)
56  {
57  idCard.TeamID = TeamID;
58  if (isPlayerTeam)
59  {
60  idCard.SubmarineSpecificID = 0;
61  }
62  }
63  }
64  if (GameMain.GameSession.CrewManager is CrewManager crewManager)
65  {
66  if (AddToCrew && isPlayerTeam)
67  {
68  if (npc.Info is CharacterInfo info)
69  {
70  info.StartItemsGiven = true;
71  crewManager.AddCharacter(npc);
72  }
73  else
74  {
75  DebugConsole.AddWarning($"Attempted to change the team of a character ({npc.Name}) that doesn't have Character Info. Can't add to the crew.");
76  }
77  ChangeItemTeam(Submarine.MainSub ?? Submarine.Loaded.FirstOrDefault(s => s.TeamID == TeamID), allowStealing: true);
78  if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
79  {
81  }
82  }
83  else if (RemoveFromCrew && npc.TeamID is CharacterTeamType.Team1 or CharacterTeamType.Team2)
84  {
85  if (npc.Info is CharacterInfo info)
86  {
87  info.StartItemsGiven = true;
88  crewManager.RemoveCharacter(npc, removeInfo: true);
89  }
90  else
91  {
92  DebugConsole.AddWarning($"Attempted to change the team of a character ({npc.Name}) that doesn't have Character Info. Can't remove from the crew.");
93  }
94  Submarine sub = Submarine.Loaded.FirstOrDefault(s => s.TeamID == TeamID);
95  ChangeItemTeam(sub, false);
96  if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
97  {
99  }
100  }
101  }
102 
103  void ChangeItemTeam(Submarine sub, bool allowStealing)
104  {
105  foreach (Item item in npc.Inventory.FindAllItems(recursive: true))
106  {
107  item.AllowStealing = allowStealing;
108  if (item.GetComponent<Items.Components.WifiComponent>() is { } wifiComponent)
109  {
110  wifiComponent.TeamID = TeamID;
111  }
112  if (item.GetComponent<Items.Components.IdCard>() is { } idCard)
113  {
114  idCard.SubmarineSpecificID = 0;
115  }
116  }
117  WayPoint subWaypoint =
118  WayPoint.WayPointList.Find(wp => wp.Submarine == sub && wp.SpawnType == SpawnType.Human && wp.AssignedJob == npc.Info?.Job?.Prefab) ??
119  WayPoint.WayPointList.Find(wp => wp.Submarine == sub && wp.SpawnType == SpawnType.Human);
120  if (subWaypoint != null)
121  {
122  npc.GiveIdCardTags(subWaypoint, createNetworkEvent: true);
123  }
124  }
125  }
126  isFinished = true;
127  }
128 
129  public override bool IsFinished(ref string goTo)
130  {
131  return isFinished;
132  }
133 
134  public override void Reset()
135  {
136  isFinished = false;
137  }
138 
139  public override string ToDebugString()
140  {
141  return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(NPCChangeTeamAction)} -> (NPCTag: {NPCTag.ColorizeObject()})";
142  }
143  }
144 }
void GiveIdCardTags(WayPoint spawnPoint, bool createNetworkEvent=false)
void SetOriginalTeamAndChangeTeam(CharacterTeamType newTeam, bool processImmediately=false)
Saves the character's original team (which affects e.g. whether the character considers the sub/outpo...
Stores information about the Character that is needed between rounds in the menu etc....
ContentPackage? ContentPackage
Responsible for keeping track of the characters in the player crew, saving and loading their orders,...
readonly ScriptedEvent ParentEvent
Definition: EventAction.cs:106
static GameSession?? GameSession
Definition: GameMain.cs:88
static NetworkMember NetworkMember
Definition: GameMain.cs:190
virtual IEnumerable< Item > AllItems
All items contained in the inventory. Stacked items are returned as individual instances....
List< Item > FindAllItems(Func< Item, bool > predicate=null, bool recursive=false, List< Item > list=null)
JobPrefab Prefab
Definition: Job.cs:18
Changes the team of an NPC. Most common use cases are adding a character to the crew,...
override void Update(float deltaTime)
override string ToDebugString()
Rich test to display in debugdraw
NPCChangeTeamAction(ScriptedEvent parentEvent, ContentXElement element)
override bool IsFinished(ref string goTo)
Has the action finished.
IEnumerable< Entity > GetTargets(Identifier tag)
static Submarine MainSub
Note that this can be null in some situations, e.g. editors and missions that don't load a submarine.