public static bool Prefix(FarmerRenderer __instance, SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who) { if (AllowOneMethodCall) { AllowOneMethodCall = false; return(true); } try { if (who != null && hitShakeTimers.ContainsKey(who.UniqueMultiplayerID)) { if (hitShakeTimers[who.UniqueMultiplayerID] % 100 < 50) { return(false); } } }catch (Exception) { return(true); } AllowOneMethodCall = true; try { __instance.draw(b, animationFrame, currentFrame, sourceRect, position, origin, layerDepth, facingDirection, overrideColor, rotation, scale, who); } catch (Exception) { } AllowOneMethodCall = false; return(false); }
/********* ** Private methods *********/ /// <summary>The method to call before <see cref="FarmerRenderer.ApplyShoeColor"/>.</summary> /// <returns>Returns whether to run the original method.</returns> private static bool Before_ApplyShoeColor(FarmerRenderer __instance, string texture_name, Color[] pixels) { var this_shoes = Mod.instance.Helper.Reflection.GetField <NetInt>(__instance, "shoes").GetValue(); if (Mod.itemLookup.ContainsKey(this_shoes.Value)) { BootsPackData data = Mod.Find(Mod.itemLookup[this_shoes.Value]) as BootsPackData; var this__SwapColor = Mod.instance.Helper.Reflection.GetMethod(__instance, "_SwapColor"); var currTex = data.pack.GetTexture(data.FarmerColors, 4, 1); int which = this_shoes.Value; Texture2D shoeColors = currTex.Texture; Color[] shoeColorsData = new Color[shoeColors.Width * shoeColors.Height]; shoeColors.GetData(0, currTex.Rect, shoeColorsData, 0, 4); Color darkest = shoeColorsData[0]; Color medium = shoeColorsData[1]; Color lightest = shoeColorsData[2]; Color lightest2 = shoeColorsData[3]; this__SwapColor.Invoke(texture_name, pixels, 268, darkest); this__SwapColor.Invoke(texture_name, pixels, 269, medium); this__SwapColor.Invoke(texture_name, pixels, 270, lightest); this__SwapColor.Invoke(texture_name, pixels, 271, lightest2); return(false); } return(true); }
public static void Prefix(FarmerRenderer __instance, Farmer who, ref Hat __state) { if (!Config.EnableMod || who.hat.Value is null || !who.hat.Value.modData.ContainsKey(seedKey)) { return; } __state = who.hat.Value; who.hat.Value = null; }
/// <summary>The method to call before <see cref="FarmerRenderer.ClampShirt"/>.</summary> /// <returns>Returns whether to run the original method.</returns> private static bool Before_ClampShirt(FarmerRenderer __instance, int shirt_value, ref int __result) { if (Mod.itemLookup.ContainsKey(shirt_value) || Mod.itemLookup.ContainsKey(shirt_value + 1)) { __result = shirt_value; return(false); } return(true); }
/// <summary>The method to call before <see cref="FarmerRenderer.ClampPants"/>.</summary> /// <returns>Returns whether to run the original method.</returns> private static bool Before_ClampPants(FarmerRenderer __instance, int pants_value, ref int __result) { if (Mod.itemLookup.ContainsKey(pants_value)) { __result = pants_value; return(false); } return(true); }
public static bool draw_Prefix(ref FarmerRenderer __instance, SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who, ref PanHat __state) { // Store the hat if it's a pan. if (who.hat.Value != null && who.hat.Value is PanHat panHat) { __state = panHat; } return(true); }
/// <summary>The method to call as a finalized on <see cref="FarmerRenderer.ApplyShoeColor"/>.</summary> private static Exception Finalizer_ApplyShoeColor(Exception __exception, FarmerRenderer __instance) { if (__exception is not null) { var this_shoes = Mod.instance.Helper.Reflection.GetField <NetInt>(__instance, "shoes").GetValue(); Log.Warn($"Detected invalid boots with value {this_shoes.ToString()} and error {__exception}"); __instance.recolorShoes(0); return(null); } return(null); }
public static bool Prefix_doChangeShirt(FarmerRenderer __instance, int whichShirt) { if (whichShirt < 0 && ((whichShirt * -1) - 1) > 0 && ((whichShirt * -1) - 1) < CustomShirtsMod.shirts.Count) { int id = CustomShirtsMod.shirts[(whichShirt * -1) - 1].baseid - 1; CustomShirtsMod._helper.Reflection.GetMethod(__instance, "doChangeShirt").Invoke(new object[] { null, null, id }); return(false); } return(true); }
public static void Postfix(FarmerRenderer __instance, Vector2 ___positionOffset, Hat __state, SpriteBatch b, int facingDirection, Farmer who, Vector2 position, Vector2 origin, float scale, int currentFrame, float rotation, Color overrideColor, float layerDepth) { if (!Config.EnableMod || __state is null) { return; } who.hat.Value = __state; //string phase = who.hat.Value.modData[phaseKey]; //string days = who.hat.Value.modData[daysKey]; bool flip = who.FarmerSprite.CurrentAnimationFrame.flip; float layer_offset = 3.9E-05f; var sourceRect = new Rectangle(Convert.ToInt32(who.hat.Value.modData[xKey]), Convert.ToInt32(who.hat.Value.modData[yKey]), 16, 32); b.Draw(Game1.cropSpriteSheet, position + origin + ___positionOffset + new Vector2((float)(-8 + (flip ? -1 : 1) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4), (float)(-16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + (who.hat.Value.ignoreHairstyleOffset.Value ? 0 : FarmerRenderer.hairstyleHatOffset[who.hair.Value % 16]) + 4 + __instance.heightOffset.Value)) + new Vector2(8, -80), sourceRect, Color.White, rotation, origin, 4f * scale, who.FacingDirection < 2 ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + layer_offset); }
private static bool ApplyShoeColorPrefix(FarmerRenderer __instance, LocalizedContentManager ___farmerTextureManager, Texture2D ___baseTexture, NetInt ___skin, bool ____sickFrame, string texture_name, Color[] pixels) { // Since the game doesn't pass the farmer over to the native ApplyShoeColor method, we have to find it by matching the FarmerRender instance Farmer who = Game1.player; if (who.FarmerRenderer != __instance && Game1.activeClickableMenu is SearchMenu searchMenu && searchMenu is not null) { foreach (var fakeFarmer in searchMenu.fakeFarmers) { if (fakeFarmer.FarmerRenderer == __instance) { who = fakeFarmer; } } } if (!who.modData.ContainsKey(ModDataKeys.UI_HAND_MIRROR_SHOES_COLOR) || !who.modData.ContainsKey(ModDataKeys.CUSTOM_SHOES_ID) || who.modData[ModDataKeys.CUSTOM_SHOES_ID] is null || who.modData[ModDataKeys.CUSTOM_SHOES_ID] == "None") { return(true); }
public static void draw_Postfix(ref FarmerRenderer __instance, SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who, Texture2D ___baseTexture, Vector2 ___positionOffset, ref PanHat __state) { // Draw our updated graphics over the original based on the upgrade level. if (who.UsingTool && who.CurrentTool is Pan pan) { switch (pan.UpgradeLevel) { case 2: sourceRect.Offset(48, 0); break; case 3: sourceRect.Offset(96, 0); break; case 4: sourceRect.Offset(-48, 0); break; default: return; } b.Draw(___baseTexture, position + origin + ___positionOffset + who.armOffset, sourceRect, overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } // Draw updated hat graphics over the original. if (__state != null) { bool flip = who.FarmerSprite.CurrentAnimationFrame.flip; float layer_offset2 = 4.0E-05f; Rectangle hatSourceRect = new Rectangle(20 * (__state.UpgradeLevel - 2), 20 * (__state.UpgradeLevel - 2) / PanHat.panHatTexture.Width * 20 * 4, 20, 20); b.Draw(PanHat.panHatTexture, position + origin + ___positionOffset + new Vector2(-8 + ((!flip) ? 1 : (-1)) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, -16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + ((!__state.ignoreHairstyleOffset) ? FarmerRenderer.hairstyleHatOffset[(int)who.hair % 16] : 0) + 4 + __instance.heightOffset.Value), hatSourceRect, __state.isPrismatic ? Utility.GetPrismaticColor() : Color.White, rotation, origin, 4f * scale, SpriteEffects.None, layerDepth + layer_offset2); //who.hat.Set(__state); } }
public static void Postfix(FarmerRenderer __instance, SpriteBatch b, int facingDirection, Farmer who, Vector2 position, Vector2 origin, float scale, int currentFrame, float rotation, Color overrideColor, float layerDepth, Rectangle ___hatSourceRect, Vector2 ___positionOffset) { if (who.hat.Value != null && !who.bathingClothes.Value) { var hat = who.hat.Value; if (!Mod.GetDataForHat(hat, out Color col, out Texture2D tex)) { return; } var hsr = ___hatSourceRect; hsr.X = 0; hsr.Y = hsr.Y % 80; // Vanilla code bool flip = who.FarmerSprite.CurrentAnimationFrame.flip; float layer_offset = 3.9E-05f + 1E-06f; if (who.hat.Value.isMask && facingDirection == 0) { Rectangle mask_draw_rect = hsr; mask_draw_rect.Height -= 11; mask_draw_rect.Y += 11; //b.Draw(tex, position + origin + ___positionOffset + new Vector2(0f, 44f) + new Vector2(-8 + ((!flip) ? 1 : (-1)) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, -16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + ((!who.hat.Value.ignoreHairstyleOffset) ? FarmerRenderer.hairstyleHatOffset[(int)who.hair % 16] : 0) + 4 + (int)__instance.heightOffset), mask_draw_rect, Color.White, rotation, origin, 4f * scale, SpriteEffects.None, layerDepth + layer_offset); mask_draw_rect = ___hatSourceRect; mask_draw_rect.Height = 11; layer_offset = +1E-06f; b.Draw(tex, position + origin + ___positionOffset + new Vector2(-8 + ((!flip) ? 1 : (-1)) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, -16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + ((!who.hat.Value.ignoreHairstyleOffset) ? FarmerRenderer.hairstyleHatOffset[(int)who.hair % 16] : 0) + 4 + (int)__instance.heightOffset), mask_draw_rect, col, rotation, origin, 4f * scale, SpriteEffects.None, layerDepth + layer_offset); } else { b.Draw(tex, position + origin + ___positionOffset + new Vector2(-8 + ((!flip) ? 1 : (-1)) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, -16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + ((!who.hat.Value.ignoreHairstyleOffset) ? FarmerRenderer.hairstyleHatOffset[(int)who.hair % 16] : 0) + 4 + (int)__instance.heightOffset), hsr, col, rotation, origin, 4f * scale, SpriteEffects.None, layerDepth + layer_offset); } } }
public FarmerRendererWrapper(FarmerRenderer item) => GetBaseType = item;
internal static void DrawPostFix(SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who, FarmerRenderer __instance) { if (ModEntry.EquippedOuterwear == null) { return; } OuterwearData outerwearData = ModEntry.OuterwearData .Where(data => data.DisplayName == ModEntry.EquippedOuterwear.DisplayName) .FirstOrDefault(); // get private member values Vector2 positionOffset = (Vector2)typeof(FarmerRenderer).GetField("positionOffset", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); positionOffset.Y -= 4; Rectangle? sourceRectangle = null; SpriteEffects spriteEffects = SpriteEffects.None; switch (facingDirection) { case 0: positionOffset.Y += 4; sourceRectangle = new Rectangle(0, 64, 16, 32); break; case 1: sourceRectangle = new Rectangle(0, 32, 16, 32); break; case 2: sourceRectangle = new Rectangle(0, 0, 16, 32); break; case 3: sourceRectangle = new Rectangle(0, 32, 16, 32); spriteEffects = SpriteEffects.FlipHorizontally; break; } b.Draw( texture: outerwearData.EquippedTexture, position: position + origin + positionOffset + new Vector2(FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4), sourceRectangle: sourceRectangle, color: Color.White, rotation: rotation, origin: origin, scale: 4f * scale, effects: spriteEffects, layerDepth: layerDepth + 4.9E-04f ); }
/********* ** Internal Methods *********/ /// <summary>The post fix for the <see cref="FarmerRenderer.draw(SpriteBatch, FarmerSprite.AnimationFrame, int, Rectangle, Vector2, Vector2, float, int, Color, float, float, Farmer)"/> method.</summary> /// <param name="b">The sprite batch to draw the outerwear to.</param> /// <param name="animationFrame">The animation frame of the farmer.</param> /// <param name="currentFrame">The current frame of the farmer.</param> /// <param name="sourceRect">The source rectangle of the farmer.</param> /// <param name="position">The position of the farmer.</param> /// <param name="origin">The origin of the farmer.</param> /// <param name="layerDepth">The layer depth of the farmer.</param> /// <param name="facingDirection">The facing direction of the farmer.</param> /// <param name="overrideColor">The override colour of the farmer.</param> /// <param name="rotation">The rotation of the farmer.</param> /// <param name="scale">The scale of the farmer.</param> /// <param name="who">The farmer being drawn.</param> /// <param name="__instance">The current <see cref="FarmerRenderer"/> instance being patched.</param> /// <remarks>This is used to draw the outerwear on the farmer.</remarks> internal static void DrawPostFix(SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who, FarmerRenderer __instance) { // ensure farmer being drawn is wearing some outerwear var objectId = ModEntry.Instance.Api.GetEquippedOuterwearId(who); if (objectId == -1) { return; } // get the outerwear with the specified objectId var outerwearData = ModEntry.Instance.Api.GetOuterwearData(objectId); if (outerwearData == null) { return; } // retrieve private members var positionOffset = (Vector2)typeof(FarmerRenderer).GetField("positionOffset", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); var rotationAdjustment = (Vector2)typeof(FarmerRenderer).GetField("rotationAdjustment", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); // get outerwear type dependant values var drawPosition = Vector2.Zero; var drawSourceRectangle = sourceRect; var drawEffects = SpriteEffects.None; var drawLayerDepth = layerDepth; switch (outerwearData.Type) { case OuterwearType.Shirt: drawPosition = position + origin + positionOffset + new Vector2(16 * scale + FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, 56 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + __instance.heightOffset * scale); drawSourceRectangle = SourceRectangles[OuterwearType.Shirt][facingDirection]; drawLayerDepth = layerDepth + 2.81E-07f; break; case OuterwearType.Accessory: drawPosition = position + origin + positionOffset + rotationAdjustment + new Vector2(FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, 4 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + __instance.heightOffset); drawSourceRectangle = SourceRectangles[OuterwearType.Accessory][facingDirection]; drawEffects = IsFlipped[OuterwearType.Accessory][facingDirection] ? SpriteEffects.FlipHorizontally : SpriteEffects.None; drawLayerDepth = layerDepth + 2.9E-05f; break; case OuterwearType.Hair: drawPosition = position + origin + positionOffset + new Vector2(FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + (facingDirection != 0 ? 4 : 0) + (who.IsMale ? -4 : 0)); drawSourceRectangle = SourceRectangles[OuterwearType.Hair][facingDirection]; drawEffects = IsFlipped[OuterwearType.Hair][facingDirection] ? SpriteEffects.FlipHorizontally : SpriteEffects.None; drawLayerDepth = layerDepth + 2.21E-05f; break; case OuterwearType.Hat: drawPosition = position + origin + positionOffset + new Vector2(-8 + (who.FarmerSprite.CurrentAnimationFrame.flip ? -1 : 1) * FarmerRenderer.featureXOffsetPerFrame[currentFrame] * 4, -16 + FarmerRenderer.featureYOffsetPerFrame[currentFrame] * 4 + 4 + __instance.heightOffset); drawSourceRectangle = SourceRectangles[OuterwearType.Hat][facingDirection]; drawLayerDepth = layerDepth + 3.91E-05f; break; case OuterwearType.Pants: drawPosition = position + origin + positionOffset; drawSourceRectangle = sourceRect; drawEffects = animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None; drawLayerDepth = layerDepth + (who.FarmerSprite.CurrentAnimationFrame.frame == 5 ? 9.9E-04f : 9.9E-08f); break; } // draw outerwear b.Draw( texture: outerwearData.EquippedTexture, position: drawPosition, sourceRectangle: drawSourceRectangle, color: Color.White, rotation: rotation, origin: origin, scale: scale * 4, effects: drawEffects, layerDepth: drawLayerDepth ); }
public static void draw_Postfix(ref FarmerRenderer __instance, SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who, Texture2D ___baseTexture, Vector2 ___positionOffset) { try { if (ModEntry.drawUmbrella) { if (ModEntry.isMaleFarmer) { if (Game1.player.FarmerSprite.currentFrame == 12) { //standing back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -4 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 13 || Game1.player.FarmerSprite.currentFrame == 14 || Game1.player.FarmerSprite.currentFrame == 22 || Game1.player.FarmerSprite.currentFrame == 23) { //moving back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset, new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 113) { //sitting back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -20 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 117) { //sitting side b.Draw(ModEntry.umbrellaOverlayTextureSide, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -20 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 107) { //sitting front b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -24 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } } else { if (Game1.player.FarmerSprite.currentFrame == 12) { //standing back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset, new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 13 || Game1.player.FarmerSprite.currentFrame == 14 || Game1.player.FarmerSprite.currentFrame == 22 || Game1.player.FarmerSprite.currentFrame == 23) { //moving back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, 4 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 113) { //sitting back b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -16 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 117) { //sitting side b.Draw(ModEntry.umbrellaOverlayTextureSide, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -16 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } else if (Game1.player.FarmerSprite.currentFrame == 107) { //sitting front b.Draw(ModEntry.umbrellaOverlayTextureBack, position + origin + ___positionOffset + who.armOffset + new Vector2(0, -20 * scale), new Rectangle(0, 0, 16, 16), overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + 5.0E-05f); } } } } catch (Exception ex) { Monitor.Log($"Failed in {nameof(draw_Postfix)}:\n{ex}", LogLevel.Error); } }
public static void Prefix_drawHairAndAccesories(FarmerRenderer __instance, Farmer who, int facingDirection, Vector2 position, Vector2 origin, float scale, int currentFrame, float rotation, Color overrideColor) { if (Game1.activeClickableMenu is TitleMenu && who.hat.Value is Hat h && !(h is CustomHat) && SaveHandler.getAdditionalSaveData(h) is Dictionary <string, string> savdata) { if (savdata.ContainsKey("blueprint") && savdata["blueprint"] is string bid && CustomShirtsMod.hats.Find(bp => bp.fullid == bid) is HatBlueprint hbp) { who.hat.Value = new CustomHat(hbp); } } if (who.hat.Value is CustomHat c) { if (c.texture == null && CustomShirtsMod.syncedHats.ContainsKey(c.hatId + "." + who.UniqueMultiplayerID)) { c.texture = CustomShirtsMod.syncedHats[c.hatId + "." + who.UniqueMultiplayerID]; } if (c.texture == null && !requestedHatSyncs.Contains(c.hatId + "." + who.UniqueMultiplayerID)) { requestedHatSyncs.Add(c.hatId + "." + who.UniqueMultiplayerID); try { Task.Run(async() => { await PyNet.sendRequestToFarmer <HatSync>(CustomShirtsMod.HatSyncerRequestName, c.hatId, who, (hs) => { requestedHatSyncs.Remove(c.hatId + "." + who.UniqueMultiplayerID); if (hs == null || hs.Texture == null) { return; } if (CustomShirtsMod.syncedHats.ContainsKey(hs.SyncId)) { CustomShirtsMod.syncedHats.Remove(hs.SyncId); } CustomShirtsMod.syncedHats.Add(hs.SyncId, hs.Texture.getTexture()); }, SerializationType.PLAIN, 1000); }); } catch (Exception e) { CustomShirtsMod._monitor.Log(e.Message + ":" + e.StackTrace); } } if (c.texture != null) { int direction = who.FacingDirection; FarmerRenderer.hatsTexture = c.texture; if (direction == 0) { direction = 3; } else if (direction == 2) { direction = 0; } else if (direction == 3) { direction = 2; } if (Game1.activeClickableMenu is TitleMenu || Game1.activeClickableMenu is GameMenu) { direction = 0; } if (c.texture is ScaledTexture2D sct) { sct.ForcedSourceRectangle = new Rectangle(0, (int)(direction * 20 * sct.Scale), (int)(20 * sct.Scale), (int)(20 * sct.Scale)); } } } else { FarmerRenderer.hatsTexture = CustomShirtsMod.vanillaHats; } bool savedShirt = CustomShirtsMod.playerShirts.ContainsKey(who.UniqueMultiplayerID) && CustomShirtsMod.playerBaseShirts.ContainsKey(who.UniqueMultiplayerID) && CustomShirtsMod.playerBaseShirts[who.UniqueMultiplayerID] != -9999; if (savedShirt && (Game1.activeClickableMenu is CharacterCustomization || menuIsCC())) { savedShirt = false; CustomShirtsMod.playerShirts.Remove(who.UniqueMultiplayerID); CustomShirtsMod.playerBaseShirts.Remove(who.UniqueMultiplayerID); who.shirt.Value = ((CustomShirtsMod.shirts.FindIndex(fj => fj.fullid == CustomShirtsMod.config.ShirtId) + 1) * -1); } if (who.shirt.Value >= 0 && !savedShirt) { FarmerRenderer.shirtsTexture = CustomShirtsMod.vanillaShirts; return; } else { try { if (!savedShirt && who == Game1.player) { FarmerRenderer.shirtsTexture = CustomShirtsMod.shirts[(who.shirt.Value * -1) - 1].texture2d; } else { if (CustomShirtsMod.playerShirts[who.UniqueMultiplayerID] == null) { return; } FarmerRenderer.shirtsTexture = CustomShirtsMod.playerShirts[who.UniqueMultiplayerID]; } } catch { } } if (FarmerRenderer.shirtsTexture is ScaledTexture2D st) { st.ForcedSourceRectangle = new Rectangle?(new Rectangle(0, (int)((facingDirection == 0 ? 24 : facingDirection == 1 ? 8 : facingDirection == 3 ? 16 : 0) * st.Scale), (int)(8 * st.Scale), (int)(8 * st.Scale))); } }
/// <summary>The method to call before <see cref="FarmerRenderer.ApplySleeveColor"/>.</summary> /// <returns>Returns whether to run the original method.</returns> private static bool Before_ApplySleeveColor(FarmerRenderer __instance, string texture_name, Color[] pixels, Farmer who) { if (who.shirtItem.Value is CustomShirt shirt) { var this_farmerTextureManager = Mod.instance.Helper.Reflection.GetField <LocalizedContentManager>(__instance, "farmerTextureManager").GetValue(); var this_skin = Mod.instance.Helper.Reflection.GetField <NetInt>(__instance, "skin").GetValue(); bool this__sickFrame = Mod.instance.Helper.Reflection.GetField <bool>(__instance, "_sickFrame").GetValue(); var this_baseTexture = Mod.instance.Helper.Reflection.GetField <Texture2D>(__instance, "baseTexture").GetValue(); var this__SwapColor = Mod.instance.Helper.Reflection.GetMethod(__instance, "_SwapColor"); Color[][] shirtData = new Color[4][] { new Color[8 * 32], new Color[8 * 32], new Color[8 * 32], new Color[8 * 32], };// new Color[FarmerRenderer.shirtsTexture.Bounds.Width * FarmerRenderer.shirtsTexture.Bounds.Height]; foreach (var colors in shirtData) { for (int i = 0; i < colors.Length; i++) { colors[i] = Color.Transparent; } } var maleNC = shirt.Data.pack.GetTexture(shirt.Data.TextureMale, 8, 32); var maleC = shirt.Data.TextureMaleColor == null ? null : shirt.Data.pack.GetTexture(shirt.Data.TextureMaleColor, 8, 32); var femaleNC = shirt.Data.TextureFemale == null ? maleNC : shirt.Data.pack.GetTexture(shirt.Data.TextureFemale, 8, 32); var femaleC = shirt.Data.TextureFemaleColor == null ? null : shirt.Data.pack.GetTexture(shirt.Data.TextureFemaleColor, 8, 32); try { maleNC.Texture.GetData(0, maleNC.Rect, shirtData[0], 0, 8 * 32); maleC?.Texture?.GetData(0, maleNC.Rect, shirtData[1], 0, 8 * 32); femaleNC.Texture.GetData(0, femaleNC.Rect, shirtData[2], 0, 8 * 32); femaleC?.Texture?.GetData(0, maleNC.Rect, shirtData[3], 0, 8 * 32); } catch (Exception ex) { Log.Error($"Failed to apply sleeve color with exception {ex}"); return(false); } //FarmerRenderer.shirtsTexture.GetData( shirtData ); int index = who.IsMale ? 0 : 2; // __instance.ClampShirt(who.GetShirtIndex()) * 8 / 128 * 32 * FarmerRenderer.shirtsTexture.Bounds.Width + __instance.ClampShirt(who.GetShirtIndex()) * 8 % 128 + FarmerRenderer.shirtsTexture.Width * 4; int dye_index = index + 1; Color shirtSleeveColor = Color.White; if (who.GetShirtExtraData().Contains("Sleeveless") || index >= shirtData.Length) { Texture2D skinColors = this_farmerTextureManager.Load <Texture2D>("Characters\\Farmer\\skinColors"); Color[] skinColorsData = new Color[skinColors.Width * skinColors.Height]; int skin_index = this_skin.Value; if (skin_index < 0) { skin_index = skinColors.Height - 1; } if (skin_index > skinColors.Height - 1) { skin_index = 0; } skinColors.GetData(skinColorsData); Color darkest = skinColorsData[skin_index * 3 % (skinColors.Height * 3)]; Color medium = skinColorsData[skin_index * 3 % (skinColors.Height * 3) + 1]; Color lightest = skinColorsData[skin_index * 3 % (skinColors.Height * 3) + 2]; if (this__sickFrame) { darkest = pixels[260 + this_baseTexture.Width]; medium = pixels[261 + this_baseTexture.Width]; lightest = pixels[262 + this_baseTexture.Width]; } shirtSleeveColor = darkest; this__SwapColor.Invoke(texture_name, pixels, 256, darkest); this__SwapColor.Invoke(texture_name, pixels, 257, medium); this__SwapColor.Invoke(texture_name, pixels, 258, lightest); return(false); } Color color = Utility.MakeCompletelyOpaque(who.GetShirtColor()); shirtSleeveColor = shirtData[dye_index][32]; Color clothes_color = color; if (shirtSleeveColor.A < byte.MaxValue) { shirtSleeveColor = shirtData[index][32]; clothes_color = Color.White; } shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothes_color); this__SwapColor.Invoke(texture_name, pixels, 256, shirtSleeveColor); shirtSleeveColor = shirtData[dye_index][24]; if (shirtSleeveColor.A < byte.MaxValue) { shirtSleeveColor = shirtData[index][24]; clothes_color = Color.White; } shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothes_color); this__SwapColor.Invoke(texture_name, pixels, 257, shirtSleeveColor); shirtSleeveColor = shirtData[dye_index][16]; if (shirtSleeveColor.A < byte.MaxValue) { shirtSleeveColor = shirtData[index][16]; clothes_color = Color.White; } shirtSleeveColor = Utility.MultiplyColor(shirtSleeveColor, clothes_color); this__SwapColor.Invoke(texture_name, pixels, 258, shirtSleeveColor); return(false); } return(true); }