private void RefreshDepletion() { this.ValueCurrent = this.publicState?.StructurePointsCurrent ?? 0; if (this.ValueCurrent <= 0) { if (PveSystem.ClientIsPve(logErrorIfDataIsNotYetAvailable: true)) { // PvE mode doesn't require the deposit under the extractor this.DepletionDurationText = TitleDepositInfinite; this.ValueCurrent = this.ValueMax = 1; } else { this.DepletionDurationText = TitleDepositDepleted; } this.DepletedInPrefixVisibility = Visibility.Collapsed; return; } var lifetimeTotalDurationSeconds = this.protoDeposit.LifetimeTotalDurationSeconds; if (lifetimeTotalDurationSeconds == 0) { this.DepletionDurationText = TitleDepositInfinite; this.DepletedInPrefixVisibility = Visibility.Collapsed; return; } this.DepletedInPrefixVisibility = Visibility.Visible; var structurePointsFraction = this.ValueCurrent / this.ValueMax; var remainsNoExtraction = structurePointsFraction * lifetimeTotalDurationSeconds; var remainsWithExtraction = remainsNoExtraction / this.protoDeposit.DecaySpeedMultiplierWhenExtractingActive; if (remainsNoExtraction == remainsWithExtraction) { // display a single duration this.DepletionDurationText = FormatDuration(remainsNoExtraction); } else { // display an interval this.DepletionDurationText = FormatInterval(remainsWithExtraction, remainsNoExtraction); } }
public static async void ClientPutCurrentVehicle() { if (!PveSystem.ClientIsPve(logErrorIfDataIsNotYetAvailable: true)) { // this feature is available only in PvE return; } var vehicleAssemblyBay = InteractionCheckerSystem.SharedGetCurrentInteraction( ClientCurrentCharacterHelper.Character); var isSuccess = await Instance.CallServer(_ => _.ServerRemote_PutCurrentVehicle()); if (isSuccess) { Client.Audio.PlayOneShot(SoundResourcePutVehicle, vehicleAssemblyBay); } }
public static void SetupSkeletonEquipmentForCharacter( ICharacter character, IItemsContainer containerEquipment, IComponentSkeleton skeletonRenderer, ProtoCharacterSkeleton skeleton, List <IClientComponent> skeletonComponents, bool isPreview = false) { if (!(skeleton is SkeletonHumanMale) && !(skeleton is SkeletonHumanFemale)) { // not a human // setup only implants using var equipmentImplants = Api.Shared.WrapInTempList( containerEquipment.GetItemsOfProto <IProtoItemEquipmentImplant>()); foreach (var item in equipmentImplants.AsList()) { var proto = (IProtoItemEquipmentImplant)item.ProtoGameObject; proto.ClientSetupSkeleton(item, character, skeletonRenderer, skeletonComponents, isPreview); } return; } bool isMale, isHeadEquipmentHiddenForSelfAndPartyMembers; CharacterHumanFaceStyle faceStyle; if (character.ProtoCharacter is PlayerCharacter) { var publicState = PlayerCharacter.GetPublicState(character); faceStyle = publicState.FaceStyle; isMale = publicState.IsMale; isHeadEquipmentHiddenForSelfAndPartyMembers = publicState.IsHeadEquipmentHiddenForSelfAndPartyMembers; if (isMale && !(skeleton is SkeletonHumanMale) || !isMale && !(skeleton is SkeletonHumanFemale)) { throw new Exception( $"Skeleton don\'t match the gender of the player\'s character: isMale={isMale}, {skeleton}"); } } else { // for NPC it will generate a random face isMale = true; faceStyle = SharedCharacterFaceStylesProvider.GetForGender(isMale).GenerateRandomFace(); isHeadEquipmentHiddenForSelfAndPartyMembers = false; } skeletonRenderer.ResetAttachments(); skeleton.ClientResetItemInHand(skeletonRenderer); var skinToneId = faceStyle.SkinToneId; if (string.IsNullOrEmpty(skinToneId)) { skeletonRenderer.DefaultTextureRemapper = null; } else { // use colorizer for the original sprites (to apply the skin tone) skeletonRenderer.DefaultTextureRemapper = textureResource => { var filePath = textureResource.LocalPath; if (filePath.IndexOf("/Weapon", StringComparison.Ordinal) >= 0 || filePath.IndexOf("/Head", StringComparison.Ordinal) >= 0) { // no need to remap the original head and weapon sprites // (they're never used as is) return(textureResource); } return(ClientCharacterSkinTexturesCache.Get(textureResource, skinToneId)); }; } // setup equipment items using var equipmentItems = Api.Shared.WrapInTempList( containerEquipment.GetItemsOfProto <IProtoItemEquipment>()); if (!IsAllowNakedHumans) { if (!equipmentItems.AsList().Any(i => i.ProtoGameObject is IProtoItemEquipmentArmor)) { // no armor equipped - apply generic one var pants = GenericPantsAttachments.Value; ClientSkeletonAttachmentsLoader.SetAttachments( skeletonRenderer, isMale ? pants.SlotAttachmentsMale : pants.SlotAttachmentsFemale); // select a random generic T-shirt based on character ID var allShirts = GenericShirtAttachments.Value; var selectedShirtIndex = character.Id % allShirts.Length; var shirt = allShirts[(int)selectedShirtIndex]; ClientSkeletonAttachmentsLoader.SetAttachments( skeletonRenderer, isMale ? shirt.SlotAttachmentsMale : shirt.SlotAttachmentsFemale); } } IItem headEquipmentForFaceSprite = null; foreach (var item in equipmentItems.AsList()) { var proto = (IProtoItemEquipment)item.ProtoGameObject; proto.ClientSetupSkeleton(item, character, skeletonRenderer, skeletonComponents, isPreview); if (item.ProtoItem is IProtoItemEquipmentHead && headEquipmentForFaceSprite is null) { headEquipmentForFaceSprite = item; } } if (isHeadEquipmentHiddenForSelfAndPartyMembers && (character.IsCurrentClientCharacter || PartySystem.ClientIsPartyMember(character.Name) || PveSystem.ClientIsPve(false))) { headEquipmentForFaceSprite = null; } // generate head sprites for human players const string slotName = "Head", attachmentName = "Head"; headGenerationId++; var spriteQualityOffset = skeletonRenderer.SpriteQualityOffset; skeletonRenderer.SetAttachmentSprite( skeleton.SkeletonResourceFront, slotName, attachmentName, new ProceduralTexture( $"Head Front CharacterID={character.Id} gen={headGenerationId}", proceduralTextureRequest => ClientCharacterHeadSpriteComposer.GenerateHeadSprite( new CharacterHeadSpriteData(faceStyle, headEquipmentForFaceSprite, skeleton.SkeletonResourceFront), proceduralTextureRequest, isMale, headSpriteType: ClientCharacterHeadSpriteComposer.HeadSpriteType.Front, spriteQualityOffset: spriteQualityOffset), isTransparent: true, isUseCache: false)); skeletonRenderer.SetAttachmentSprite( skeleton.SkeletonResourceBack, slotName, attachmentName, new ProceduralTexture( $"Head Back CharacterID={character.Id} gen={headGenerationId}", proceduralTextureRequest => ClientCharacterHeadSpriteComposer.GenerateHeadSprite( new CharacterHeadSpriteData(faceStyle, headEquipmentForFaceSprite, skeleton.SkeletonResourceBack), proceduralTextureRequest, isMale, headSpriteType: ClientCharacterHeadSpriteComposer.HeadSpriteType.Back, spriteQualityOffset: spriteQualityOffset), isTransparent: true, isUseCache: false)); skeletonRenderer.SetAttachmentSprite( skeleton.SkeletonResourceBack, slotName + "Back", attachmentName, new ProceduralTexture( $"Head Back2 CharacterID={character.Id} gen={headGenerationId}", proceduralTextureRequest => ClientCharacterHeadSpriteComposer.GenerateHeadSprite( new CharacterHeadSpriteData(faceStyle, headEquipmentForFaceSprite, skeleton.SkeletonResourceBack), proceduralTextureRequest, isMale, headSpriteType: ClientCharacterHeadSpriteComposer.HeadSpriteType.BackOverlay, spriteQualityOffset: spriteQualityOffset), isTransparent: true, isUseCache: false)); }
private static async Task <WelcomeMessageRemoteData> ClientOnWelcomeMessageReceivedFromServer( Task <WelcomeMessageRemoteData> t) { const string h1s = "[h1]", h1c = "[/h1]", br = "[br]", brbr = br + br; var data = t.Result; var sb = new StringBuilder(); var welcomeMessage = data.WelcomeMessage; await PveSystem.ClientAwaitPvEModeFromServer(); // Header 0 - Community server if (!Client.CurrentGame.IsConnectedToOfficialServer) { sb.AppendLine(h1s + HeaderDescriptionCommunity + h1c) .AppendLine(br) .AppendLine(DescriptionCommunity) .AppendLine(brbr); } // Header 1 - Server welcome message (section displayed only when available) if (!string.IsNullOrWhiteSpace(welcomeMessage)) { sb.AppendLine(h1s + HeaderWelcomeMessage + h1c) .AppendLine(br) .AppendLine(welcomeMessage) .AppendLine(brbr); } // Header 2 - PvP or PvE server description var isPveServer = PveSystem.ClientIsPve(logErrorIfDataIsNotYetAvailable: true); if (isPveServer) { sb.AppendLine(h1s + HeaderDescriptionPvE + h1c) .AppendLine(br) .AppendLine(DescriptionPvE) .AppendLine(brbr); } else // PvP server { sb.AppendLine(h1s + HeaderDescriptionPvP + h1c) .AppendLine(br) .AppendLine(DescriptionPvP) .AppendLine(brbr); } // Header 3 - Modded server (if the server is modded) if (Client.CurrentGame.ServerInfo.ModsOnServer.Count > 0) { sb.AppendLine(h1s + HeaderModded + h1c) .AppendLine(br) .AppendLine(DescriptionModded) .AppendLine(brbr); } // Header 4 - Server wipe information sb.AppendLine(h1s + HeaderWipeInformation + h1c) .AppendLine(br); if (data.ScheduledWipeDateUtc.HasValue) { sb.AppendLine(string.Format(CoreStrings.ServerWipeInfoStartedDate_Format, FormatDate(Client.CurrentGame.ServerInfo.CreationDateUtc.ToLocalTime()))) .AppendLine(br) .AppendLine(string.Format(CoreStrings.ServerWipeInfoNextWipeDate_Format, FormatDate(data.ScheduledWipeDateUtc.Value.ToLocalTime()))) .AppendLine(br) .AppendLine(ClientLocalTimeZoneHelper.GetTextTimeAlreadyConvertedToLocalTimeZone()); } else if (Client.CurrentGame.IsConnectedToOfficialServer && isPveServer) { sb.AppendLine(CoreStrings.ServerWipeInfoOnMajorUpdatesOnly); } else { sb.AppendLine(CoreStrings.ServerWipeInfoNotSpecified + " " + CoreStrings.ConsultServerAdministrator); } return(new WelcomeMessageRemoteData(sb.ToString(), data.ScheduledWipeDateUtc)); }
private async static void InitPVE() { await PveSystem.ClientAwaitPvEModeFromServer(); IsPVE = PveSystem.ClientIsPve(false); }