Talk:Oil of Garlic

From Stardew Valley Wiki
Jump to navigation Jump to search
This talk page is for discussing Oil of Garlic.
  • Sign and date your posts by typing four tildes (~~~~).
  • Put new text below old text.
  • Be polite.
  • Assume good faith.
  • Don't delete discussions.

Effect on Monster Spawning

I was looking at the code, and saw this:

In Locations\MineShaft::adjustLevelChances (systematically called by MineShaft::populateLevel)

bool num = AnyOnlineFarmerHasBuff(23);
flag = AnyOnlineFarmerHasBuff(24);
if (num && getMineArea() != 121)
{
	if (!flag)
	{
		monsterChance = 0.0;
	}
}

23 is Oil of Garlic, 24 is Monster Musk (can be double checked in Buffs.cs)

I don't see any modification to monsterChance after adjustLevelChances() has been called. I guess it would mean using Oil of Garlic (without Monster Musk) remove all monsters in the Mines (not in Skull Cavern, for which getMineArea() == 121).

I checked in-game quickly. I encountered no monster in the Mines, except on "quarry levels" (this is specified in the code right after my excerpt in the same function), and level 91; looking in the game code I don't find why, probably just a bug?

-- Charly (talk) 18:38, 23 November 2021 (UTC)

Well, this is huge! The game didn't used to function this way, I remember thinking Oil of Garlic was pretty much worthless if I was carrying a staircase, because it only prevented swarms/infested levels. I wonder when it changed?
Anyway, thanks for doing the work and for testing in-game. I'm not sure what to report as the bug -- if preventing all monsters in the mines was intended (why wasn't it in the change notes?), or just limiting it to "weak" monsters (not including Haunted Skulls). ??? margotbean (talk) 21:06, 23 November 2021 (UTC)
I looked up in the Forums, Discord, and YouTube trying to have some infos about the Oil of Garlic history, but I couldn't find anything conclusive. There are a lot of references to the wiki page. My guess is the access to the Oil is quite late in the game to people already have reached level 120 in the Mines by that time (and a lot of people just rely on the wiki), so it probably hasn't been tested a lot.
To make myself more clear about the bug thing:
  1. I think the removing of monsters, except for quarry levels (so Haunted Skull and Slimes can spawn in there), is a feature, as it is written clearly and very likely purposely in the code.
  2. More suspicious: Entering level 91 once I got two Shadow mobs (it was a normal lava level). I tried to reproduce this. I went with staircases through the Mines with the Buff, and I encountered one or two mobs very rarely: e.g. 1 Bug in level 3, 1 Green Slime in level 15, 2 Grubs in level 19, 1 Bug in level 39, 1 Shadow Brute on level 94, 1 Red Slime on level 115... (Note that's not just one straight up-to-bottom travel, I made some back-and-forth.)
I dug a bit into that. My first guess following a bug hypothesis was it could be linked to the fact a "lesser or equal" is used in the code to compare with monsterChance, i.e. mineRandom.NextDouble() <= monsterChance. But it would be quite a surprise that a random double between 0 and 1 could equal 0 so often.
So I checked every characters.Add(...) calls in the Locations\MineShaft.cs file to inspect monster spawning processes. (In passing, I can say spawnFlyingMonsterOffScreen() should never trigger when the Buff is active if I'm not mistaken.)
Checking those, I think the rare spawning is due to this chunk of code towards the end of the populateLevel() function, which does not depend on the monsterChance value, and sometimes replace a stone with a mob (if I'm reading it right: for each 35 stones batch on the level, a 1.5 to 3.5 square around one random stone is defined, and each stone in this square, if it is at more than 5 tiles to the elevator or entering ladder, has a 1.2% chance to be turned into a mob). I can't say if the omission of monsterChance check (like != 0) is voluntary or oblivious (could indeed be oblivious in my opinion).
if (stonesLeftOnThisLevel > 35)
{
	int num4 = stonesLeftOnThisLevel / 35;
	for (int l = 0; l < num4; l++)
	{
		Vector2 key2 = objects.Keys.ElementAt(mineRandom.Next(objects.Count()));
		if (!objects[key2].name.Equals("Stone"))
		{
			continue;
		}
		int num5 = mineRandom.Next(3, 8);
		bool flag3 = mineRandom.NextDouble() < 0.1;
		for (int m = (int)key2.X - num5 / 2; (float)m < key2.X + (float)(num5 / 2); m++)
		{
			for (int n = (int)key2.Y - num5 / 2; (float)n < key2.Y + (float)(num5 / 2); n++)
			{
				Vector2 key3 = new Vector2(m, n);
				if (objects.ContainsKey(key3) && objects[key3].name.Equals("Stone"))
				{
					objects.Remove(key3);
					stonesLeftOnThisLevel--;
					if (getDistanceFromStart(m, n) > 5f && flag3 && mineRandom.NextDouble() < 0.12)
					{
						Monster monster3 = BuffMonsterIfNecessary(getMonsterForThisLevel(mineLevel, m, n));
						characters.Add((NPC)monster3);
					}
				}
			}
		}
	}
}
-- Charly (talk) 01:21, 24 November 2021 (UTC)