protected override void OnReload(GameMode currentGameMode, bool maintainState) { if (maintainState) { return; } var anyPrevious = _allOverlayTextures != null && _allOverlayTextures.Any(); if (anyPrevious) { RemoveAllOverlays(); } var pd = GetExtendedData(); if (pd != null && pd.data.TryGetValue(OverlayDataKey, out var overlayData)) { if (overlayData is byte[] overlayBytes) { try { _allOverlayTextures = MessagePackSerializer.Deserialize < Dictionary <CoordinateType, Dictionary <string, ClothesTexData> > >( overlayBytes); } catch (Exception ex) { var logLevel = currentGameMode == GameMode.Maker ? LogLevel.Message | LogLevel.Warning : LogLevel.Warning; Logger.Log(logLevel, "[KCOX] WARNING: Failed to load embedded overlay data for " + (ChaFileControl?.charaFileName ?? "?")); Logger.Log(LogLevel.Debug, ex); } } } if (_allOverlayTextures == null) { _allOverlayTextures = new Dictionary <CoordinateType, Dictionary <string, ClothesTexData> >(); } if (anyPrevious || _allOverlayTextures.Any()) { StartCoroutine(RefreshAllTexturesCo()); } }
public static void ChangeCustomClothesPostHook(ChaControl __instance, bool main, int kind) { var controller = __instance.GetComponent <KoiClothesOverlayController>(); if (controller == null) { return; } var clothesCtrl = GetCustomClothesComponent(__instance, main, kind); if (clothesCtrl == null) { return; } // Clean up no longer used textures when switching between top clothes with 3 parts and 1 part if (MakerAPI.InsideMaker && controller.CurrentOverlayTextures != null) { List <KeyValuePair <string, ClothesTexData> > toRemoveList = null; if (main && kind == 0) { toRemoveList = controller.CurrentOverlayTextures.Where(x => KoiClothesOverlayMgr.SubClothesNames.Contains(x.Key)).ToList(); } else if (!main) { toRemoveList = controller.CurrentOverlayTextures.Where(x => KoiClothesOverlayMgr.MainClothesNames[0] == x.Key).ToList(); } if (toRemoveList != null && toRemoveList.Count > 0) { Logger.Log(LogLevel.Warning | LogLevel.Message, $"[KCOX] Removing {toRemoveList.Count} no longer used Top overlay(s)"); foreach (var toRemove in toRemoveList) { controller.SetOverlayTex(null, toRemove.Key); } } } controller.ApplyOverlays(clothesCtrl); }
private void DumpBaseTextureImpl(Renderer[][] rendererArrs) { var act = RenderTexture.active; try { var renderer = GetApplicableRenderers(rendererArrs).FirstOrDefault(); var renderTexture = (RenderTexture)renderer?.material?.mainTexture; if (renderTexture == null) { throw new Exception("There are no renderers or textures to dump"); } RenderTexture.active = renderTexture; var tex = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false); tex.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); var png = tex.EncodeToPNG(); Destroy(tex); _dumpCallback(png); } catch (Exception e) { Logger.Log(LogLevel.Error | LogLevel.Message, "[KCOX] Dumping texture failed - " + e.Message); Logger.Log(LogLevel.Debug, e); RenderTexture.active = null; } finally { RenderTexture.active = act; _dumpCallback = null; } }
private void ApplyOverlays(ChaClothesComponent clothesCtrl) { if (CurrentOverlayTextures == null) { return; } var clothesName = clothesCtrl.name; var rendererArrs = GetRendererArrays(clothesCtrl); if (_dumpCallback != null && _dumpClothesId == clothesName) { DumpBaseTextureImpl(rendererArrs); } if (CurrentOverlayTextures.Count == 0) { return; } if (!CurrentOverlayTextures.TryGetValue(clothesName, out var overlay)) { return; } if (overlay == null || overlay.IsEmpty()) { return; } var applicableRenderers = GetApplicableRenderers(rendererArrs).ToList(); if (applicableRenderers.Count == 0) { Logger.Log(MakerAPI.InsideMaker ? LogLevel.Warning | LogLevel.Message : LogLevel.Debug, $"[KCOX] Removing unused overlay for {clothesName}"); overlay.Dispose(); CurrentOverlayTextures.Remove(clothesName); return; } foreach (var renderer in applicableRenderers) { var mat = renderer.material; var mainTexture = (RenderTexture)mat.mainTexture; if (mainTexture == null) { return; } if (overlay.Override) { var rta = RenderTexture.active; RenderTexture.active = mainTexture; GL.Clear(false, true, Color.clear); RenderTexture.active = rta; } if (overlay.Texture != null) { KoiSkinOverlayController.ApplyOverlay(mainTexture, overlay.Texture); } } }