/// <summary> /// Uses in texture procedural generation. /// </summary> /// <param name="request">Request from ProceduralTexture generator</param> /// <param name="textureWidth">Texture width</param> /// <param name="textureHeight">Texture height</param> /// <param name="spriteQualityOffset">Sprite quality modifier (0 = full size, 1 = x0.5, 2 = x0.25)</param> /// <returns></returns> public override async Task <ITextureResource> GenerateIcon( ProceduralTextureRequest request, ushort textureWidth = 512, ushort textureHeight = 512, sbyte spriteQualityOffset = 0) { if (!(ProtoEntity is IProtoCharacterMob creature)) // Can't be via constructor rule { Api.Logger.Error("CNEI: creature is not IProtoCharacterMob, but it shouldn't be possible!"); return(DefaultIcon); } creature.SharedGetSkeletonProto(null, out var creatureSkeleton, out double _); var worldScale = 1.0; if (creatureSkeleton is ProtoCharacterSkeletonAnimal animalSkeleton) { worldScale = animalSkeleton.WorldScale * 2; } string renderingTag = request.TextureName; var renderTarget = Api.Client.Rendering.CreateRenderTexture(renderingTag, textureWidth, textureHeight); var cameraObject = Api.Client.Scene.CreateSceneObject(renderingTag); var camera = Api.Client.Rendering.CreateCamera(cameraObject, renderingTag: renderingTag, drawOrder: -10); camera.RenderTarget = renderTarget; camera.ClearColor = Color.FromArgb(0, 0, 0, 0); camera.SetOrthographicProjection(textureWidth, textureHeight); var currentSkeleton = ClientCharacterEquipmentHelper.CreateCharacterSkeleton( cameraObject, creatureSkeleton, worldScale: worldScale, spriteQualityOffset: spriteQualityOffset); currentSkeleton.PositionOffset = (textureWidth / 2d, -textureHeight * 0.70); currentSkeleton.RenderingTag = renderingTag; await camera.DrawAsync(); cameraObject.Destroy(); request.ThrowIfCancelled(); var generatedTexture = await renderTarget.SaveToTexture( isTransparent : true, qualityScaleCoef : Api.Client.Rendering.CalculateCurrentQualityScaleCoefWithOffset( spriteQualityOffset)); currentSkeleton.Destroy(); renderTarget.Dispose(); request.ThrowIfCancelled(); return(generatedTexture); }
public async Task <ITextureResource> GenerateIcon( ProceduralTextureRequest request, ushort textureWidth = 384, ushort textureHeight = 384, sbyte spriteQualityOffset = 0) { var protoSkeleton = this; var scale = protoSkeleton.IconScale * textureWidth / 256.0; var renderingTag = request.TextureName; var renderTarget = Api.Client.Rendering.CreateRenderTexture(renderingTag, textureWidth, textureHeight); var cameraObject = Api.Client.Scene.CreateSceneObject(renderingTag); var camera = Api.Client.Rendering.CreateCamera(cameraObject, renderingTag: renderingTag, drawOrder: -100); camera.RenderTarget = renderTarget; camera.ClearColor = Color.FromArgb(0, 0, 0, 0); camera.SetOrthographicProjection(textureWidth, textureHeight); var currentSkeleton = ClientCharacterEquipmentHelper.CreateCharacterSkeleton( cameraObject, protoSkeleton, worldScale: scale, spriteQualityOffset: spriteQualityOffset); currentSkeleton.PositionOffset = (textureWidth / 2.0 + this.IconOffset.X * scale, -textureHeight * 0.7 + this.IconOffset.Y * scale); currentSkeleton.RenderingTag = renderingTag; await camera.DrawAsync(); cameraObject.Destroy(); request.ThrowIfCancelled(); var generatedTexture = await renderTarget.SaveToTexture( isTransparent : true, qualityScaleCoef : Api.Client.Rendering.CalculateCurrentQualityScaleCoefWithOffset( spriteQualityOffset)); currentSkeleton.Destroy(); renderTarget.Dispose(); request.ThrowIfCancelled(); return(generatedTexture); }