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 == CharacterTeamType.Team1 || TeamID == CharacterTeamType.Team2;
46 
47  affectedNpcs = ParentEvent.GetTargets(NPCTag).Where(c => c is Character).Select(c => c as Character).ToList();
48  foreach (var npc in affectedNpcs)
49  {
50  // characters will still remain on friendlyNPC team for rest of the tick
51  npc.SetOriginalTeam(TeamID);
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 (AddToCrew && isPlayerTeam)
65  {
66  npc.Info.StartItemsGiven = true;
68  ChangeItemTeam(Submarine.MainSub, true);
69  if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
70  {
71  GameMain.NetworkMember.CreateEntityEvent(npc, new Character.AddToCrewEventData(TeamID, npc.Inventory.AllItems));
72  }
73  }
74  else if (RemoveFromCrew && (npc.TeamID == CharacterTeamType.Team1 || npc.TeamID == CharacterTeamType.Team2))
75  {
76  npc.Info.StartItemsGiven = true;
77  GameMain.GameSession.CrewManager.RemoveCharacter(npc, removeInfo: true);
78  var sub = Submarine.Loaded.FirstOrDefault(s => s.TeamID == TeamID);
79  ChangeItemTeam(sub, false);
80  if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
81  {
82  GameMain.NetworkMember.CreateEntityEvent(npc, new Character.RemoveFromCrewEventData(TeamID, npc.Inventory.AllItems));
83  }
84  }
85 
86  void ChangeItemTeam(Submarine sub, bool allowStealing)
87  {
88  foreach (Item item in npc.Inventory.FindAllItems(recursive: true))
89  {
90  item.AllowStealing = allowStealing;
91  if (item.GetComponent<Items.Components.WifiComponent>() is { } wifiComponent)
92  {
93  wifiComponent.TeamID = TeamID;
94  }
95  if (item.GetComponent<Items.Components.IdCard>() is { } idCard)
96  {
97  idCard.SubmarineSpecificID = 0;
98  }
99  }
100  WayPoint subWaypoint =
101  WayPoint.WayPointList.Find(wp => wp.Submarine == sub && wp.SpawnType == SpawnType.Human && wp.AssignedJob == npc.Info.Job?.Prefab) ??
102  WayPoint.WayPointList.Find(wp => wp.Submarine == sub && wp.SpawnType == SpawnType.Human);
103  if (subWaypoint != null)
104  {
105  npc.GiveIdCardTags(subWaypoint, createNetworkEvent: true);
106  }
107  }
108  }
109  isFinished = true;
110  }
111 
112  public override bool IsFinished(ref string goTo)
113  {
114  return isFinished;
115  }
116 
117  public override void Reset()
118  {
119  isFinished = false;
120  }
121 
122  public override string ToDebugString()
123  {
124  return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(NPCChangeTeamAction)} -> (NPCTag: {NPCTag.ColorizeObject()})";
125  }
126  }
127 }
ContentPackage? ContentPackage
void RemoveCharacter(Character character, bool removeInfo=false, bool resetCrewListIndex=true)
Remove the character from the crew (and crew menus).
void AddCharacter(Character character, bool sortCrewList=true)
readonly ScriptedEvent ParentEvent
Definition: EventAction.cs:102
static GameSession?? GameSession
Definition: GameMain.cs:88
static NetworkMember NetworkMember
Definition: GameMain.cs:190
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)