Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TileID.Sets To Let Tiles Be Placed Next to Non-Solid tiles #3684

Merged
merged 5 commits into from
Sep 20, 2023

Conversation

Rijam
Copy link
Contributor

@Rijam Rijam commented Aug 2, 2023

What is the new feature?

Added a new tile ID set TileID.Sets.CanPlaceNextToNonSolidTile[] which allows players to place tiles next to non-solid tiles.

Why should this be part of tModLoader?

By default, you cannot place tiles on non-solid tiles. In vanilla, Player.PlaceThing_Tiles_BlockPlacementForAssortedThings() has an exception for Cobwebs, Coin Piles, Living Fire Blocks, Smoke Blocks, and Bubble Blocks which lets you place them on other non-solid tiles. Since the values are hardcoded, it is extremely difficult to make a non-solid mod tile that behaves in the same way.

Using TileID.Sets.IsBeam[] comes close, but there are still placement differences. Beams can be placed on each other, but they can't be placed on other non-solid tiles. Here is a gif example between Beams and Living Fire:

BeamVsLivingFire

Are there alternative designs?

  • As far as trying to get a mod tile with this placement style, you could mess around with TileObjectData.newTile.HookCheckIfCanPlace, TileObjectData.newTile.UsesCustomCanPlace = true, and making a CanPlace hook. I've tried it and gotten it to do the placement correctly, but it was causing an object reference not set to an instance of an object error on the player when denying the placement (which causes the player's vanity and animations to break). You could instead allow the player to place the tile anywhere (midair), but that is a compromise rather than a real solution.
Old bullet points
  • If anyone thinks of a better name for the set, suggest it. Maybe NonSolidCanPlaceOnNonSolid or NonSolidCanBePlacedOnNonSolid?

  • For the patch. I used /* */ to comment out the vanilla code. I thought putting a // directly on the line made an uglier looking patch. The first example is the patch I committed. Tell me if one is more preferred:

@@ -31729,7 +_,10 @@
 		else if (inventory[selectedItem].createTile == 275 || inventory[selectedItem].createTile == 276 || inventory[selectedItem].createTile == 277) {
 			canPlace = true;
 		}
+		/*
 		else if (inventory[selectedItem].createTile == 51 || inventory[selectedItem].createTile == 330 || inventory[selectedItem].createTile == 331 || inventory[selectedItem].createTile == 332 || inventory[selectedItem].createTile == 333 || inventory[selectedItem].createTile == 336 || inventory[selectedItem].createTile == 340 || inventory[selectedItem].createTile == 342 || inventory[selectedItem].createTile == 341 || inventory[selectedItem].createTile == 343 || inventory[selectedItem].createTile == 344 || inventory[selectedItem].createTile == 379 || inventory[selectedItem].createTile == 351) {
+		*/
+		else if (TileID.Sets.NonSolidCanPlaceOnEachOther[inventory[selectedItem].createTile]) {
 			if (Main.tile[tileTargetX + 1, tileTargetY].active() || Main.tile[tileTargetX + 1, tileTargetY].wall > 0 || Main.tile[tileTargetX - 1, tileTargetY].active() || Main.tile[tileTargetX - 1, tileTargetY].wall > 0 || Main.tile[tileTargetX, tileTargetY + 1].active() || Main.tile[tileTargetX, tileTargetY + 1].wall > 0 || Main.tile[tileTargetX, tileTargetY - 1].active() || Main.tile[tileTargetX, tileTargetY - 1].wall > 0)
 				canPlace = true;
 		}
@@ -32318,7 +_,9 @@
@@ -31729,7 +_,8 @@
 		else if (inventory[selectedItem].createTile == 275 || inventory[selectedItem].createTile == 276 || inventory[selectedItem].createTile == 277) {
 			canPlace = true;
 		}
-		else if (inventory[selectedItem].createTile == 51 || inventory[selectedItem].createTile == 330 || inventory[selectedItem].createTile == 331 || inventory[selectedItem].createTile == 332 || inventory[selectedItem].createTile == 333 || inventory[selectedItem].createTile == 336 || inventory[selectedItem].createTile == 340 || inventory[selectedItem].createTile == 342 || inventory[selectedItem].createTile == 341 || inventory[selectedItem].createTile == 343 || inventory[selectedItem].createTile == 344 || inventory[selectedItem].createTile == 379 || inventory[selectedItem].createTile == 351) {
+		// else if (inventory[selectedItem].createTile == 51 || inventory[selectedItem].createTile == 330 || inventory[selectedItem].createTile == 331 || inventory[selectedItem].createTile == 332 || inventory[selectedItem].createTile == 333 || inventory[selectedItem].createTile == 336 || inventory[selectedItem].createTile == 340 || inventory[selectedItem].createTile == 342 || inventory[selectedItem].createTile == 341 || inventory[selectedItem].createTile == 343 || inventory[selectedItem].createTile == 344 || inventory[selectedItem].createTile == 379 || inventory[selectedItem].createTile == 351) {
+		else if (TileID.Sets.NonSolidCanPlaceOnEachOther[inventory[selectedItem].createTile]) {
 			if (Main.tile[tileTargetX + 1, tileTargetY].active() || Main.tile[tileTargetX + 1, tileTargetY].wall > 0 || Main.tile[tileTargetX - 1, tileTargetY].active() || Main.tile[tileTargetX - 1, tileTargetY].wall > 0 || Main.tile[tileTargetX, tileTargetY + 1].active() || Main.tile[tileTargetX, tileTargetY + 1].wall > 0 || Main.tile[tileTargetX, tileTargetY - 1].active() || Main.tile[tileTargetX, tileTargetY - 1].wall > 0)
 				canPlace = true;
 		}
@@ -32318,7 +_,9 @@

Sample usage for the new feature

Added ExampleLivingFire and ExampleLivingFireTile. See below.

ExampleMod updates

Added ExampleLivingFire and ExampleLivingFireTile.

  • The item defines a static Vector3 for the light color which is used several times instead of re-typing the color values for each spot.
  • The tile showcases the new set as well as moving the drawing down 2 pixels in SetDrawPositions() and animating the tiles with AnimateTile(). (The only difference between ExampleLivingFireTile and the vanilla Living Fire tiles is that the vanilla Living File has a different color for the map and doesn't reuse the light color.)

@JavidPack JavidPack changed the title TileID.Sets To Let Non-Solid Tiles Be Placed On Each Other TileID.Sets To Let Tiles Be Placed Next to Non-Solid tiles Sep 20, 2023
@JavidPack
Copy link
Collaborator

Very good. I ended up renaming it since it doesn't just affect non-solid tiles themselves.

Also, your AnimateIndividualTile code does not animate the tile more randomly than the AnimateTile approach, it just runs the same logic for every tile on screen rather than once for the tile type. To animate more randomly you would need to adjust the frameYOffset using the tile coordinates to have the animation desync from the normal tile animation cycle.

@JavidPack JavidPack merged commit 0a0f59d into tModLoader:1.4.4 Sep 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants