public static void PressKey(MobileApp app) { if (app.closePhone) { PhoneUtils.TogglePhone(false); } if (!Enum.TryParse(app.keyPress, out SButton keyPress)) { Monitor.Log($"Error on app invoke: {app.keyPress} isn't a valid key", LogLevel.Error); return; } // get SMAPI's input handler var input = Game1.input; // get OverrideButton method var method = input.GetType().GetMethod("OverrideButton"); if (method == null) { Monitor.Log("Can't find 'OverrideButton' method on SMAPI's input class.", LogLevel.Error); return; } // call method // The arguments are the button to override, and whether to mark the button pressed (true) or raised (false) method.Invoke(input, new object[] { keyPress, true }); return; }
public static void GameLoop_OneSecondUpdateTicked(object sender, OneSecondUpdateTickedEventArgs e) { if (ModEntry.callingNPC != null && Game1.activeClickableMenu == null) { if (ModEntry.currentCallRings < ModEntry.currentCallMaxRings && !ModEntry.inCall) { if (ModEntry.ringToggle == Config.PhoneRingInterval) { Monitor.Log($"Phone ringing, {ModEntry.callingNPC.displayName} calling", LogLevel.Debug); PhoneUtils.PlayRingTone(); ModEntry.currentCallRings++; ModEntry.ringToggle = 0; } else { ModEntry.ringToggle++; } } else { if (!ModEntry.inCall) { ModEntry.callingNPC = null; } ModEntry.currentCallRings = 0; } } }
public static void PressKey(MobileApp app) { if (app.closePhone) { PhoneUtils.TogglePhone(false); } if (!Enum.TryParse(app.keyPress, out SButton keyPress)) { Monitor.Log($"Error on app invoke: {app.keyPress} isn't a valid key", LogLevel.Error); return; } // get SMAPI's input handler object input = typeof(Game1).GetField("input", BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) ?? throw new InvalidOperationException("Can't find 'Game1.input' field."); // get OverrideButton method var method = input.GetType().GetMethod("OverrideButton") ?? throw new InvalidOperationException("Can't find 'OverrideButton' method on SMAPI's input class."); // call method // The arguments are the button to override, and whether to mark the button pressed (true) or raised (false) method.Invoke(input, new object[] { keyPress, true }); return; }
public static void GameLoop_OneSecondUpdateTicked(object sender, OneSecondUpdateTickedEventArgs e) { if (ModEntry.callingNPC != null && Game1.activeClickableMenu == null) { if (ModEntry.currentCallRings < ModEntry.currentCallMaxRings && !ModEntry.inCall) { if (ModEntry.currentCallRings == 0 && Config.NotifyOnRing) { Game1.addHUDMessage(new HUDMessage(Helper.Translation.Get("phone-ringing"), 2)); } if (ModEntry.ringToggle == Config.PhoneRingInterval) { Monitor.Log($"Phone ringing, {ModEntry.callingNPC.displayName} calling", LogLevel.Debug); PhoneUtils.PlayRingTone(); ModEntry.currentCallRings++; ModEntry.ringToggle = 0; } else { ModEntry.ringToggle++; } } else { PhoneUtils.StopRingTone(); if (!ModEntry.inCall) { ModEntry.callingNPC = null; } ModEntry.currentCallRings = 0; } } }
private static void DoRecruit(NPC npc) { Monitor.Log($"Doing recruit"); if (!ModEntry.inCall) { Monitor.Log($"Not in call, exiting"); return; } if (ModEntry.npcAdventureModApi.RecruitCompanion(Game1.player, npc)) { if (ModEntry.npcAdventureModApi.IsRecruited(npc)) { Vector2 targetPos = PhoneUtils.GetOpenSurroundingPosition(); Monitor.Log($"Recruiting {npc.Name} to {targetPos} (player: {Game1.player.getTileLocation()})"); Game1.warpCharacter(npc, Game1.player.currentLocation, targetPos); npc.Sprite.StopAnimation(); EndCall(); } else { ShowMainCallDialogue(npc); } } else { Monitor.Log($"Error trying to recruit {npc.Name}", LogLevel.Error); ShowMainCallDialogue(npc); } }
public static void ReceiveRandomCall() { CreateCallableList(); if (callableList.Count == 0) { Monitor.Log($"You have no friends.", LogLevel.Debug); return; } CallableNPC[] callers = callableList.Where(s => (s.npc.CurrentDialogue.Count >= 1 || s.npc.endOfRouteMessage.Value != null) && !s.npc.isSleeping).ToArray(); if (callers.Length == 0) { Monitor.Log($"None of your friends want to talk to you.", LogLevel.Debug); return; } CallableNPC caller = callers[Game1.random.Next(callers.Length)]; Monitor.Log($"Friend calling: {caller.npc.displayName}", LogLevel.Debug); PhoneUtils.PlayRingTone(); ModEntry.currentCallRings = 0; ModEntry.currentCallMaxRings = Game1.random.Next(Math.Max(0, Config.IncomingCallMinRings), Math.Max(Config.IncomingCallMinRings + 1, Config.IncomingCallMaxRings)); ModEntry.callingNPC = caller.npc; }
public static void GameLoop_SaveLoaded(object sender, StardewModdingAPI.Events.SaveLoadedEventArgs e) { Monitor.Log($"total apps: {ModEntry.apps.Count}"); PhoneUtils.OrderApps(); PhoneUtils.RefreshPhoneLayout(); Helper.Events.Display.RenderedWorld += PhoneVisuals.Display_RenderedWorld; if (ModEntry.npcAdventureModApi != null) { Monitor.Log("Testing NpcAdventureModApi..."); try { Monitor.Log($"Can recruit: {ModEntry.npcAdventureModApi.CanRecruitCompanions()}"); Monitor.Log($"Possible companions: {ModEntry.npcAdventureModApi.GetPossibleCompanions().Count()}"); Monitor.Log($"Can recruit Abigail: {ModEntry.npcAdventureModApi.IsPossibleCompanion("Abigail")}"); Monitor.Log($"Recruit Abigail: {ModEntry.npcAdventureModApi.IsPossibleCompanion("Abigail") && ModEntry.npcAdventureModApi.RecruitCompanion(Game1.player, Game1.getCharacterFromName("Abigail"))}"); } catch (Exception ex) { Monitor.Log($"Error testing NpcAdventureModApi: {ex}", LogLevel.Warn); } Monitor.Log("Testing NpcAdventureModApi finished"); } }
private static void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) { if (ModEntry.callingNPC != null) { return; } if (!ModEntry.appRunning || !ModEntry.phoneOpen || ModEntry.runningApp != Helper.ModRegistry.ModID) { ModEntry.appRunning = false; ModEntry.phoneAppRunning = false; Helper.Events.Display.RenderedWorld -= Display_RenderedWorld; Helper.Events.Input.ButtonPressed -= Input_ButtonPressed; Helper.Events.Input.MouseWheelScrolled -= Input_MouseWheelScrolled; return; } Vector2 screenPos = PhoneUtils.GetScreenPosition(); Vector2 screenSize = PhoneUtils.GetScreenSize(); Rectangle headerRect = new Rectangle((int)screenPos.X, (int)screenPos.Y, (int)screenSize.X, Config.AppHeaderHeight); Point mousePos = Game1.getMousePosition(); if (Helper.Input.IsSuppressed(SButton.MouseLeft)) { int dy = mousePos.Y - lastMousePositionY; if (Math.Abs(dy) > 0 && ModEntry.screenRect.Contains(mousePos)) { dragging = true; } if (dragging) { AddYOffset(dy); } } if (clicked && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { clicked = false; if (dragging) { Monitor.Log($"was dragging"); dragging = false; } else { if (headerRect.Contains(mousePos)) { if (new Rectangle((int)screenPos.X + (int)screenSize.X - Config.AppHeaderHeight, (int)screenPos.Y, Config.AppHeaderHeight, Config.AppHeaderHeight).Contains(mousePos)) { PhoneUtils.ToggleApp(false); } } else { for (int i = 0; i < callableList.Count; i++) { Vector2 pos = GetNPCPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.ContactWidth, Config.ContactHeight); if (r.Contains(mousePos)) { Monitor.Log($"calling {callableList[i].npc.Name}"); //PhoneUtils.PlayRingTone(); CallNPC(callableList[i].npc); } } } } } lastMousePositionY = Game1.getMouseY(); int startListY = (int)screenPos.Y + Config.AppHeaderHeight; e.SpriteBatch.Draw(ModEntry.phoneBookTexture, screenPos, Color.White); if (yOffset < 0) { e.SpriteBatch.Draw(ModEntry.upArrowTexture, ModEntry.upArrowPosition, Color.White); } if (yOffset > PhoneUtils.GetScreenSize().Y - Config.AppHeaderHeight - listHeight) { e.SpriteBatch.Draw(ModEntry.downArrowTexture, ModEntry.downArrowPosition, Color.White); } int screenBottom = (int)(screenPos.Y + screenSize.Y); for (int i = 0; i < callableList.Count; i++) { Vector2 npcPos = GetNPCPos(i); Rectangle r = callableList[i].sourceRect; if (npcPos.Y < startListY - r.Height * 2 || npcPos.Y >= screenBottom) { continue; } Rectangle sourceRect = r; int cutTop = 0; int cutBottom = 0; if (npcPos.Y < startListY) { cutTop = (int)Math.Round((startListY - (int)npcPos.Y) / 2f); sourceRect = new Rectangle(r.X, r.Y + cutTop, r.Width, r.Height - cutTop); npcPos = new Vector2(npcPos.X, startListY); } else if (npcPos.Y > screenBottom - r.Height * 2) { cutBottom = (int)Math.Round((screenBottom - r.Height * 2 - (int)npcPos.Y) / 2f); sourceRect = new Rectangle(r.X, r.Y, r.Width, r.Height + cutBottom); } int alpha = callableList[i].npc.CurrentDialogue.Any() && !callableList[i].npc.isSleeping ? 255 : Config.UncallableNPCAlpha; e.SpriteBatch.Draw(callableList[i].portrait, npcPos + new Vector2((Config.ContactWidth - 32) / 2f, 0), sourceRect, new Color(255, 255, 255, alpha), 0, Vector2.Zero, 2, SpriteEffects.None, 0.86f); if (Config.ShowNamesInPhoneBook && npcPos.Y < screenBottom - Config.ContactHeight - callableList[i].nameSize.Y * 0.4f + 6) { e.SpriteBatch.DrawString(Game1.dialogueFont, callableList[i].name, GetNPCPos(i) + new Vector2(Config.ContactWidth / 2f - callableList[i].nameSize.X * 0.2f, Config.ContactHeight - 6), Color.Black, 0, Vector2.Zero, 0.4f, SpriteEffects.None, 0.86f); } } e.SpriteBatch.Draw(ModEntry.phoneBookHeaderTexture, headerRect, Color.White); string headerText = Helper.Translation.Get("phone-book"); Vector2 headerTextSize = Game1.dialogueFont.MeasureString(headerText) * Config.HeaderTextScale; e.SpriteBatch.DrawString(Game1.dialogueFont, headerText, screenPos + new Vector2(screenSize.X / 2f - headerTextSize.X / 2f, Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), Config.PhoneBookHeaderTextColor, 0, Vector2.Zero, Config.HeaderTextScale, SpriteEffects.None, 0.86f); e.SpriteBatch.DrawString(Game1.dialogueFont, "x", screenPos + new Vector2(screenSize.X - Config.AppHeaderHeight / 2f - Game1.dialogueFont.MeasureString("x").X *Config.HeaderTextScale / 2f, Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), Config.PhoneBookHeaderTextColor, 0, Vector2.Zero, Config.HeaderTextScale, SpriteEffects.None, 0.86f); }
public static void GameLoop_GameLaunched(object sender, StardewModdingAPI.Events.GameLaunchedEventArgs e) { foreach (IContentPack contentPack in Helper.ContentPacks.GetOwned()) { Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}"); try { MobilePhonePackJSON json = contentPack.ReadJsonFile <MobilePhonePackJSON>("content.json") ?? null; if (json != null) { if (json.apps != null && json.apps.Any()) { foreach (AppJSON app in json.apps) { Texture2D tex = contentPack.LoadAsset <Texture2D>(app.iconPath); if (tex == null) { continue; } ModEntry.apps.Add(app.id, new MobileApp(app.name, app.keyPress, app.closePhone, tex)); Monitor.Log($"Added app {app.name} from {contentPack.DirectoryPath}"); } } else if (json.iconPath != null) { Texture2D icon = contentPack.LoadAsset <Texture2D>(json.iconPath); if (icon == null) { continue; } ModEntry.apps.Add(json.id, new MobileApp(json.name, json.keyPress, json.closePhone, icon)); Monitor.Log($"Added app {json.name} from {contentPack.DirectoryPath}"); } if (json.invites != null && json.invites.Any()) { foreach (EventInvite invite in json.invites) { MobilePhoneCall.eventInvites.Add(invite); Monitor.Log($"Added event invite {invite.name} from {contentPack.DirectoryPath}"); } } } } catch (Exception ex) { Monitor.Log($"error reading content.json file in content pack {contentPack.Manifest.Name}.\r\n{ex}", LogLevel.Error); } if (Directory.Exists(Path.Combine(contentPack.DirectoryPath, "assets", "events"))) { Monitor.Log($"Adding events"); string[] events = Directory.GetFiles(Path.Combine(contentPack.DirectoryPath, "assets", "events"), "*.json"); Monitor.Log($"CP has {events.Length} events"); foreach (string eventFile in events) { try { string eventPath = Path.Combine("assets", "events", Path.GetFileName(eventFile)); Monitor.Log($"Adding events {Path.GetFileName(eventFile)} from {contentPack.DirectoryPath}"); Reminiscence r = contentPack.ReadJsonFile <Reminiscence>(eventPath); var key = Path.GetFileName(eventFile).Replace(".json", ""); MobilePhoneCall.contentPackReminiscences.TryAdd(key, new Reminiscence()); MobilePhoneCall.contentPackReminiscences[key].events.AddRange(r.events); Monitor.Log($"Added event {Path.GetFileName(eventFile)} from {contentPack.DirectoryPath}"); } catch { } } } if (Directory.Exists(Path.Combine(contentPack.DirectoryPath, "assets", "skins"))) { Monitor.Log($"Adding skins"); string[] skins = Directory.GetFiles(Path.Combine(contentPack.DirectoryPath, "assets", "skins"), "*_landscape.png"); Monitor.Log($"CP has {skins.Length} skins"); foreach (string skinFile in skins) { try { string skinPath = Path.Combine("assets", "skins", Path.GetFileName(skinFile)); Monitor.Log($"Adding skin {Path.GetFileName(skinFile).Replace("_landscape.png", "")} from {contentPack.DirectoryPath}"); Texture2D skin = contentPack.LoadAsset <Texture2D>(skinPath.Replace("_landscape.png", ".png")); Texture2D skinl = contentPack.LoadAsset <Texture2D>(skinPath); ThemeApp.skinList.Add(contentPack.Manifest.UniqueID + ":" + Path.GetFileName(skinFile).Replace("_landscape.png", "")); ThemeApp.skinDict.Add(contentPack.Manifest.UniqueID + ":" + Path.GetFileName(skinFile).Replace("_landscape.png", ""), new Texture2D[] { skin, skinl }); Monitor.Log($"Added skin {Path.GetFileName(skinFile).Replace("_landscape.png", "")} from {contentPack.DirectoryPath}"); } catch { } } } if (Directory.Exists(Path.Combine(contentPack.DirectoryPath, "assets", "backgrounds"))) { Monitor.Log($"Adding backgrounds"); string[] backgrounds = Directory.GetFiles(Path.Combine(contentPack.DirectoryPath, "assets", "backgrounds"), "*_landscape.png"); Monitor.Log($"CP has {backgrounds.Length} backgrounds"); foreach (string backFile in backgrounds) { try { string backPath = Path.Combine("assets", "backgrounds", Path.GetFileName(backFile)); Monitor.Log($"Adding background {Path.GetFileName(backFile).Replace("_landscape.png", "")} from {contentPack.DirectoryPath}"); Texture2D back = contentPack.LoadAsset <Texture2D>(backPath.Replace("_landscape.png", ".png")); Texture2D backl = contentPack.LoadAsset <Texture2D>(backPath); ThemeApp.backgroundDict.Add(contentPack.Manifest.UniqueID + ":" + Path.GetFileName(backFile).Replace("_landscape.png", ""), new Texture2D[] { back, backl }); ThemeApp.backgroundList.Add(contentPack.Manifest.UniqueID + ":" + Path.GetFileName(backFile).Replace("_landscape.png", "")); Monitor.Log($"Added background {Path.GetFileName(backFile).Replace("_landscape.png", "")} from {contentPack.DirectoryPath}"); } catch { } } } if (Directory.Exists(Path.Combine(contentPack.DirectoryPath, "assets", "ringtones"))) { Monitor.Log($"Adding ringtones"); string[] rings = Directory.GetFiles(Path.Combine(contentPack.DirectoryPath, "assets", "ringtones"), "*.wav"); Monitor.Log($"CP has {rings.Length} ringtones"); foreach (string path in rings) { try { object ring; try { var type = Type.GetType("System.Media.SoundPlayer, System"); ring = Activator.CreateInstance(type, new object[] { path }); } catch { ring = SoundEffect.FromStream(new FileStream(path, FileMode.Open)); } if (ring != null) { ThemeApp.ringDict.Add(string.Concat(contentPack.Manifest.UniqueID, ":", Path.GetFileName(path).Replace(".wav", "")), ring); ThemeApp.ringList.Add(string.Concat(contentPack.Manifest.UniqueID, ":", Path.GetFileName(path).Replace(".wav", ""))); Monitor.Log($"loaded ring {path}"); } else { Monitor.Log($"Couldn't load ring {path}"); } } catch (Exception ex) { Monitor.Log($"Couldn't load ring {path}:\r\n{ex}", LogLevel.Error); } } } } ModEntry.listHeight = Config.IconMarginY + (int)Math.Ceiling(ModEntry.apps.Count / (float)ModEntry.gridWidth) * (Config.IconHeight + Config.IconMarginY); PhoneVisuals.CreatePhoneTextures(); PhoneUtils.RefreshPhoneLayout(); if (Helper.ModRegistry.IsLoaded("purrplingcat.npcadventure")) { INpcAdventureModApi api = Helper.ModRegistry.GetApi <INpcAdventureModApi>("purrplingcat.npcadventure"); if (api != null) { Monitor.Log("Loaded NpcAdventureModApi successfully"); ModEntry.npcAdventureModApi = api; } } if (Helper.ModRegistry.IsLoaded("tlitookilakin.HDPortraits")) { IHDPortraitsAPI api = Helper.ModRegistry.GetApi <IHDPortraitsAPI>("tlitookilakin.HDPortraits"); if (api != null) { Monitor.Log("Loaded HD Portraits api successfully"); ModEntry.iHDPortraitsAPI = api; } } }
public Vector2 GetScreenPosition() { return(PhoneUtils.GetScreenPosition()); }
public static void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) { if (!Context.IsWorldReady) { return; } if (Game1.activeClickableMenu == null && ModEntry.phoneOpen && e.Button == SButton.Escape) { PhoneUtils.TogglePhone(); Helper.Input.Suppress(SButton.Escape); return; } if (e.Button == Config.OpenPhoneKey && Config.EnableOpenPhoneKey) { PhoneUtils.TogglePhone(); return; } if (e.Button == Config.RotatePhoneKey && Config.EnableRotatePhoneKey) { PhoneUtils.RotatePhone(); return; } Point mousePos = Game1.getMousePosition(); if (!ModEntry.phoneOpen) { if (e.Button == SButton.MouseLeft && Game1.displayHUD && Config.ShowPhoneIcon && new Rectangle((int)ModEntry.phoneIconPosition.X, (int)ModEntry.phoneIconPosition.Y, Config.PhoneIconWidth, Config.PhoneIconHeight).Contains(mousePos)) { Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clickingPhoneIcon = true; ModEntry.draggingPhoneIcon = false; ModEntry.lastMousePosition = mousePos; } return; } if (e.Button == SButton.MouseLeft) { if (Game1.activeClickableMenu == null && !ModEntry.inCall && !ModEntry.appRunning && !ModEntry.phoneRect.Contains(mousePos)) { Monitor.Log($"pressing mouse outside of opened phone"); Helper.Input.Suppress(SButton.MouseLeft); PhoneUtils.TogglePhone(); return; } if (ModEntry.phoneRect.Contains(mousePos) && !ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key on phone border"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; ModEntry.draggingPhone = true; ModEntry.lastMousePosition = mousePos; return; } if (ModEntry.callingNPC != null && ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key in phone while calling"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; return; } if (!ModEntry.appRunning && ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key in phone"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; ModEntry.lastMousePosition = mousePos; for (int i = 0; i < ModEntry.appOrder.Count; i++) { Vector2 pos = PhoneUtils.GetAppPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.IconWidth, Config.IconHeight); if (r.Contains(mousePos)) { ModEntry.clickingApp = i; ModEntry.clickingTicks = 0; break; } } } } }
public static void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) { Point mousePos = Game1.getMousePosition(); Point lastMousePos = ModEntry.lastMousePosition; ModEntry.lastMousePosition = mousePos; if (!ModEntry.phoneOpen) { ModEntry.appRunning = false; ModEntry.runningApp = null; if (Config.ShowPhoneIcon && Game1.displayHUD && !Game1.eventUp && Game1.currentBillboard == 0 && Game1.gameMode == 3 && !Game1.freezeControls && !Game1.panMode && !Game1.HostPaused && !Game1.game1.takingMapScreenshot) { if (ModEntry.clickingPhoneIcon) { if (Helper.Input.IsSuppressed(SButton.MouseLeft) && lastMousePos != mousePos) { ModEntry.draggingPhoneIcon = true; Config.PhoneIconOffsetX += mousePos.X - lastMousePos.X; Config.PhoneIconOffsetY += mousePos.Y - lastMousePos.Y; ModEntry.phoneIconPosition = PhoneUtils.GetPhoneIconPosition(); } else if (!Helper.Input.IsSuppressed(SButton.MouseLeft)) { if (!ModEntry.draggingPhoneIcon) { PhoneUtils.TogglePhone(true); } else { Helper.WriteConfig(Config); } ModEntry.clickingPhoneIcon = false; ModEntry.draggingPhoneIcon = false; } } e.SpriteBatch.Draw(ModEntry.iconTexture, ModEntry.phoneIconPosition, Color.White); } return; } else { ModEntry.clickingPhoneIcon = false; ModEntry.draggingPhoneIcon = false; } if (Game1.game1.takingMapScreenshot) { return; } if (ModEntry.draggingPhone) { if (Helper.Input.IsSuppressed(SButton.MouseLeft)) { if (mousePos != lastMousePos) { int x = mousePos.X - lastMousePos.X; int y = mousePos.Y - lastMousePos.Y; if (ModEntry.phoneRotated) { Config.PhoneRotatedOffsetX += x; Config.PhoneRotatedOffsetY += y; } else { Config.PhoneOffsetX += x; Config.PhoneOffsetY += y; } PhoneUtils.RefreshPhoneLayout(); } } else { ModEntry.context.Helper.WriteConfig(Config); ModEntry.draggingPhone = false; Monitor.Log($"released dragging phone"); } } else if (Helper.Input.IsSuppressed(SButton.MouseLeft) && !ModEntry.movingAppIcon) { int dy = mousePos.Y - lastMousePos.Y; if (Math.Abs(dy) > 0 && ModEntry.screenRect.Contains(mousePos)) { ModEntry.clickingApp = -1; ModEntry.draggingIcons = true; } if (ModEntry.draggingIcons) { ModEntry.yOffset = (int)Math.Max(Math.Min(0, ModEntry.yOffset + dy), -1 * Math.Max(0, ModEntry.listHeight - PhoneUtils.GetScreenSize().Y)); } } e.SpriteBatch.Draw(ModEntry.phoneRotated ? ModEntry.backgroundRotatedTexture : ModEntry.backgroundTexture, ModEntry.phoneRect, Color.White); e.SpriteBatch.Draw(ModEntry.phoneRotated ? ModEntry.phoneRotatedTexture : ModEntry.phoneTexture, ModEntry.phoneRect, Color.White); Vector2 screenPos = PhoneUtils.GetScreenPosition(); Vector2 screenSize = PhoneUtils.GetScreenSize(); if (ModEntry.callingNPC != null) { Rectangle destRect; Rectangle portraitSource = Game1.getSourceRectForStandardTileSheet(ModEntry.callingNPC.Portrait, 0, 64, 64); float scale; if ((float)portraitSource.Height * screenSize.X / (float)portraitSource.Width > screenSize.Y - Config.AppHeaderHeight) { scale = (screenSize.Y - Config.AppHeaderHeight) / (float)portraitSource.Height; destRect = new Rectangle((int)(screenPos.X + screenSize.X / 2f - portraitSource.Width * scale / 2f), (int)screenPos.Y, (int)(portraitSource.Width * scale), (int)screenSize.Y - Config.AppHeaderHeight); } else { scale = screenSize.X / (float)portraitSource.Width; //Monitor.Log($"{screenSize} {portraitSource.Width},{portraitSource.Height} {scale}"); destRect = new Rectangle((int)(screenPos.X), (int)(screenPos.Y + (screenSize.Y - Config.AppHeaderHeight) / 2f - portraitSource.Height * scale / 2f), (int)screenSize.X, (int)(portraitSource.Height * scale)); } e.SpriteBatch.Draw(ModEntry.callingNPC.Portrait, destRect, new Rectangle?(portraitSource), Color.White); SpriteText.drawStringHorizontallyCenteredAt(e.SpriteBatch, ModEntry.callingNPC.getName(), destRect.X + destRect.Width / 2, destRect.Bottom + 16, 999999, -1, 999999, 1f, 0.88f, false, -1, 99999); if (!ModEntry.inCall) { Rectangle answerRect = new Rectangle((int)(screenPos.X), ModEntry.screenRect.Bottom - Config.AppHeaderHeight, (int)(screenSize.X / 2f), Config.AppHeaderHeight); Rectangle declineRect = new Rectangle((int)(screenPos.X + screenSize.X / 2f), ModEntry.screenRect.Bottom - Config.AppHeaderHeight, (int)(screenSize.X / 2f), Config.AppHeaderHeight); e.SpriteBatch.Draw(ModEntry.answerTexture, answerRect, Color.White); e.SpriteBatch.Draw(ModEntry.declineTexture, declineRect, Color.White); float textScale = Config.CallTextScale; string ans = Helper.Translation.Get("answer"); Vector2 ansSize = Game1.dialogueFont.MeasureString(ans) * textScale; string dec = Helper.Translation.Get("decline"); Vector2 decSize = Game1.dialogueFont.MeasureString(dec) * textScale; e.SpriteBatch.DrawString(Game1.dialogueFont, ans, new Vector2(answerRect.X + answerRect.Width / 2f - ansSize.X / 2f, answerRect.Top + answerRect.Height / 2f - ansSize.Y / 2f), Config.CallTextColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 1f); e.SpriteBatch.DrawString(Game1.dialogueFont, dec, new Vector2(declineRect.X + declineRect.Width / 2f - decSize.X / 2f, declineRect.Top + declineRect.Height / 2f - decSize.Y / 2f), Config.CallTextColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 1f); if (ModEntry.clicking && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { if (answerRect.Contains(mousePos)) { MobilePhoneApp.CallNPC(ModEntry.callingNPC); ModEntry.currentCallRings = 0; } else if (declineRect.Contains(mousePos)) { ModEntry.currentCallRings = 0; ModEntry.callingNPC = null; } } } else { Rectangle endRect = new Rectangle((int)(screenPos.X + screenSize.X / 4), ModEntry.screenRect.Bottom - Config.AppHeaderHeight, (int)(screenSize.X / 2), Config.AppHeaderHeight); e.SpriteBatch.Draw(ModEntry.declineTexture, endRect, Color.White); float textScale = Config.CallTextScale; string ends = Helper.Translation.Get("end-call"); Vector2 endsSize = Game1.dialogueFont.MeasureString(ends) * textScale; e.SpriteBatch.DrawString(Game1.dialogueFont, ends, new Vector2(endRect.X + endRect.Width / 2f - endsSize.X / 2f, endRect.Top + endRect.Height / 2f - endsSize.Y / 2f), Config.CallTextColor, 0f, Vector2.Zero, textScale, SpriteEffects.None, 1f); if (ModEntry.clicking && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { if (endRect.Contains(mousePos)) { MobilePhoneCall.EndCall(); if (Game1.activeClickableMenu is DialogueBox) { Game1.activeClickableMenu = null; } } } } if ((ModEntry.clicking || ModEntry.clickingPhoneIcon) && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { ModEntry.clickingApp = -1; ModEntry.switchingApp = -1; ModEntry.movingAppIconOffset = new Point(0, 0); ModEntry.clickingTicks = 0; ModEntry.clicking = false; ModEntry.movingAppIcon = false; ModEntry.clickingPhoneIcon = false; ModEntry.draggingPhone = false; ModEntry.draggingIcons = false; } return; } if (ModEntry.appRunning) { return; } if (ModEntry.runningApp == Helper.ModRegistry.ModID && Game1.activeClickableMenu == null) { MobilePhoneApp.OpenPhoneBook(); return; } List <string> keys = new List <string>(ModEntry.appOrder); if ((ModEntry.clicking || ModEntry.clickingPhoneIcon) && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { Monitor.Log($"released click"); if (ModEntry.movingAppIcon && ModEntry.switchingApp != -1) { Monitor.Log($"switching app: {ModEntry.switchingApp} clicking app {ModEntry.clickingApp}"); Game1.playSound("stoneStep"); ModEntry.appOrder[ModEntry.clickingApp] = keys[ModEntry.switchingApp]; ModEntry.appOrder[ModEntry.switchingApp] = keys[ModEntry.clickingApp]; keys = new List <string>(ModEntry.appOrder); Config.AppList = keys.ToArray(); Helper.WriteConfig(Config); } else if (ModEntry.draggingIcons) { ModEntry.draggingIcons = false; } else if (!ModEntry.movingAppIcon) { for (int i = 0; i < keys.Count; i++) { Vector2 pos = PhoneUtils.GetAppPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.IconWidth, Config.IconHeight); if (r.Contains(mousePos)) { if (ModEntry.apps[keys[i]].keyPress != null) { Monitor.Log($"pressing key {ModEntry.apps[keys[i]].keyPress}"); PhoneInput.PressKey(ModEntry.apps[keys[i]]); } else { Monitor.Log($"starting app {ModEntry.apps[keys[i]].name}"); ModEntry.apps[keys[i]].action.Invoke(); } } } } ModEntry.clickingApp = -1; ModEntry.switchingApp = -1; ModEntry.movingAppIconOffset = new Point(0, 0); ModEntry.clickingTicks = 0; ModEntry.clicking = false; ModEntry.movingAppIcon = false; ModEntry.clickingPhoneIcon = false; ModEntry.draggingPhone = false; ModEntry.draggingIcons = false; } else if (ModEntry.clicking && ModEntry.clickingApp != -1 && !ModEntry.movingAppIcon) { if (lastMousePos == mousePos) { if (ModEntry.clickingTicks > Config.TicksToMoveAppIcon) { Game1.playSound("pickUpItem"); ModEntry.movingAppIconOffset = new Point(5, 5); ModEntry.movingAppIcon = true; } else { ModEntry.clickingTicks++; } } else { ModEntry.clickingTicks = 0; ModEntry.clickingApp = -1; } } else if (ModEntry.movingAppIcon) { ModEntry.movingAppIconOffset = new Point(ModEntry.movingAppIconOffset.X + mousePos.X - lastMousePos.X, ModEntry.movingAppIconOffset.Y + mousePos.Y - lastMousePos.Y); Vector2 currentPos = PhoneUtils.GetAppPos(ModEntry.clickingApp); if (ModEntry.screenRect.Contains(Utility.Vector2ToPoint(currentPos))) { bool alreadySwitched = false; if (ModEntry.switchingApp != -1) { Vector2 pos = PhoneUtils.GetAppPos(ModEntry.switchingApp, true); if (Vector2.Distance(currentPos, pos) < (Config.IconWidth + Config.IconHeight) / 4f) { alreadySwitched = true; } } if (!alreadySwitched) { for (int i = 0; i < keys.Count; i++) { Vector2 pos = PhoneUtils.GetAppPos(i); if (i != ModEntry.clickingApp && Vector2.Distance(currentPos, pos) < (Config.IconWidth + Config.IconHeight) / 4f) { ModEntry.switchingApp = i; Monitor.Log($"new switching app: {ModEntry.switchingApp} clicking app {ModEntry.clickingApp}"); break; } else { ModEntry.switchingApp = -1; } } } } } string appHover = null; bool hover = false; if (mousePos == lastMousePos && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { hover = true; } else { ModEntry.ticksSinceMoved = 0; } int screenBottom = (int)(screenPos.Y + screenSize.Y); for (int i = keys.Count - 1; i >= 0; i--) { MobileApp app = ModEntry.apps[keys[i]]; Vector2 appPos = PhoneUtils.GetAppPos(i); Rectangle r = new Rectangle(0, 0, Config.IconWidth, Config.IconHeight); Rectangle sourceRect = r; if (!ModEntry.movingAppIcon || i != ModEntry.clickingApp) { if (appPos.Y < screenPos.Y - r.Height * 2 || appPos.Y >= screenBottom) { continue; } if (appPos.Y < screenPos.Y) { int cutTop = (int)screenPos.Y - (int)appPos.Y; sourceRect = new Rectangle(r.X, r.Y + cutTop, r.Width, r.Height - cutTop); appPos = new Vector2(appPos.X, screenPos.Y); } else if (appPos.Y > screenBottom - r.Height) { int cutBottom = screenBottom - r.Height - (int)appPos.Y; sourceRect = new Rectangle(r.X, r.Y, r.Width, r.Height + cutBottom); } } e.SpriteBatch.Draw(app.icon, new Rectangle((int)appPos.X, (int)appPos.Y, sourceRect.Width, sourceRect.Height), sourceRect, Color.White, 0, Vector2.Zero, SpriteEffects.None, i == ModEntry.clickingApp && ModEntry.movingAppIcon ? 1f : 0.5f); Rectangle rect = new Rectangle((int)appPos.X, (int)appPos.Y, Config.IconWidth, sourceRect.Height); if (hover && !Helper.Input.IsSuppressed(SButton.MouseLeft) && rect.Contains(mousePos)) { ModEntry.ticksSinceMoved++; if (ModEntry.ticksSinceMoved > Config.ToolTipDelayTicks) { appHover = app.name; } } } if (appHover != null) { e.SpriteBatch.DrawString(Game1.dialogueFont, appHover, new Vector2(mousePos.X, mousePos.Y) - Game1.dialogueFont.MeasureString(appHover) + new Vector2(-2, 2), Color.Black); e.SpriteBatch.DrawString(Game1.dialogueFont, appHover, new Vector2(mousePos.X, mousePos.Y) - Game1.dialogueFont.MeasureString(appHover), Color.White); } }
private static void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e) { if (ModEntry.callingNPC != null) { return; } if (!ModEntry.appRunning || !ModEntry.phoneOpen || ModEntry.runningApp != Helper.ModRegistry.ModID) { ModEntry.appRunning = false; Helper.Events.Display.RenderedWorld -= Display_RenderedWorld; Helper.Events.Input.ButtonPressed -= Input_ButtonPressed; return; } Vector2 screenPos = PhoneUtils.GetScreenPosition(); Vector2 screenSize = PhoneUtils.GetScreenSize(); Rectangle headerRect = new Rectangle((int)screenPos.X, (int)screenPos.Y, (int)screenSize.X, Config.AppHeaderHeight); Rectangle footerRect = new Rectangle((int)screenPos.X, (int)screenPos.Y + (int)screenSize.Y - Config.AppHeaderHeight, (int)screenSize.X, Config.AppHeaderHeight); Point mousePos = Game1.getMousePosition(); if (Helper.Input.IsSuppressed(SButton.MouseLeft)) { int dy = mousePos.Y - lastMousePositionY; if (Math.Abs(dy) > 0 && ModEntry.screenRect.Contains(mousePos) && !headerRect.Contains(mousePos) && !footerRect.Contains(mousePos)) { dragging = true; } if (dragging) { float listHeight; if (whichTab == 0) { listHeight = skinListHeight; } else if (whichTab == 1) { listHeight = backListHeight; } else { listHeight = ringListHeight; } yOffset = (int)Math.Max(Math.Min(0, yOffset + dy), -1 * Math.Max(0, listHeight - screenSize.Y)); } } if (clicked && !Helper.Input.IsSuppressed(SButton.MouseLeft)) { clicked = false; Monitor.Log($"unclicked"); if (dragging) { Monitor.Log($"was dragging"); dragging = false; } else { if (headerRect.Contains(mousePos)) { if (new Rectangle((int)screenPos.X + (int)screenSize.X - Config.AppHeaderHeight, (int)screenPos.Y, Config.AppHeaderHeight, Config.AppHeaderHeight).Contains(mousePos)) { PhoneUtils.ToggleApp(false); } } else if (footerRect.Contains(mousePos)) { int newTab = (int)((mousePos.X - screenPos.X) / (screenSize.X / 3)); if (whichTab != newTab) { whichTab = newTab; yOffset = 0; int listcount = whichTab == 0 ? skinList.Count : (whichTab == 1 ? backgroundList.Count : ringList.Count); Monitor.Log($"switching to tab {whichTab}: {listcount} items"); } } else { if (whichTab == 0) { for (int i = 0; i < skinList.Count; i++) { Vector2 pos = GetItemPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.ThemeItemWidth, Config.ThemeItemHeight); if (r.Contains(mousePos)) { Monitor.Log($"switching to {skinList[i]}"); SetSkin(skinList[i]); } } } else if (whichTab == 1) { for (int i = 0; i < backgroundList.Count; i++) { Vector2 pos = GetItemPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.ThemeItemWidth, Config.ThemeItemHeight); if (r.Contains(mousePos)) { Monitor.Log($"switching to {backgroundList[i]}"); SetBackground(backgroundList[i]); } } } else if (whichTab == 2) { for (int i = 0; i < ringList.Count; i++) { Vector2 pos = GetItemPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, ModEntry.phoneWidth, Config.RingListItemHeight); if (r.Contains(mousePos)) { Monitor.Log($"switching to {ringList[i]}"); SetRing(ringList[i]); } } } } } } lastMousePositionY = Game1.getMouseY(); int startListY = (int)screenPos.Y + Config.AppHeaderHeight; if (whichTab == 2) { e.SpriteBatch.Draw(ModEntry.ringListBackgroundTexture, ModEntry.screenRect, Color.White); } else { e.SpriteBatch.Draw(ModEntry.backgroundTexture, ModEntry.phoneRect, Color.White); } if (yOffset < 0) { e.SpriteBatch.Draw(ModEntry.upArrowTexture, ModEntry.upArrowPosition, Color.White); } if (yOffset > PhoneUtils.GetScreenSize().Y - Config.AppHeaderHeight - skinListHeight) { e.SpriteBatch.Draw(ModEntry.downArrowTexture, ModEntry.downArrowPosition, Color.White); } int screenBottom = (int)(screenPos.Y + screenSize.Y); int count = whichTab == 0 ? skinList.Count : (whichTab == 1 ? backgroundList.Count : ringList.Count); for (int i = 0; i < count; i++) { Vector2 itemPos = GetItemPos(i); if (whichTab < 2) { Rectangle r = new Rectangle(0, 0, Config.PhoneWidth, Config.PhoneHeight); Rectangle sourceRect = r; Rectangle destRect; destRect = new Rectangle((int)itemPos.X, (int)itemPos.Y, Config.ThemeItemWidth, Config.ThemeItemHeight); float yScale = Config.ThemeItemHeight / (float)Config.PhoneHeight; if (itemPos.Y < startListY - r.Height * yScale || itemPos.Y >= screenBottom) { continue; } int cutTop = 0; int cutBottom = 0; if (itemPos.Y < startListY) { cutTop = (int)Math.Ceiling((startListY - itemPos.Y) / yScale); sourceRect = new Rectangle(r.X, (int)(r.Y + cutTop), r.Width, (int)(r.Height - cutTop)); destRect.Y = startListY; destRect.Height -= (int)(cutTop * yScale); itemPos = new Vector2(itemPos.X, startListY); } else if (itemPos.Y > screenBottom - r.Height * yScale - Config.AppHeaderHeight) { cutBottom = (int)Math.Ceiling((screenBottom - Config.AppHeaderHeight - r.Height * yScale - itemPos.Y) / yScale); destRect.Height += (int)(cutBottom * yScale); sourceRect = new Rectangle(r.X, r.Y, r.Width, r.Height + cutBottom); } Texture2D texture = whichTab == 0 ? skinDict[skinList[i]][0] : backgroundDict[backgroundList[i]][0]; //Monitor.Log($"drawing texture {i} {texture.Width}x{texture.Height} {destRect} {ModEntry.screenRect}"); e.SpriteBatch.Draw(texture, destRect, sourceRect, Color.White); } else { if (itemPos.Y < screenPos.Y || itemPos.Y >= screenBottom - Config.AppHeaderHeight) { continue; } if (ringList[i] == Config.PhoneRingTone) { e.SpriteBatch.Draw(ModEntry.ringListHighlightTexture, new Rectangle((int)(itemPos.X), (int)itemPos.Y, (int)(screenSize.X), Config.RingListItemHeight), Color.White); } string itemName = ringList[i]; if (itemName.Contains(":")) { itemName = itemName.Split(':')[1]; } e.SpriteBatch.DrawString(Game1.dialogueFont, itemName, itemPos, Config.RingListItemColor, 0, Vector2.Zero, Config.RingListItemScale, SpriteEffects.None, 0.86f); } } e.SpriteBatch.Draw(ModEntry.themesHeaderTexture, headerRect, Color.White); e.SpriteBatch.Draw(ModEntry.themesHeaderTexture, footerRect, Color.White); e.SpriteBatch.Draw(ModEntry.themesHighlightTexture, new Rectangle((int)(screenPos.X + (screenSize.X / 3f) * whichTab), screenBottom - Config.AppHeaderHeight, (int)(screenSize.X / 3f), Config.AppHeaderHeight), Color.White); string headerText = Helper.Translation.Get("themes"); string skinsText = Helper.Translation.Get("skins"); string backsText = Helper.Translation.Get("backs"); string ringsText = Helper.Translation.Get("rings"); Vector2 headerTextSize = Game1.dialogueFont.MeasureString(headerText) * Config.HeaderTextScale; Vector2 skinsTextSize = Game1.dialogueFont.MeasureString(skinsText) * Config.TabTextScale; Vector2 backsTextSize = Game1.dialogueFont.MeasureString(backsText) * Config.TabTextScale; Vector2 ringsTextSize = Game1.dialogueFont.MeasureString(ringsText) * Config.TabTextScale; e.SpriteBatch.DrawString(Game1.dialogueFont, headerText, screenPos + new Vector2(screenSize.X / 2f - headerTextSize.X / 2f, Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), Config.PhoneBookHeaderTextColor, 0, Vector2.Zero, Config.HeaderTextScale, SpriteEffects.None, 0.86f); e.SpriteBatch.DrawString(Game1.dialogueFont, "x", screenPos + new Vector2(screenSize.X - Config.AppHeaderHeight / 2f - Game1.dialogueFont.MeasureString("x").X *Config.HeaderTextScale / 2f, Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), Config.PhoneBookHeaderTextColor, 0, Vector2.Zero, Config.HeaderTextScale, SpriteEffects.None, 0.86f); e.SpriteBatch.DrawString(Game1.dialogueFont, skinsText, screenPos + new Vector2(screenSize.X / 6f - skinsTextSize.X / 2f, screenSize.Y - Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), whichTab == 0 ? Config.ThemesHeaderHighlightedTextColor : Config.ThemesHeaderTextColor, 0, Vector2.Zero, Config.TabTextScale, SpriteEffects.None, 0.86f); e.SpriteBatch.DrawString(Game1.dialogueFont, backsText, screenPos + new Vector2(screenSize.X / 2f - backsTextSize.X / 2f, screenSize.Y - Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), whichTab == 1 ? Config.ThemesHeaderHighlightedTextColor : Config.ThemesHeaderTextColor, 0, Vector2.Zero, Config.TabTextScale, SpriteEffects.None, 0.86f); e.SpriteBatch.DrawString(Game1.dialogueFont, ringsText, screenPos + new Vector2(screenSize.X * 5f / 6f - ringsTextSize.X / 2f, screenSize.Y - Config.AppHeaderHeight / 2f - headerTextSize.Y / 2f), whichTab == 2 ? Config.ThemesHeaderHighlightedTextColor : Config.ThemesHeaderTextColor, 0, Vector2.Zero, Config.TabTextScale, SpriteEffects.None, 0.86f); }
public void SetPhoneOpened(bool value) { PhoneUtils.TogglePhone(value); }
public Vector2 GetScreenSize(bool rotated) { return(PhoneUtils.GetScreenSize(rotated)); }
public Vector2 GetScreenSize() { return(PhoneUtils.GetScreenSize()); }
public static void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) { if (!Context.IsWorldReady) { return; } if (Game1.activeClickableMenu == null && ModEntry.phoneOpen && e.Button == SButton.Escape) { PhoneUtils.TogglePhone(); Helper.Input.Suppress(SButton.Escape); return; } if (e.Button == Config.OpenPhoneKey) { PhoneUtils.TogglePhone(); return; } if (e.Button == Config.RotatePhoneKey) { PhoneUtils.RotatePhone(); return; } if (e.Button == SButton.MouseLeft && ModEntry.inCall && Game1.activeClickableMenu?.GetType() == typeof(DialogueBox) && Game1.player.currentLocation?.lastQuestionKey?.StartsWith("PhoneApp_InCall_") == true) { IClickableMenu menu = Game1.activeClickableMenu; int resp = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); if (resp >= 0 && resps != null && resp < resps.Count && resps[resp] != null) { Helper.Input.Suppress(SButton.MouseLeft); Game1.player.currentLocation.lastQuestionKey = ""; Monitor.Log($"clicked on response {resps[resp].responseKey} calling npc: {ModEntry.callingNPC} inCall {ModEntry.inCall}"); MobilePhoneCall.CallDialogueAnswer(resps[resp].responseKey, ModEntry.callingNPC); return; } } Point mousePos = Game1.getMousePosition(); if (!ModEntry.phoneOpen) { if (e.Button == SButton.MouseLeft && Game1.displayHUD && Config.ShowPhoneIcon && new Rectangle((int)ModEntry.phoneIconPosition.X, (int)ModEntry.phoneIconPosition.Y, Config.PhoneIconWidth, Config.PhoneIconHeight).Contains(mousePos)) { Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clickingPhoneIcon = true; ModEntry.draggingPhoneIcon = false; ModEntry.lastMousePosition = mousePos; } return; } if (e.Button == SButton.MouseLeft) { if (Game1.activeClickableMenu == null && !ModEntry.inCall && !ModEntry.appRunning && !ModEntry.phoneRect.Contains(mousePos)) { Monitor.Log($"pressing mouse outside of opened phone"); Helper.Input.Suppress(SButton.MouseLeft); PhoneUtils.TogglePhone(); return; } if (ModEntry.phoneRect.Contains(mousePos) && !ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key on phone border"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; ModEntry.draggingPhone = true; ModEntry.lastMousePosition = mousePos; return; } if (ModEntry.callingNPC != null && ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key in phone while calling"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; return; } if (!ModEntry.appRunning && ModEntry.screenRect.Contains(mousePos)) { Monitor.Log($"pressing mouse key in phone"); Helper.Input.Suppress(SButton.MouseLeft); ModEntry.clicking = true; ModEntry.lastMousePosition = mousePos; for (int i = 0; i < ModEntry.appOrder.Count; i++) { Vector2 pos = PhoneUtils.GetAppPos(i); Rectangle r = new Rectangle((int)pos.X, (int)pos.Y, Config.IconWidth, Config.IconHeight); if (r.Contains(mousePos)) { ModEntry.clickingApp = i; ModEntry.clickingTicks = 0; break; } } } } }
public void PlayRingTone() { PhoneUtils.PlayRingTone(); }
public static void Display_WindowResized(object sender, StardewModdingAPI.Events.WindowResizedEventArgs e) { PhoneUtils.RefreshPhoneLayout(); }
public void PlayNotificationTone() { PhoneUtils.PlayNotificationTone(); }
/// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { context = this; Config = helper.ReadConfig <ModConfig>(); SHelper = helper; if (!Config.EnableMod) { return; } api = (MobilePhoneApi)GetApi(); MobilePhoneApp.Initialize(Helper, Monitor, Config); MobilePhoneCall.Initialize(Helper, Monitor, Config); ThemeApp.Initialize(Helper, Monitor, Config); PhoneVisuals.Initialize(Helper, Monitor, Config); PhoneInput.Initialize(Helper, Monitor, Config); PhoneGameLoop.Initialize(Helper, Monitor, Config); PhoneUtils.Initialize(Helper, Monitor, Config); PhonePatches.Initialize(Helper, Monitor, Config); if (Config.AddRotateApp) { apps.Add(Helper.ModRegistry.ModID + "_Rotate", new MobileApp(helper.Translation.Get("rotate-phone"), null, helper.Content.Load <Texture2D>("assets/rotate_icon.png"))); } var harmony = HarmonyInstance.Create(ModManifest.UniqueID); harmony.Patch( original: AccessTools.Method(typeof(Game1), nameof(Game1.pressSwitchToolButton)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Game1_pressSwitchToolButton_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.endBehaviors)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_endBehaviors_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Farmer), nameof(Farmer.changeFriendship)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Farmer_changeFriendship_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(GameLocation), "resetLocalState"), postfix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.GameLocation_resetLocalState_postfix)) ); harmony.Patch( original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.answerDialogue)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.GameLocation_answerDialogue_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_awardFestivalPrize)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addTool)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addConversationTopic)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addCookingRecipe)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addCraftingRecipe)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_money)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_removeItem)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_friendship)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_dump)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addQuest)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_cutscene)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_cutscene_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.skipEvent)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_skipEvent_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), "namePet"), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_namePet_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(CarpenterMenu), nameof(CarpenterMenu.returnToCarpentryMenu)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.CarpenterMenu_returnToCarpentryMenu_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(CarpenterMenu), nameof(CarpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.CarpenterMenu_returnToCarpentryMenuAfterSuccessfulBuild_prefix)) ); Helper.Events.Input.ButtonPressed += PhoneInput.Input_ButtonPressed; Helper.Events.GameLoop.SaveLoaded += PhoneGameLoop.GameLoop_SaveLoaded; Helper.Events.GameLoop.GameLaunched += PhoneGameLoop.GameLoop_GameLaunched; Helper.Events.GameLoop.ReturnedToTitle += PhoneGameLoop.ReturnedToTitle; Helper.Events.GameLoop.TimeChanged += PhoneGameLoop.GameLoop_TimeChanged; Helper.Events.GameLoop.OneSecondUpdateTicked += PhoneGameLoop.GameLoop_OneSecondUpdateTicked; Helper.Events.Display.WindowResized += PhoneVisuals.Display_WindowResized; /* * var files = Directory.GetFiles(Path.Combine(Helper.DirectoryPath, Path.Combine("assets", "events"))); * foreach(string file in files) * { * Reminiscence r = Helper.Data.ReadJsonFile<Reminiscence>(Path.Combine("assets", Path.Combine("events", Path.GetFileName(file)))); * for(int i = 0; i < r.events.Count; i++) * { * string t = $"{Path.GetFileName(file).Replace(".json", "")}-event-{i}"; * Monitor.Log($"\"{t}\":\"{r.events[i].name}\""); * r.events[i].name = t; * } * Helper.Data.WriteJsonFile(Path.Combine("tmp", Path.GetFileName(file)),r); * } */ }
/// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { context = this; Config = helper.ReadConfig <ModConfig>(); SHelper = helper; if (!Config.EnableMod) { return; } api = (MobilePhoneApi)GetApi(); MobilePhoneApp.Initialize(Helper, Monitor, Config); MobilePhoneCall.Initialize(Helper, Monitor, Config); ThemeApp.Initialize(Helper, Monitor, Config); PhoneVisuals.Initialize(Helper, Monitor, Config); PhoneInput.Initialize(Helper, Monitor, Config); PhoneGameLoop.Initialize(Helper, Monitor, Config); PhoneUtils.Initialize(Helper, Monitor, Config); PhonePatches.Initialize(Helper, Monitor, Config); var harmony = HarmonyInstance.Create(ModManifest.UniqueID); harmony.Patch( original: AccessTools.Method(typeof(Game1), nameof(Game1.pressSwitchToolButton)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Game1_pressSwitchToolButton_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.endBehaviors)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_endBehaviors_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Farmer), nameof(Farmer.changeFriendship)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Farmer_changeFriendship_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(GameLocation), "resetLocalState"), postfix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.GameLocation_resetLocalState_postfix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_awardFestivalPrize)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addTool)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addConversationTopic)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addCookingRecipe)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_addCraftingRecipe)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_money)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_removeItem)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_friendship)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_dump)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), nameof(Event.command_cutscene)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_command_cutscene_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(Event), "namePet"), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.Event_namePet_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(CarpenterMenu), nameof(CarpenterMenu.returnToCarpentryMenu)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.CarpenterMenu_returnToCarpentryMenu_prefix)) ); harmony.Patch( original: AccessTools.Method(typeof(CarpenterMenu), nameof(CarpenterMenu.returnToCarpentryMenuAfterSuccessfulBuild)), prefix: new HarmonyMethod(typeof(PhonePatches), nameof(PhonePatches.CarpenterMenu_returnToCarpentryMenuAfterSuccessfulBuild_prefix)) ); Helper.Events.Input.ButtonPressed += PhoneInput.Input_ButtonPressed; Helper.Events.GameLoop.SaveLoaded += PhoneGameLoop.GameLoop_SaveLoaded; Helper.Events.GameLoop.GameLaunched += PhoneGameLoop.GameLoop_GameLaunched; Helper.Events.GameLoop.ReturnedToTitle += PhoneGameLoop.ReturnedToTitle; Helper.Events.GameLoop.TimeChanged += PhoneGameLoop.GameLoop_TimeChanged; Helper.Events.GameLoop.OneSecondUpdateTicked += PhoneGameLoop.GameLoop_OneSecondUpdateTicked; Helper.Events.Display.WindowResized += PhoneVisuals.Display_WindowResized; }