/// <summary> /// Incept placing of the meta pieces. /// Cancels the real placement of the placeholder pieces. /// </summary> private bool BeforePlaceBlueprintPiece(On.Player.orig_PlacePiece orig, Player self, Piece piece) { // Client only if (!ZNet.instance.IsDedicated()) { // Capture a new blueprint if (piece.name == "make_blueprint") { return(MakeBlueprint(self)); } // Place a known blueprint if (Player.m_localPlayer.m_placementStatus == Player.PlacementStatus.Valid && piece.name != BlueprintRunePrefab.BlueprintSnapPointName && piece.name != BlueprintRunePrefab.BlueprintCenterPointName && piece.name.StartsWith("piece_blueprint")) { return(PlaceBlueprint(self, piece)); } else if (piece.name.StartsWith(BlueprintRunePrefab.DeletePlansName)) { return(DeletePlans(self)); } else if (piece.name.StartsWith(BlueprintRunePrefab.UndoBlueprintName)) { return(UndoBlueprint()); } } return(orig(self, piece)); }
/// <summary> /// CLIENT SIDE: React to a placement of a portal /// </summary> private static bool AfterPlacingPortal(On.Player.orig_PlacePiece orig, Player self, Piece piece) { bool successful = orig(self, piece); if (ZNet.instance.IsServerInstance()) { return(successful); } if (successful && !piece.IsCreator() && piece.m_name == "$piece_portal") { Logger.LogInfo("Portal created"); if (ZNet.instance.IsLocalInstance()) { Logger.LogInfo("Sending portal sync request to server"); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); } if (ZNet.instance.IsClientInstance()) { Logger.LogInfo("Sending deferred portal sync request to server"); Task.Factory.StartNew(() => { // Wait for ZDO to be sent else server won't have accurate information to send back Thread.Sleep(5000); // Send trigger to server ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); }); } } return(successful); }
/// <summary> /// Incept placing of the meta pieces. /// Cancels the real placement of the placeholder pieces. /// </summary> private bool BeforePlaceBlueprintPiece(On.Player.orig_PlacePiece orig, Player self, Piece piece) { // Client only if (!ZNet.instance.IsServerInstance()) { // Capture a new blueprint if (piece.name == "make_blueprint") { var circleProjector = self.m_placementGhost.GetComponent <CircleProjector>(); if (circleProjector != null) { Destroy(circleProjector); } var bpname = $"blueprint{Instance.m_blueprints.Count() + 1:000}"; Jotunn.Logger.LogInfo($"Capturing blueprint {bpname}"); if (Player.m_localPlayer.m_hoveringPiece != null) { var bp = new Blueprint(bpname); if (bp.Capture(Player.m_localPlayer.m_hoveringPiece.transform.position, Instance.selectionRadius, 1.0f)) { TextInput.instance.m_queuedSign = new Blueprint.BlueprintSaveGUI(bp); TextInput.instance.Show($"Save Blueprint ({bp.GetPieceCount()} pieces captured)", bpname, 50); } else { Jotunn.Logger.LogWarning($"Could not capture blueprint {bpname}"); } } else { Jotunn.Logger.LogInfo("Not hovering any piece"); } // Reset Camera offset Instance.cameraOffsetMake = 0f; // Don't place the piece and clutter the world with it return(false); } // Place a known blueprint if (Player.m_localPlayer.m_placementStatus == Player.PlacementStatus.Valid && piece.name.StartsWith("piece_blueprint")) { Blueprint bp = Instance.m_blueprints[piece.m_name]; var transform = self.m_placementGhost.transform; var position = self.m_placementGhost.transform.position; var rotation = self.m_placementGhost.transform.rotation; if (ZInput.GetButton("Crouch") && !ConfigUtil.Get <bool>("Blueprints", "allowPlacementWithoutMaterial")) { MessageHud.instance.ShowMessage(MessageHud.MessageType.Center, "$plan_direct_build_disable"); return(false); } if (ZInput.GetButton("AltPlace")) { Vector2 extent = bp.GetExtent(); FlattenTerrain.FlattenForBlueprint(transform, extent.x, extent.y, bp.m_pieceEntries); } uint cntEffects = 0u; uint maxEffects = 10u; foreach (var entry in bp.m_pieceEntries) { // Final position Vector3 entryPosition = position + transform.forward * entry.posZ + transform.right * entry.posX + new Vector3(0, entry.posY, 0); // Final rotation Quaternion entryQuat = new Quaternion(entry.rotX, entry.rotY, entry.rotZ, entry.rotW); entryQuat.eulerAngles += rotation.eulerAngles; // Get the prefab of the piece or the plan piece string prefabName = entry.name; if (!ConfigUtil.Get <bool>("Blueprints", "allowPlacementWithoutMaterial") || !ZInput.GetButton("Crouch")) { prefabName += "_planned"; } GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName); if (!prefab) { Jotunn.Logger.LogError(entry.name + " not found?"); continue; } // Instantiate a new object with the new prefab GameObject gameObject = Instantiate(prefab, entryPosition, entryQuat); // Register special effects CraftingStation craftingStation = gameObject.GetComponentInChildren <CraftingStation>(); if (craftingStation) { self.AddKnownStation(craftingStation); } Piece newpiece = gameObject.GetComponent <Piece>(); if (newpiece != null) { newpiece.SetCreator(self.GetPlayerID()); } PrivateArea privateArea = gameObject.GetComponent <PrivateArea>(); if (privateArea != null) { privateArea.Setup(Game.instance.GetPlayerProfile().GetName()); } WearNTear wearntear = gameObject.GetComponent <WearNTear>(); if (wearntear != null) { wearntear.OnPlaced(); } TextReceiver textReceiver = gameObject.GetComponent <TextReceiver>(); if (textReceiver != null) { textReceiver.SetText(entry.additionalInfo); } // Limited build effects if (cntEffects < maxEffects) { newpiece.m_placeEffect.Create(gameObject.transform.position, rotation, gameObject.transform, 1f); self.AddNoise(50f); cntEffects++; } // Count up player builds Game.instance.GetPlayerProfile().m_playerStats.m_builds++; } // Reset Camera offset Instance.cameraOffsetPlace = 5f; // Dont set the blueprint piece and clutter the world with it return(false); } } return(orig(self, piece)); }