Skip to content

Spawn Condition

Rijam edited this page Apr 4, 2024 · 2 revisions

We've set up the basics minimum for our Town NPC, but it won't ever spawn in by itself. We'll need to override the CanTownNPCSpawn() hook to tell the game when it can spawn.

public override bool CanTownNPCSpawn(int numTownNPCs) {
	return true;
}

The above code says that our Town NPC can always arrive as soon as there is a house available. We can add if statements to change the conditions.

public override bool CanTownNPCSpawn(int numTownNPCs) {
	if (NPC.downedBoss1) {
		return true;
	}
	return false;
}

Now the above code says that our Town NPC can only arrive once the Eye of Cthulhu has been defeated (NPC.downedBoss1 corresponds to the Eye of Cthulhu). We don't need an else statement in this case because if the Eye of Cthulhu has not been defeated, the code will return false meaning it cannot spawn.

public override bool CanTownNPCSpawn(int numTownNPCs) {
	if (NPC.AnyNPCs(NPCID.ArmsDealer) && numTownNPCs >= 5 && Main.hardMode) {
		return true;
	}
	return false;
}

This code says that our Town NPC can only arrive if the Arms Dealer is present, there are at least 5 Town NPCs, and the world is in Hardmode.

public override bool CanTownNPCSpawn(int numTownNPCs) {
	// Search through all of the players
	for (int k = 0; k < Main.maxPlayers; k++) {
		Player player = Main.player[k];
		// If the player is not active (disconnected/doesn't exist), continue to the next player.
		if (!player.active) {
			continue;
		}

		// Player has at least 100 maximum mana, return true.
		// statManaMax2 includes the "temporary" mana. This includes accessories/potions/etc. that give extra max mana.
		if (player.statManaMax2 >= 100) {
			return true;
		}
	}
	return false;
}

This final code example says that our Town NPC can arrive if at least one player who is playing has at least 100 maximum mana.

Useful conditions can be found in the Basic NPC Spawning Guide, the NPC Class Documentation, and Player Class Documentation.

Specific Housing Requirements

If you want your Town NPC to only be able to live in specific requirements, like how the Truffle needs to live in a surface mushroom biome, we can override the CheckConditions() hook. If you want your Town NPC to be able to live in any normal house, simply don't include this hook.

public override bool CheckConditions(int left, int right, int top, int bottom) {
	// This code is very similar to how the Truffle checks if it is a surface mushroom biome. In this example, we are checking it is a surface Hallow biome instead.
	
	// If the bottom bound is below the surface height, return false.
	// The code might like the opposite of what you'd expect. That is because positive Y values go down.
	// So if the bottom is greater than the surface height, that means it is deeper in the world.
	if (bottom > Main.worldSurface) {
		return false;
	}

	// We call this function to get the bounds of the "biome". We are going to count how many Hallow blocks are in the area and see if it is enough to count as a Hallow biome.
	WorldGen.Housing_GetTestedRoomBounds(out var startX, out var endX, out var startY, out var endY);
	int score = 0;
	for (int i = startX + 1; i < endX; i++) {
		for (int j = startY + 2; j < endY + 2; j++) {
			Tile tile = Main.tile[i, j];
			// If the tile we are searching is Hallowed Grass, Pearlstone, Pearlsand, Pearlsandstone, Hardened Pearlsand, or Pink Ice, increase the score.
			if (tile.HasTile && (tile.TileType == TileID.HallowedGrass || tile.TileType == TileID.Pearlstone || tile.TileType == TileID.Pearlsand || tile.TileType == TileID.HallowSandstone || tile.TileType == TileID.HallowHardenedSand || tile.TileType == TileID.HallowedIce)) {
				score++;
			}
		}
	}

	// If the score matches the threshold for the biome, return true. In this case, 125 tiles are needed to count as a Hallow biome.
	if (score >= SceneMetrics.HallowTileThreshold) {
		return true;
	}

	return false;
}

In this example, we are checking if the house is in a surface Hallow biome. We make sure the height is correct, then count the number of Hallow tiles in the area to see if it counts as a Hallow biome. Why is this so complex? Why can't we just know what biome the house is in? Generally, only players know which biome they are in. NPCs, even bosses, don't know what biome they are in and base it off of where the player is. More on this in the Shop section.

Rescuable Town NPC

See Intermediate - Rescuable Town NPC



Clone this wiki locally