public override void ClientResetItemInHand(IComponentSkeleton skeletonRenderer) { skeletonRenderer.SetAttachmentSprite(this.SlotNameItemInHand, attachmentName: "WeaponMelee", textureResource: null); skeletonRenderer.SetAttachmentSprite(this.SlotNameItemInHand, attachmentName: "WeaponRifle", textureResource: null); skeletonRenderer.SetAttachment(this.SlotNameItemInHand, attachmentName: null); }
public static void SetAttachments( IComponentSkeleton skeletonRenderer, IReadOnlyList <SkeletonSlotAttachment> slotAttachments) { foreach (var skeleton in skeletonRenderer.AllSkeletons) { var skeletonName = skeleton.SkeletonName; foreach (var slotAttachment in slotAttachments) { if (slotAttachment.SkeletonName is not null && !slotAttachment.SkeletonName.Equals(skeletonName, StringComparison.Ordinal)) { // this attachment for different skeleton continue; } if (slotAttachment.AttachmentName.StartsWith("Head", StringComparison.Ordinal)) { // Head attachments are processed by ClientCharacterHeadSpriteComposer // when generating the head sprite. They're not assigned directly to skeleton. continue; } skeletonRenderer.SetAttachmentSprite( skeleton, // auto find slot slotName: null, attachmentName: slotAttachment.AttachmentName, textureResource: slotAttachment.TextureResource); } } }
public virtual void ClientSetupItemInHand( IComponentSkeleton skeletonRenderer, string attachmentName, TextureResource textureResource) { skeletonRenderer.SetAttachmentSprite(this.SlotNameItemInHand, attachmentName, textureResource); skeletonRenderer.SetAttachment(this.SlotNameItemInHand, attachmentName); }
public override void ClientSetupItemInHand( IComponentSkeleton skeletonRenderer, string attachmentName, TextureResource textureResource) { skeletonRenderer.SetAttachmentSprite(this.SlotNameItemInHand, attachmentName, textureResource); skeletonRenderer.SetAttachment(this.SlotNameItemInHand, attachmentName); // set left hand to use special sprite (representing holding of the item in hand) skeletonRenderer.SetAttachment("HandLeft", "HandLeft2"); skeletonRenderer.SetAttachment("HandLeftEquipment", "HandLeft2Equipment"); }
public static void Setup( IComponentSkeleton skeletonRenderer, string attachmentName, TextureResource textureResource) { skeletonRenderer.SetAttachmentSprite(SlotNameWeapon, attachmentName, textureResource); skeletonRenderer.SetAttachment(SlotNameWeapon, attachmentName); // set left hand to use special sprite (representing holding of the item in hand) skeletonRenderer.SetAttachment(SlotNameHandLeft, "HandLeft2"); skeletonRenderer.SetAttachment(SlotNameHandLeft + "Equipment", "HandLeft2Equipment"); }
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)); }
public static void SetupSkeletonEquipmentForCharacter( ICharacter character, IItemsContainer containerEquipment, IComponentSkeleton skeletonRenderer, ProtoCharacterSkeleton skeleton, List <IClientComponent> skeletonComponents) { if (!(skeleton is SkeletonHumanMale) && !(skeleton is SkeletonHumanFemale)) { // not a human return; } skeletonRenderer.ResetAttachments(); bool isMale; CharacterHumanFaceStyle faceStyle; if (character.ProtoCharacter is PlayerCharacter) { var pubicState = PlayerCharacter.GetPublicState(character); faceStyle = pubicState.FaceStyle; isMale = pubicState.IsMale; 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(); } // setup equipment items var equipmentItems = containerEquipment.GetItemsOfProto <IProtoItemEquipment>().ToList(); if (!IsAllowNakedHumans) { if (!equipmentItems.Any(i => i.ProtoGameObject is IProtoItemEquipmentLegs)) { // no lower cloth - apply generic one ClientSkeletonAttachmentsLoader.SetAttachments( skeletonRenderer, isMale ? GenericPantsAttachments.Value.SlotAttachmentsMale : GenericPantsAttachments.Value.SlotAttachmentsFemale); } if (!equipmentItems.Any(i => i.ProtoGameObject is IProtoItemEquipmentChest)) { // no upper cloth - apply generic one (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 headEquipment = null; foreach (var item in equipmentItems) { var proto = (IProtoItemEquipment)item.ProtoGameObject; proto.ClientSetupSkeleton(item, character, skeletonRenderer, skeletonComponents); if (item.ProtoItem is IProtoItemEquipmentHead && headEquipment == null) { headEquipment = item; } } // generate head sprites for human players const string slotName = "Head", attachmentName = "Head"; skeletonRenderer.SetAttachmentSprite( skeleton.SkeletonResourceFront, slotName, attachmentName, new ProceduralTexture( "Head Front CharacterID=" + character.Id, proceduralTextureRequest => ClientCharacterHeadSpriteComposer.GenerateHeadSprite( new CharacterHeadSpriteData(faceStyle, headEquipment, skeleton.SkeletonResourceFront), proceduralTextureRequest, isMale, isFrontFace: true, spriteQualityOffset: skeletonRenderer.SpriteQualityOffset), isTransparent: true, isUseCache: false)); skeletonRenderer.SetAttachmentSprite( skeleton.SkeletonResourceBack, slotName, attachmentName, new ProceduralTexture( "Head Back CharacterID=" + character.Id, proceduralTextureRequest => ClientCharacterHeadSpriteComposer.GenerateHeadSprite( new CharacterHeadSpriteData(faceStyle, headEquipment, skeleton.SkeletonResourceBack), proceduralTextureRequest, isMale, isFrontFace: false, spriteQualityOffset: skeletonRenderer.SpriteQualityOffset), isTransparent: true, isUseCache: false)); ClientResetWeaponAttachments(skeletonRenderer); }
public static void Reset(IComponentSkeleton skeletonRenderer) { skeletonRenderer.SetAttachmentSprite(SlotNameWeapon, attachmentName: "WeaponMelee", textureResource: null); skeletonRenderer.SetAttachmentSprite(SlotNameWeapon, attachmentName: "WeaponRifle", textureResource: null); skeletonRenderer.SetAttachment(SlotNameWeapon, attachmentName: null); }