private void DrawMarkers() { var b = Game1.spriteBatch; var color = Color.White; var offsetMmX = mmX + offset; var offsetMmLoc = new Vector2(mmLoc.X + offset, mmLoc.Y); // // ===== Farm types ===== // // The farms are always overlayed at (0, 43) on the map // The crop position, dimensions, and overlay position must all be adjusted accordingly // When any part of the cropped farm is outside of the minimap as player moves var farmWidth = 131; var farmHeight = 61; var farmX = NormalizeToMap(MathHelper.Clamp(offsetMmLoc.X, offsetMmX, offsetMmX + mmWidth)); var farmY = NormalizeToMap(MathHelper.Clamp(offsetMmLoc.Y + 172, mmY, mmY + mmHeight) + 2); var farmCropX = (int)MathHelper.Clamp((offsetMmX - offsetMmLoc.X) / Game1.pixelZoom, 0, farmWidth); var farmCropY = (int)MathHelper.Clamp((mmY - offsetMmLoc.Y - 172) / Game1.pixelZoom, 0, farmHeight); // Check if farm crop extends outside of minimap var farmCropWidth = (farmX / Game1.pixelZoom + farmWidth > (offsetMmX + mmWidth) / Game1.pixelZoom) ? (int)((offsetMmX + mmWidth - farmX) / Game1.pixelZoom) : farmWidth - farmCropX; var farmCropHeight = (farmY / Game1.pixelZoom + farmHeight > (mmY + mmHeight) / Game1.pixelZoom) ? (int)((mmY + mmHeight - farmY) / Game1.pixelZoom) : farmHeight - farmCropY; // Check if farm crop extends beyond farm size if (farmCropX + farmCropWidth > farmWidth) { farmCropWidth = farmWidth - farmCropX; } if (farmCropY + farmCropHeight > farmHeight) { farmCropHeight = farmHeight - farmCropY; } switch (Game1.whichFarm) { case 1: b.Draw(map, new Vector2(farmX, farmY), new Rectangle(0 + farmCropX, 180 + farmCropY, farmCropWidth, farmCropHeight), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); break; case 2: b.Draw(map, new Vector2(farmX, farmY), new Rectangle(131 + farmCropX, 180 + farmCropY, farmCropWidth, farmCropHeight), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); break; case 3: b.Draw(map, new Vector2(farmX, farmY), new Rectangle(0 + farmCropX, 241 + farmCropY, farmCropWidth, farmCropHeight), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); break; case 4: b.Draw(map, new Vector2(farmX, farmY), new Rectangle(131 + farmCropX, 241 + farmCropY, farmCropWidth, farmCropHeight), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); break; } // // ===== Pam house upgrade ===== // if (drawPamHouseUpgrade) { var pamHouseX = ModConstants.MapVectors["Trailer_Big"][0].MapX; var pamHouseY = ModConstants.MapVectors["Trailer_Big"][0].MapY; if (IsWithinMapArea(pamHouseX, pamHouseY)) { b.Draw(map, new Vector2(NormalizeToMap(offsetMmLoc.X + pamHouseX - 13), NormalizeToMap(offsetMmLoc.Y + pamHouseY - 16)), new Rectangle(263, 181, 8, 8), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); } } // // ===== Farm buildings ===== // if (Config.ShowFarmBuildings && FarmBuildings != null && BuildingMarkers != null) { var sortedBuildings = FarmBuildings.ToList(); sortedBuildings.Sort((x, y) => x.Value.Value.Y.CompareTo(y.Value.Value.Y)); foreach (var building in sortedBuildings) { if (ModConstants.FarmBuildingRects.TryGetValue(building.Value.Key, out var buildingRect)) { if (IsWithinMapArea(building.Value.Value.X - buildingRect.Width / 2, building.Value.Value.Y - buildingRect.Height / 2)) { if (MapName == "starblue_map") { buildingRect.Y = 7; } else if (MapName == "eemie_recolour_map") { buildingRect.Y = 14; } b.Draw( BuildingMarkers, new Vector2( NormalizeToMap(offsetMmLoc.X + building.Value.Value.X - (float)Math.Floor(buildingRect.Width / 2.0)), NormalizeToMap(offsetMmLoc.Y + building.Value.Value.Y - (float)Math.Floor(buildingRect.Height / 2.0)) ), buildingRect, color, 0f, Vector2.Zero, 3f, SpriteEffects.None, 1f ); } } } } // // ===== Custom locations ===== // if (Config.CustomMapMarkers != null && CustomMarkerTex != null) { foreach (var location in Config.CustomMapMarkers) { if (CustomMapLocations.TryGetValue(location.Key, out var locationVector) && Config.CustomMapMarkers.TryGetValue(location.Key, out var locationRects)) { var fromAreaRect = locationRects.GetValue("FromArea"); var toAreaRect = locationRects.GetValue("ToArea"); var srcRect = new Rectangle(fromAreaRect.Value <int>("X"), fromAreaRect.Value <int>("Y"), fromAreaRect.Value <int>("Width"), fromAreaRect.Value <int>("Height")); var locationX = toAreaRect.Value <int>("X"); var locationY = toAreaRect.Value <int>("Y"); // If only one Vector specified, treat it as a marker // Markers are centered based on width/height if (locationVector.Length == 1) { b.Draw( CustomMarkerTex, new Vector2(offsetMmLoc.X + locationX, offsetMmLoc.Y + locationY), srcRect, Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 1f ); } // If more than one Vector, treat it as a region with lower & upper bound // Regions are draw by the top-left corner else if (locationVector.Length > 1) { var regionWidth = srcRect.Width; var regionHeight = srcRect.Height; var regionX = NormalizeToMap(MathHelper.Clamp(offsetMmLoc.X + locationX, offsetMmX, offsetMmX + mmWidth)); var regionY = NormalizeToMap(MathHelper.Clamp(offsetMmLoc.Y + locationY, mmY, mmY + mmHeight) + 2); var regionCropX = (int)MathHelper.Clamp((offsetMmX - offsetMmLoc.X - locationX) / Game1.pixelZoom, 0, farmWidth); var regionCropY = (int)MathHelper.Clamp((mmY - offsetMmLoc.Y - locationY) / Game1.pixelZoom, 0, farmHeight); // Check if region crop extends outside of minimap var regionCropWidth = (regionX / Game1.pixelZoom + regionWidth > (offsetMmX + mmWidth) / Game1.pixelZoom) ? (int)((offsetMmX + mmWidth - regionX) / Game1.pixelZoom) : regionWidth - regionCropX; var regionCropHeight = (regionY / Game1.pixelZoom + regionHeight > (mmY + mmHeight) / Game1.pixelZoom) ? (int)((mmY + mmHeight - regionY) / Game1.pixelZoom) : regionHeight - regionCropY; // Check if region crop extends beyond region size if (regionCropX + regionCropWidth > regionWidth) { regionCropWidth = regionWidth - regionCropX; } if (regionCropY + regionCropHeight > regionHeight) { regionCropHeight = regionHeight - regionCropY; } b.Draw(CustomMarkerTex, new Vector2(regionX, regionY), new Rectangle(srcRect.X + regionCropX, srcRect.Y + regionCropY, regionCropWidth, regionCropHeight), color, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); } } } } // // ===== Traveling Merchant ===== // if (Config.ShowTravelingMerchant && SecondaryNpcs["Merchant"]) { Vector2 merchantLoc = new Vector2(ModConstants.MapVectors["Merchant"][0].MapX, ModConstants.MapVectors["Merchant"][0].MapY); if (IsWithinMapArea(merchantLoc.X - 16, merchantLoc.Y - 16)) { b.Draw(Game1.mouseCursors, new Vector2(NormalizeToMap(offsetMmLoc.X + merchantLoc.X - 16), NormalizeToMap(offsetMmLoc.Y + merchantLoc.Y - 15)), new Rectangle(191, 1410, 22, 21), Color.White, 0f, Vector2.Zero, 1.3f, SpriteEffects.None, 1f); } } if (Context.IsMultiplayer) { foreach (var farmer in Game1.getOnlineFarmers()) { // Temporary solution to handle desync of farmhand location/tile position when changing location if (FarmerMarkers.TryGetValue(farmer.UniqueMultiplayerID, out var farMarker)) { if (farMarker.MapLocation.X < 0) { continue; } if (farMarker.DrawDelay == 0 && IsWithinMapArea(farMarker.MapLocation.X - 16, farMarker.MapLocation.Y - 15)) { farmer.FarmerRenderer.drawMiniPortrat(b, new Vector2(NormalizeToMap(offsetMmLoc.X + farMarker.MapLocation.X - 16), NormalizeToMap(offsetMmLoc.Y + farMarker.MapLocation.Y - 15)), 0.00011f, 2f, 1, farmer); } } } } else { if (playerLoc.X >= 0) { Game1.player.FarmerRenderer.drawMiniPortrat(b, new Vector2(NormalizeToMap(offsetMmLoc.X + playerLoc.X - 16), NormalizeToMap(offsetMmLoc.Y + playerLoc.Y - 15)), 0.00011f, 2f, 1, Game1.player); } } // // ===== NPCs ===== // // Sort by drawing order if (NpcMarkers != null) { var sortedMarkers = NpcMarkers.ToList(); sortedMarkers.Sort((x, y) => x.Layer.CompareTo(y.Layer)); foreach (var npcMarker in sortedMarkers) { // Skip if no specified location if (npcMarker.MapLocation.X < 0 || npcMarker.Marker == null || !MarkerCropOffsets.ContainsKey(npcMarker.Npc.Name) || !IsWithinMapArea(npcMarker.MapLocation.X, npcMarker.MapLocation.Y)) { continue; } var markerColor = npcMarker.IsHidden ? Color.DimGray * 0.7f : Color.White; // Draw NPC marker b.Draw(npcMarker.Marker, new Rectangle(NormalizeToMap(offsetMmLoc.X + npcMarker.MapLocation.X), NormalizeToMap(offsetMmLoc.Y + npcMarker.MapLocation.Y), 30, 32), new Rectangle(0, MarkerCropOffsets[npcMarker.Npc.Name], 16, 15), markerColor); // Icons for birthday/quest if (Config.MarkQuests) { if (npcMarker.IsBirthday) { b.Draw(Game1.mouseCursors, new Vector2(NormalizeToMap(offsetMmLoc.X + npcMarker.MapLocation.X + 20), NormalizeToMap(offsetMmLoc.Y + npcMarker.MapLocation.Y)), new Rectangle(147, 412, 10, 11), markerColor, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } if (npcMarker.HasQuest) { b.Draw(Game1.mouseCursors, new Vector2(NormalizeToMap(offsetMmLoc.X + npcMarker.MapLocation.X + 22), NormalizeToMap(offsetMmLoc.Y + npcMarker.MapLocation.Y - 3)), new Rectangle(403, 496, 5, 14), markerColor, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } } } } }
// Draw event // Subtractions within location vectors are to set the origin to the center of the sprite public void DrawMarkers(SpriteBatch b) { if (Config.ShowFarmBuildings && FarmBuildings != null && BuildingMarkers != null) { var sortedBuildings = FarmBuildings.ToList(); sortedBuildings.Sort((x, y) => x.Value.Value.Y.CompareTo(y.Value.Value.Y)); foreach (KeyValuePair <string, KeyValuePair <string, Vector2> > building in sortedBuildings) { if (ModConstants.FarmBuildingRects.TryGetValue(building.Value.Key, out Rectangle buildingRect)) { if (MapName == "starblue_map") { buildingRect.Y = 7; } else if (MapName == "eemie_recolour_map") { buildingRect.Y = 14; } } b.Draw( BuildingMarkers, new Vector2( mapX + building.Value.Value.X - buildingRect.Width / 2, mapY + building.Value.Value.Y - buildingRect.Height / 2 ), new Rectangle?(buildingRect), Color.White, 0f, Vector2.Zero, 3f, SpriteEffects.None, 1f ); } } // ===== Custom locations ===== if (Config.CustomMapMarkers != null && CustomMarkerTex != null) { foreach (var location in Config.CustomMapMarkers) { if (CustomMapLocations.TryGetValue(location.Key, out var locationVector) && Config.CustomMapMarkers.TryGetValue(location.Key, out var locationRects)) { var fromAreaRect = locationRects.GetValue("FromArea"); var toAreaRect = locationRects.GetValue("ToArea"); var srcRect = new Rectangle(fromAreaRect.Value <int>("X"), fromAreaRect.Value <int>("Y"), fromAreaRect.Value <int>("Width"), fromAreaRect.Value <int>("Height")); b.Draw(CustomMarkerTex, new Vector2(mapX + toAreaRect.Value <int>("X"), mapY + toAreaRect.Value <int>("Y")), srcRect, Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.861f); } } } // Traveling Merchant if (Config.ShowTravelingMerchant && SecondaryNpcs["Merchant"]) { Vector2 merchantLoc = new Vector2(ModConstants.MapVectors["Merchant"][0].MapX, ModConstants.MapVectors["Merchant"][0].MapY); b.Draw(Game1.mouseCursors, new Vector2(mapX + merchantLoc.X - 16, mapY + merchantLoc.Y - 15), new Rectangle?(new Rectangle(191, 1410, 22, 21)), Color.White, 0f, Vector2.Zero, 1.3f, SpriteEffects.None, 1f); } // Farmers if (Context.IsMultiplayer) { foreach (Farmer farmer in Game1.getOnlineFarmers()) { // Temporary solution to handle desync of farmhand location/tile position when changing location if (FarmerMarkers.TryGetValue(farmer.UniqueMultiplayerID, out CharacterMarker farMarker)) { if (farMarker == null || farMarker.MapLocation.X < 0) { continue; } } if (farMarker != null && farMarker.DrawDelay == 0) { farmer.FarmerRenderer.drawMiniPortrat(b, new Vector2(mapX + farMarker.MapLocation.X - 16, mapY + farMarker.MapLocation.Y - 15), 0.00011f, 2f, 1, farmer); } } } else { Vector2 playerLoc = ModMain.LocationToMap(Game1.player.currentLocation.uniqueName.Value ?? Game1.player.currentLocation.Name, Game1.player.getTileX(), Game1.player.getTileY(), CustomMapLocations, true); if (playerLoc.X >= 0) { Game1.player.FarmerRenderer.drawMiniPortrat(b, new Vector2(mapX + playerLoc.X - 16, mapY + playerLoc.Y - 15), 0.00011f, 2f, 1, Game1.player); } } // NPCs // Sort by drawing order if (NpcMarkers != null) { var sortedMarkers = NpcMarkers.ToList(); sortedMarkers.Sort((x, y) => x.Layer.CompareTo(y.Layer)); foreach (CharacterMarker npcMarker in sortedMarkers) { // Skip if no specified location if (npcMarker.MapLocation.X < 0 || npcMarker.Marker == null || !MarkerCropOffsets.ContainsKey(npcMarker.Npc.Name)) { continue; } // Dim marker for hidden markers var markerColor = npcMarker.IsHidden ? Color.DimGray * 0.7f : Color.White; // Draw NPC marker b.Draw(npcMarker.Marker, new Rectangle((int)(mapX + npcMarker.MapLocation.X), (int)(mapY + npcMarker.MapLocation.Y), 32, 30), new Rectangle?(new Rectangle(0, MarkerCropOffsets[npcMarker.Npc.Name], 16, 15)), markerColor); // Draw icons for quests/birthday if (Config.MarkQuests) { if (npcMarker.IsBirthday) { // Gift icon b.Draw(Game1.mouseCursors, new Vector2(mapX + npcMarker.MapLocation.X + 20, mapY + npcMarker.MapLocation.Y), new Rectangle?(new Rectangle(147, 412, 10, 11)), markerColor, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } if (npcMarker.HasQuest) { // Quest icon b.Draw(Game1.mouseCursors, new Vector2(mapX + npcMarker.MapLocation.X + 22, mapY + npcMarker.MapLocation.Y - 3), new Rectangle?(new Rectangle(403, 496, 5, 14)), markerColor, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } } } } }
// Draw event // Subtractions within location vectors are to set the origin to the center of the sprite public void DrawMarkers(SpriteBatch b) { if (Config.ShowFarmBuildings && FarmBuildings != null) { var sortedBuildings = ModMain.FarmBuildings.ToList(); sortedBuildings.Sort((x, y) => x.Value.Value.Y.CompareTo(y.Value.Value.Y)); foreach (KeyValuePair<string, KeyValuePair<string, Vector2>> building in sortedBuildings) { if (ModConstants.FarmBuildingRects.TryGetValue(building.Value.Key, out Rectangle buildingRect)) b.Draw(BuildingMarkers, new Vector2(building.Value.Value.X - buildingRect.Width / 2, building.Value.Value.Y - buildingRect.Height / 2), new Rectangle?(buildingRect), Color.White, 0f, Vector2.Zero, 3f, SpriteEffects.None, 1f); } } // Traveling Merchant if (Config.ShowTravelingMerchant && SecondaryNpcs["Merchant"]) { Vector2 merchantLoc = ModMain.LocationToMap("Forest", 28, 11); b.Draw(Game1.mouseCursors, new Vector2(merchantLoc.X - 16, merchantLoc.Y - 15), new Rectangle?(new Rectangle(191, 1410, 22, 21)), Color.White, 0f, Vector2.Zero, 1.3f, SpriteEffects.None, 1f); } // Farmers if (Context.IsMultiplayer) { foreach (Farmer farmer in Game1.getOnlineFarmers()) { // Temporary solution to handle desync of farmhand location/tile position when changing location if (FarmerMarkers.TryGetValue(farmer.UniqueMultiplayerID, out FarmerMarker farMarker)) if (farMarker.DrawDelay == 0) farmer.FarmerRenderer.drawMiniPortrat(b, new Vector2(farMarker.Location.X - 16, farMarker.Location.Y - 15), 0.00011f, 2f, 1, farmer); } } else { Vector2 playerLoc = ModMain.GetMapPosition(Game1.player.currentLocation, Game1.player.getTileX(), Game1.player.getTileY()); Game1.player.FarmerRenderer.drawMiniPortrat(b, new Vector2(playerLoc.X - 16, playerLoc.Y - 15), 0.00011f, 2f, 1, Game1.player); } // NPCs // Sort by drawing order var sortedMarkers = NpcMarkers.ToList(); sortedMarkers.Sort((x, y) => x.Layer.CompareTo(y.Layer)); foreach (NpcMarker npcMarker in sortedMarkers) { // Skip if no specified location if (npcMarker.Location == Rectangle.Empty || npcMarker.Marker == null || !MarkerCropOffsets.ContainsKey(npcMarker.Npc.Name)) { continue; } // Tint/dim hidden markers if (npcMarker.IsHidden) { b.Draw(npcMarker.Marker, npcMarker.Location, new Rectangle?(new Rectangle(0, MarkerCropOffsets[npcMarker.Npc.Name], 16, 15)), Color.DimGray * 0.7f); if (npcMarker.IsBirthday) { // Gift icon b.Draw(Game1.mouseCursors, new Vector2(npcMarker.Location.X + 20, npcMarker.Location.Y), new Rectangle?(new Rectangle(147, 412, 10, 11)), Color.DimGray * 0.7f, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } if (npcMarker.HasQuest) { // Quest icon b.Draw(Game1.mouseCursors, new Vector2(npcMarker.Location.X + 22, npcMarker.Location.Y - 3), new Rectangle?(new Rectangle(403, 496, 5, 14)), Color.DimGray * 0.7f, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } } else { b.Draw(npcMarker.Marker, npcMarker.Location, new Rectangle?(new Rectangle(0, MarkerCropOffsets[npcMarker.Npc.Name], 16, 15)), Color.White); if (npcMarker.IsBirthday) { // Gift icon b.Draw(Game1.mouseCursors, new Vector2(npcMarker.Location.X + 20, npcMarker.Location.Y), new Rectangle?(new Rectangle(147, 412, 10, 11)), Color.White, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } if (npcMarker.HasQuest) { // Quest icon b.Draw(Game1.mouseCursors, new Vector2(npcMarker.Location.X + 22, npcMarker.Location.Y - 3), new Rectangle?(new Rectangle(403, 496, 5, 14)), Color.White, 0f, Vector2.Zero, 1.8f, SpriteEffects.None, 0f); } } } }