private static void SaveEditedScene(CustomScene scene) { // Write the scene to a file try { string outPath = string.Join(Path.DirectorySeparatorChar.ToString(), new string[] { scene.Owner.DefaultResourcePath, "Scenes", scene.Name, "scene.json" }); // Save all images to a JSON object Dictionary <string, object> jsonObj = scene.ToJsonObj(); foreach (var img in scene.Images) { img.OnSave(jsonObj); } // Write to a file Directory.CreateDirectory(Path.GetDirectoryName(outPath)); File.WriteAllText(outPath, jsonObj.toJson()); // Unset all dirty flags foreach (var img in scene.Images) { img.dirty = false; } scene.dirty = false; } catch (Exception e) { Debug.Log("Failed to save scene to file!"); Debug.LogException(e); } }
internal static CustomScene OverrideNextScene(SlugBaseCharacter ply, string customSceneName, SceneImageFilter filter = null) { sceneOverride = ply.BuildScene(customSceneName); if (filter != null) { sceneOverride.ApplyFilter(filter); } return(sceneOverride); }
public void Update(MenuScene owner) { if (!alive) { return; } int handle = 0; Vector2?mousePos = Input.mousePosition; // Fade out handles not close to the mouse MenuIllustration closestIllust = null; { float minIllustDist = 20f * 20f; for (int i = 0; i < owner.subObjects.Count; i++) { if (!(owner.subObjects[i] is MenuIllustration illust)) { continue; } float dist = Vector2.SqrMagnitude(illust.pos + illust.size / 2f - mousePos.Value); if (minIllustDist > dist) { closestIllust = illust; minIllustDist = dist; } } } // Update move handles for (int i = 0; i < owner.subObjects.Count; i++) { if (!(owner.subObjects[i] is MenuIllustration illust)) { continue; } if (!customRep.TryGet(illust, out SceneImage csi)) { continue; } Vector2 centerPos = illust.pos + illust.size / 2f; if (handles.Count <= handle) { handles.Add(new MoveHandle(csi.DisplayName)); } handles[handle].SetVisible(illust.sprite.concatenatedAlpha > 0f); handles[handle].Update(ref centerPos, ref mousePos, closestIllust != null && closestIllust != illust); illust.pos = centerPos - illust.size / 2f; csi.Pos = illust.pos; handle++; } // Save on request if (Input.GetKeyDown(KeyCode.LeftBracket)) { CustomScene sceneToSave = null; foreach (var subObj in owner.subObjects) { if (!(subObj is MenuIllustration illust)) { continue; } SceneImage csi = customRep[illust]; if (csi != null && csi.Owner.dirty) { sceneToSave = csi.Owner; break; } } if (sceneToSave != null) { SaveEditedScene(sceneToSave); } } }
internal static void ClearSceneOverride() { sceneOverride = null; }
public GlowImage(CustomScene owner, float depth) : base(owner) { Pos = new Vector2(owner.GetProperty <float?>("glowx") ?? 683f, owner.GetProperty <float?>("glowy") ?? 484f); Debug.Log($"Glow is at {Pos}"); Depth = depth; }
public MarkImage(CustomScene owner, float depth) : base(owner) { Pos = new Vector2(owner.GetProperty <float?>("markx") ?? 683f, owner.GetProperty <float?>("marky") ?? 484f); Depth = depth; }
// Override select scenes for SlugBase characters private static void SlugcatPage_AddImage(On.Menu.SlugcatSelectMenu.SlugcatPage.orig_AddImage orig, SlugcatSelectMenu.SlugcatPage self, bool ascended) { SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(self.slugcatNumber); // Do not modify scenes for any non-SlugBase slugcats if (ply == null) { orig(self, ascended); return; } // Use Survivor's default scenes on the select menu string sceneName = ascended ? "SelectMenuAscended" : "SelectMenu"; if (!ply.HasScene(sceneName)) { orig(self, ascended); // Fix the scene position being off if (self.sceneOffset == default(Vector2)) { self.sceneOffset = new Vector2(-10f, 100f); } // Fix the wrong scene loading in when ascended if (ascended && self.slugcatImage.sceneID == MenuScene.SceneID.Slugcat_White) { self.slugcatImage.RemoveSprites(); self.RemoveSubObject(self.slugcatImage); self.slugcatImage = new InteractiveMenuScene(self.menu, self, MenuScene.SceneID.Ghost_White); self.subObjects.Add(self.slugcatImage); } return; } // Make sure it doesn't crash if the mark or glow is missing self.markSquare = new FSprite("pixel") { isVisible = false }; self.markGlow = new FSprite("pixel") { isVisible = false }; self.glowSpriteA = new FSprite("pixel") { isVisible = false }; self.glowSpriteB = new FSprite("pixel") { isVisible = false }; // This function intentionally does not call the original // If this mod has claimed a slot, it seems best to not let other mods try to change this screen // Taken from SlugcatPage.AddImage self.imagePos = new Vector2(683f, 484f); self.sceneOffset = new Vector2(0f, 0f); // Load a custom character's select screen from resources CustomScene scene = OverrideNextScene(ply, sceneName, img => { if (img.HasTag("MARK") && !self.HasMark) { return(false); } if (img.HasTag("GLOW") && !self.HasGlow) { return(false); } return(true); }); // Parse selectmenux and selectmenuy self.sceneOffset.x = scene.GetProperty <float?>("selectmenux") ?? 0f; self.sceneOffset.y = scene.GetProperty <float?>("selectmenuy") ?? 0f; Debug.Log($"Scene offset for {ply.Name}: {self.sceneOffset}"); // Slugcat depth, used for positioning the glow and mark self.slugcatDepth = scene.GetProperty <float?>("slugcatdepth") ?? 3f; // Add mark MarkImage mark = new MarkImage(scene, self.slugcatDepth + 0.1f); scene.InsertImage(mark); // Add glow GlowImage glow = new GlowImage(scene, self.slugcatDepth + 0.1f); scene.InsertImage(glow); try { self.slugcatImage = new InteractiveMenuScene(self.menu, self, MenuScene.SceneID.Slugcat_White); // This scene will be immediately overwritten } finally { ClearSceneOverride(); } self.subObjects.Add(self.slugcatImage); // Find the relative mark and glow positions self.markOffset = mark.Pos - new Vector2(self.MidXpos, self.imagePos.y + 150f) + self.sceneOffset; self.glowOffset = glow.Pos - new Vector2(self.MidXpos, self.imagePos.y) + self.sceneOffset; }