-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathPlayerInitialSyncProcessor.cs
More file actions
150 lines (129 loc) · 5.71 KB
/
PlayerInitialSyncProcessor.cs
File metadata and controls
150 lines (129 loc) · 5.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System.Collections;
using NitroxClient.GameLogic.InitialSync.Abstract;
using NitroxClient.MonoBehaviours;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.Server;
using UnityEngine;
namespace NitroxClient.GameLogic.InitialSync;
/// <summary>
/// Makes sure the player is configured.
/// </summary>
/// <remarks>
/// This allows the player to:<br/>
/// - use equipment
/// </remarks>
public sealed class PlayerInitialSyncProcessor : InitialSyncProcessor
{
private readonly Items item;
private readonly ItemContainers itemContainers;
private readonly LocalPlayer localPlayer;
public PlayerInitialSyncProcessor(Items item, ItemContainers itemContainers, LocalPlayer localPlayer)
{
this.item = item;
this.itemContainers = itemContainers;
this.localPlayer = localPlayer;
AddStep(sync => SetupEscapePod(sync.FirstTimeConnecting));
AddStep(sync => SetPlayerPermissions(sync.Permissions));
AddStep(sync => SetPlayerIntroCinematicMode(sync.IntroCinematicMode));
AddStep(sync => SetPlayerGameObjectId(sync.PlayerGameObjectId));
AddStep(sync => AddStartingItemsToPlayer(sync.FirstTimeConnecting));
AddStep(sync => SetPlayerStats(sync.PlayerStatsData));
AddStep(sync => SetPlayerGameMode(sync.GameMode));
AddStep(sync => SetPlayerKeepInventoryOnDeath(sync.KeepInventoryOnDeath));
AddStep(sync => SetPlayerMarkDeathPointsWithBeacon(sync.MarkDeathPointsWithBeacon));
}
private void SetPlayerPermissions(Perms permissions)
{
localPlayer.Permissions = permissions;
}
private void SetPlayerIntroCinematicMode(IntroCinematicMode introCinematicMode)
{
if (localPlayer.IntroCinematicMode < introCinematicMode)
{
localPlayer.IntroCinematicMode = introCinematicMode;
Log.Info($"Received initial sync player IntroCinematicMode: {introCinematicMode}");
}
}
private static void SetPlayerGameObjectId(NitroxId id)
{
EcoTarget playerEcoTarget = Player.mainObject.AddComponent<EcoTarget>();
playerEcoTarget.SetTargetType(RemotePlayer.PLAYER_ECO_TARGET_TYPE);
NitroxEntity.SetNewId(Player.mainObject, id);
Log.Info($"Received initial sync player GameObject Id: {id}");
}
private void SetupEscapePod(bool firstTimeConnecting)
{
EscapePod escapePod = EscapePod.main;
if (escapePod)
{
Log.Info($"Setting up escape pod, FirstTimeConnecting: {firstTimeConnecting}");
escapePod.bottomHatchUsed = !firstTimeConnecting;
escapePod.topHatchUsed = !firstTimeConnecting;
// Call code we suppressed inside EscapePodFirstUseCinematicsController_OnSceneObjectsLoaded_Patch
EscapePodFirstUseCinematicsController cinematicController = escapePod.GetComponentInChildren<EscapePodFirstUseCinematicsController>(true);
if (cinematicController)
{
cinematicController.Initialize();
}
}
}
private IEnumerator AddStartingItemsToPlayer(bool firstTimeConnecting)
{
if (firstTimeConnecting)
{
if (!Player.main.TryGetIdOrWarn(out NitroxId localPlayerId))
{
yield break;
}
foreach (TechType techType in LootSpawner.main.GetEscapePodStorageTechTypes())
{
TaskResult<GameObject> result = new();
yield return CraftData.InstantiateFromPrefabAsync(techType, result);
GameObject gameObject = result.Get();
Pickupable pickupable = gameObject.GetComponent<Pickupable>();
pickupable.Initialize();
item.Created(gameObject);
itemContainers.AddItem(gameObject, localPlayerId);
}
}
}
private static void SetPlayerStats(PlayerStatsData statsData)
{
if (statsData != null)
{
Player.main.oxygenMgr.AddOxygen(statsData.Oxygen);
// Spawning a player with 0 health makes them invincible so we'd rather set it to 1 HP
Player.main.liveMixin.health = Mathf.Max(1f, statsData.Health);
Survival survivalComponent = Player.main.GetComponent<Survival>();
survivalComponent.food = statsData.Food;
survivalComponent.water = statsData.Water;
Player.main.infectedMixin.SetInfectedAmount(statsData.InfectionAmount);
//If InfectionAmount is at least 1f then the infection reveal should have happened already.
//If InfectionAmount is below 1f then the reveal has not.
if (statsData.InfectionAmount >= 1f)
{
Player.main.infectionRevealed = true;
}
// We need to make the player invincible before he finishes loading because in some cases he will eventually die before loading
Player.main.liveMixin.invincible = true;
Player.main.FreezeStats();
}
// We need to start it at least once for everything that's in the PDA to load
Player.main.GetPDA().Open(PDATab.Inventory);
Player.main.GetPDA().Close();
}
private static void SetPlayerGameMode(NitroxGameMode gameMode)
{
Log.Info($"Received initial sync packet with gamemode {gameMode}");
GameModeUtils.SetGameMode((GameModeOption)(int)gameMode, GameModeOption.None);
}
private void SetPlayerKeepInventoryOnDeath(bool keepInventoryOnDeath)
{
localPlayer.KeepInventoryOnDeath = keepInventoryOnDeath;
}
private void SetPlayerMarkDeathPointsWithBeacon(bool markDeathPointsWithBeacon)
{
localPlayer.MarkDeathPointsWithBeacon = markDeathPointsWithBeacon;
}
}