void GenFelnumOre() { string text = "The clouds have been blessed with Felnum."; if (Main.netMode == NetmodeID.SinglePlayer) { Main.NewText(text, Colors.RarityPurple); } else if (Main.netMode == NetmodeID.Server) { NetMessage.BroadcastChatMessage(NetworkText.FromLiteral(text), Colors.RarityPurple); } if (!Main.gameMenu && Main.netMode != NetmodeID.MultiplayerClient) { int x = 0, y = 0; int felnumOre = ModContent.TileType <Felnum_Ore>(); int type; Tile tile; int fails = 0; int success = 0; for (int k = 0; k < (int)((Main.maxTilesX * Main.maxTilesY) * (Main.expertMode?6E-06:4E-06)); k++) { int tries = 0; type = TileID.BlueDungeonBrick; while (type != TileID.Cloud && type != TileID.Dirt && type != TileID.Grass && type != TileID.Stone && type != TileID.RainCloud) { x = WorldGen.genRand.Next(0, Main.maxTilesX); y = WorldGen.genRand.Next(90, (int)OriginWorld.worldSurfaceLow - 5); tile = Framing.GetTileSafely(x, y); type = tile.active()?tile.type:TileID.BlueDungeonBrick; if (++tries >= 150) { if (++fails % 2 == 0) { k--; } success--; type = TileID.Dirt; } } success++; GenRunners.FelnumRunner(x, y, WorldGen.genRand.Next(2, 6), WorldGen.genRand.Next(2, 6), felnumOre); } //Main.NewText($"generation complete, ran {runCount} times with {fails} fails"); } }
void Apply() { switch (mode) { case 0: { GenRunners.VeinRunner( i: (int)p.Dequeue(), j: (int)p.Dequeue(), strength: (double)p.Dequeue(), speed: (Vector2)p.Dequeue(), length: (double)p.Dequeue(), twist: (float)p.Dequeue(), randomtwist: (bool)p.Dequeue()); break; } case 1: { int i = (int)p.Dequeue(); int j = (int)p.Dequeue(); double strength = (double)p.Dequeue(); Vector2 speed = (Vector2)p.Dequeue(); Stack <((Vector2, Vector2), byte)> veins = new Stack <((Vector2, Vector2), byte)>(); double length = (double)p.Dequeue(); float twist = (float)p.Dequeue(); bool twistRand = (bool)p.Dequeue(); veins.Push(((new Vector2(i, j), speed), (p.Count > 0 ? (byte)p.Dequeue() : (byte)10))); ((Vector2 p, Vector2 v)v, byte count)curr; (Vector2 p, Vector2 v)ret; byte count; while (veins.Count > 0) { curr = veins.Pop(); count = curr.count; ret = GenRunners.VeinRunner( i: (int)curr.v.p.X, j: (int)curr.v.p.Y, strength: strength, speed: curr.v.v, length: length, twist: twist, randomtwist: twistRand); if (count > 0 && Main.rand.Next(3) == 0) { veins.Push(((ret.p, ret.v.RotatedBy(Main.rand.NextBool() ? -1 : 1)), (byte)Main.rand.Next(--count))); } if (count > 0) { veins.Push(((ret.p, ret.v.RotatedByRandom(0.05)), --count)); } } break; } case 2: World.BiomeData.RivenHive.Gen.StartHive((int)p.Dequeue(), (int)p.Dequeue()); break; case 3: World.BiomeData.RivenHive.Gen.HiveCave((int)p.Dequeue(), (int)p.Dequeue()); break; case 4: World.BiomeData.BrinePool.Gen.BrineStart((int)p.Dequeue(), (int)p.Dequeue()); break; case 5: World.BiomeData.DefiledWastelands.Gen.StartDefiled((int)p.Dequeue(), (int)p.Dequeue()); break; case 6: { Vector2 a = new Vector2((float)p.Dequeue(), (float)p.Dequeue()); World.BiomeData.DefiledWastelands.Gen.DefiledRibs((int)a.X, (int)a.Y); for (int i = (int)a.X - 1; i < (int)a.X + 3; i++) { for (int j = (int)a.Y - 2; j < (int)a.Y + 2; j++) { Main.tile[i, j].active(false); } } TileObject.CanPlace((int)a.X, (int)a.Y, (ushort)ModContent.TileType <Tiles.Defiled.Defiled_Heart>(), 0, 1, out var data); TileObject.Place(data); break; } } }
public static void StartHive(int i, int j) { const float strength = 2.4f; const float wallThickness = 4f; ushort fleshID = (ushort)ModContent.TileType <Riven_Flesh>(); ushort weakFleshID = (ushort)ModContent.TileType <Weak_Riven_Flesh>(); ushort fleshWallID = (ushort)ModContent.WallType <Riven_Flesh_Wall>(); lesionCount = 0; int j2 = j; if (j2 > Main.worldSurface) { j2 = (int)Main.worldSurface; } for (; !SolidTile(i, j2); j2++) { } Vector2 position = new Vector2(i, j2); for (int x = i - 30; x < i + 30; x++) { for (int y = j2 - 25; y < j2 + 15; y++) { float diff = (((y - j2) * (y - j2) * 1.5f) + (x - i) * (x - i)); if (diff > 800) { continue; } Main.tile[x, y].ResetToType(fleshID); if (diff < 750) { Main.tile[x, y].wall = fleshWallID; } } } Vector2 vector = new Vector2(0, -1).RotatedByRandom(1.6f, genRand); int distance = 0; while (Main.tile[(int)position.X, (int)position.Y].active() && Main.tileSolid[Main.tile[(int)position.X, (int)position.Y].type]) { //Main.tile[(int)position.X, (int)position.Y].ResetToType(TileID.EmeraldGemspark); //SquareTileFrame((int)position.X, (int)position.Y); position += vector; if (++distance >= 160) { break; } } vector = -vector; (Vector2 position, Vector2 velocity)last = (position, vector); //Tile t = Main.tile[(int)last.position.X, (int)last.position.Y]; (int x, int y, Vector2 direction, double length)startValues = ((int)last.position.X, (int)last.position.Y, last.velocity.RotatedByRandom(0.5f, genRand), distance *genRand.NextFloat(0.4f, 0.6f)); last = GenRunners.WalledVeinRunner(startValues.x, startValues.y, strength * genRand.NextFloat(0.9f, 1.1f), startValues.direction, startValues.length, weakFleshID, wallThickness); //t.ResetToType(TileID.AmethystGemspark); Vector2 manualVel = new Vector2(last.velocity.X, 0.2f); //t = Main.tile[(int)last.position.X, (int)last.position.Y]; GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(new Vector2(-manualVel.X, 0.2f)), genRand.NextFloat(distance * 0.4f, distance * 0.6f) * (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); last = GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(manualVel), genRand.NextFloat(distance * 0.4f, distance * 0.6f) / (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(manualVel), genRand.NextFloat(distance * 0.4f, distance * 0.6f) / (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); last = GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), new Vector2(0, 1).RotatedByRandom(0.2f, genRand), genRand.NextFloat(distance * 0.4f, distance * 0.6f), weakFleshID, wallThickness, wallType: fleshWallID); //t.ResetToType(TileID.AmethystGemspark); manualVel.X = -manualVel.X; //t = Main.tile[(int)last.position.X, (int)last.position.Y]; GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(new Vector2(-manualVel.X, 0.2f)), genRand.NextFloat(distance * 0.4f, distance * 0.6f) * (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); last = GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(manualVel), genRand.NextFloat(distance * 0.4f, distance * 0.6f) / (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), Vector2.Normalize(manualVel), genRand.NextFloat(distance * 0.4f, distance * 0.6f) / (Math.Abs(manualVel.X) + 0.5f), weakFleshID, wallThickness, wallType: fleshWallID); last = GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), new Vector2(0, 1).RotatedByRandom(0.2f, genRand), genRand.NextFloat(distance * 0.4f, distance * 0.6f), weakFleshID, wallThickness, wallType: fleshWallID); //t.ResetToType(TileID.AmethystGemspark); for (int index = 0; index < 10; index++) { //t = Main.tile[(int)last.position.X, (int)last.position.Y]; last = GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), last.velocity.RotatedByRandom(0.8f, genRand), genRand.NextFloat(distance * 0.2f, distance * 0.3f), weakFleshID, wallThickness, wallType: fleshWallID); if (index < 8) { GenRunners.WalledVeinRunner((int)last.position.X, (int)last.position.Y, strength * genRand.NextFloat(0.9f, 1.1f), last.velocity.RotatedBy(genRand.Next(2) * 2 - 1).RotatedByRandom(0.8f, genRand), genRand.NextFloat(distance * 0.4f, distance * 0.6f), weakFleshID, wallThickness, wallType: fleshWallID); } PolarVec2 vel = new PolarVec2(1, last.velocity.ToRotation()); OriginExtensions.AngularSmoothing(ref vel.Theta, MathHelper.PiOver2, 0.7f); //t.ResetToType(TileID.AmethystGemspark); last = (last.position, (Vector2)vel); } //t = Main.tile[(int)last.position.X, (int)last.position.Y]; //t.ResetToType(TileID.AmethystGemspark); Point caveCenter = HiveCave((int)last.position.X, (int)last.position.Y); Vector2 cavernOpening = last.position - caveCenter.ToVector2(); GenRunners.VeinRunner((int)last.position.X, (int)last.position.Y, strength, cavernOpening.SafeNormalize(Vector2.Zero), cavernOpening.Length()); GenRunners.VeinRunner(startValues.x, startValues.y, strength, startValues.direction, startValues.length); (Vector2 position, Vector2 velocity)[] arms = new (Vector2 position, Vector2 velocity)[4];
public static Point BrineStart(int i, int j, float sizeMult = 1f) { ushort stoneID = (ushort)ModContent.TileType <Sulphur_Stone>(); ushort stoneWallID = WallID.BlueDungeonSlab; //(ushort)ModContent.WallType<Riven_Flesh_Wall>(); int i2 = i + (int)(genRand.Next(-22, 22) * sizeMult); int j2 = j + (int)(44 * sizeMult); for (int x = i2 - (int)(66 * sizeMult + 10); x < i2 + (int)(66 * sizeMult + 10); x++) { for (int y = j2 + (int)(56 * sizeMult + 8); y >= j2 - (int)(56 * sizeMult + 8); y--) { float j3 = (Math.Min(j2, y) + j2 * 2) / 3f; float sq = Math.Max(Math.Abs(y - j3) * 1.5f, Math.Abs(x - i2)); float pyth = (((y - j3) * (y - j3) * 1.5f) + (x - i2) * (x - i2)); //define the distance between the point and center as a combination of Euclidian distance (dist = sqrt(xdist² + ydist²)) and Chebyshev distance (dist = max(xdist, ydist)) float diff = (float)Math.Sqrt((sq * sq + (pyth * 3)) * 0.25f * (GenRunners.GetWallDistOffset(x) * 0.0316076058772687986171132238548f + 1)); if (diff > 70 * sizeMult) { continue; } switch (Main.tile[x, y].type) { case TileID.IridescentBrick: case TileID.TinBrick: case TileID.GoldBrick: case TileID.Mudstone: if (Main.tileContainer[Main.tile[x, y - 1].type] || genRand.Next(5) > 0) { break; } goto default; case TileID.LivingMahogany: Main.tile[x, y].type = TileID.Ash; break; default: if (Main.tileContainer[Main.tile[x, y].type]) { break; } Main.tile[x, y].ResetToType(stoneID); if (diff < 70 * sizeMult - 10 || ((y - j) * (y - j)) + ((x - i) * (x - i) * 0.5f) < 700 * sizeMult * sizeMult) //(x - i) * { if (Main.tileContainer[Main.tile[x, y - 1].type]) { break; } Main.tile[x, y].active(false); //if (y > j2 - (sizeMult * 32)) { Main.tile[x, y].liquid = 255; //} } break; } switch (Main.tile[x, y].wall) { case WallID.IridescentBrick: case WallID.TinBrick: case WallID.GoldBrick: case WallID.MudstoneBrick: if (genRand.Next(5) == 0) { goto default; } break; default: Main.tile[x, y].wall = stoneWallID; break; } } } int c = 0; float size = 70; int wallSize = 10; Vector2 topLeft = new Vector2(i2, (float)worldSurfaceHigh); Vector2 topRight = new Vector2(i2, (float)worldSurfaceHigh); int minX = int.MaxValue; int maxX = int.MinValue; for (int y = j2 - (int)(50 * sizeMult + 8); y > worldSurfaceLow; y--) { c++; int changed = 0; for (int x = i2 - (int)(66 * sizeMult + 10); x < i2 + (int)(66 * sizeMult + 10); x++) { float j3 = (Math.Min(j2 - c, y) + (j2 - c) * 2) / 3f; float sq = Math.Max(Math.Abs(y - j3) * 1.5f, Math.Abs(x - i2)); float pyth = ((y - j3) * (y - j3) * 1.5f) + (x - i2) * (x - i2); float diff = (float)Math.Sqrt((sq * sq + (pyth * 3)) * 0.25f * (GenRunners.GetWallDistOffset((x > i2?c:-c)) * 0.0105358686257562662057044079516f + 1)); if (diff > size * sizeMult) { continue; } bool change = false; switch (Main.tile[x, y].type) { case TileID.IridescentBrick: case TileID.TinBrick: case TileID.GoldBrick: case TileID.Mudstone: if (Main.tileContainer[Main.tile[x, y - 1].type] || genRand.Next(5) > 0) { break; } goto default; case TileID.LivingMahogany: Main.tile[x, y].type = TileID.Ash; break; default: if (Main.tileContainer[Main.tile[x, y].type]) { break; } if (y > worldSurfaceHigh || (Main.tile[x, y].active() && Main.tileSolid[Main.tile[x, y].type])) { Main.tile[x, y].ResetToType(stoneID); change = true; } if (diff < size * sizeMult - wallSize) //(x - i) * { if (Main.tileContainer[Main.tile[x, y - 1].type]) { break; } if (Main.tile[x, y].active()) { change = true; } Main.tile[x, y].active(false); if (y > worldSurfaceHigh) { Main.tile[x, y].liquid = 255; } } if (y < worldSurfaceHigh && Main.tile[x, y].active() && change) { if (x > i2)//right side { if (x > maxX) { maxX = x; } if (y <= topRight.Y) { topRight = new Vector2(x, y); } } else //left side { if (x < minX) { minX = x; } if (y < topLeft.Y) { topLeft = new Vector2(x, y); } } } break; } switch (Main.tile[x, y].wall) { case WallID.IridescentBrick: case WallID.TinBrick: case WallID.GoldBrick: case WallID.MudstoneBrick: if (genRand.Next(5) == 0) { goto default; } break; default: if (y > worldSurfaceHigh) { Main.tile[x, y].wall = stoneWallID; } break; } if (change) { changed++; } } if (y < worldSurfaceHigh) { size -= 0.03f; } if (changed < 23 * sizeMult + 10) { break; } } int top = (int)Math.Max(topLeft.Y, topRight.Y); float slope = (topLeft.Y - topRight.Y) / (topRight.X - topLeft.X); float minY; int prog = 0; for (int x = minX; x < maxX; x++) { minY = top - slope * prog + GenRunners.GetWallDistOffset(x + top) * 0.4f; if (x >= topLeft.X && x <= topRight.X) { prog++; } for (int y = (int)(worldSurfaceHigh + 1); y >= minY; y--) { Main.tile[x, y].wall = stoneWallID; } } return(new Point(i2, j2)); }
public static (Vector2 position, Vector2 velocity) DefiledVeinRunner(int i, int j, double strength, Vector2 speed, double length, ushort wallBlockType, float wallThickness, float twist = 0, bool randomtwist = false, int wallType = -1) { Vector2 pos = new Vector2(i, j); Tile tile; if (randomtwist) { twist = Math.Abs(twist); } int X0 = int.MaxValue; int X1 = 0; int Y0 = int.MaxValue; int Y1 = 0; double baseStrength = strength; strength = Math.Pow(strength, 2); float basewallThickness = wallThickness; wallThickness *= wallThickness; double decay = speed.Length(); Vector2 direction = speed / (float)decay; bool hasWall = wallType != -1; ushort _wallType = hasWall ? (ushort)wallType : (ushort)0; while (length > 0) { length -= decay; int minX = (int)(pos.X - (strength + wallThickness) * 0.5); int maxX = (int)(pos.X + (strength + wallThickness) * 0.5); int minY = (int)(pos.Y - (strength + wallThickness) * 0.5); int maxY = (int)(pos.Y + (strength + wallThickness) * 0.5); if (minX < 1) { minX = 1; } if (maxX > Main.maxTilesX - 1) { maxX = Main.maxTilesX - 1; } if (minY < 1) { minY = 1; } if (maxY > Main.maxTilesY - 1) { maxY = Main.maxTilesY - 1; } for (int l = minX; l < maxX; l++) { for (int k = minY; k < maxY; k++) { float el = l + (GenRunners.GetWallDistOffset((float)length + k) + 0.5f) / 2.5f; float ek = k + (GenRunners.GetWallDistOffset((float)length + l) + 0.5f) / 2.5f; double dist = Math.Pow(Math.Abs(el - pos.X), 2) + Math.Pow(Math.Abs(ek - pos.Y), 2); tile = Main.tile[l, k]; bool openAir = (k < Main.worldSurface && tile.wall == WallID.None); if (dist > strength) { double d = Math.Sqrt(dist); if (!openAir && d < baseStrength + basewallThickness && TileID.Sets.CanBeClearedDuringGeneration[tile.type] && tile.wall != _wallType) { if (!Main.tileContainer[tile.type]) { tile.active(active: true); tile.ResetToType(wallBlockType); } //WorldGen.SquareTileFrame(l, k); if (hasWall) { tile.wall = _wallType; } } continue; } if (TileID.Sets.CanBeClearedDuringGeneration[tile.type]) { if (!Main.tileContainer[tile.type] && !Main.tileContainer[Main.tile[l, k - 1].type]) { Main.tile[l, k].active(active: false); } //WorldGen.SquareTileFrame(l, k); if (hasWall && !openAir) { tile.wall = _wallType; } if (l > X1) { X1 = l; } else if (l < X0) { X0 = l; } if (k > Y1) { Y1 = k; } else if (k < Y0) { Y0 = k; } } } } pos += speed; if (randomtwist || twist != 0.0) { speed = randomtwist ? speed.RotatedBy(genRand.NextFloat(-twist, twist)) : speed.RotatedBy(twist); } } if (X0 < 1) { X0 = 1; } if (Y0 > Main.maxTilesX - 1) { Y0 = Main.maxTilesX - 1; } if (X1 < 1) { X1 = 1; } if (Y1 > Main.maxTilesY - 1) { Y1 = Main.maxTilesY - 1; } RangeFrame(X0, Y0, X1, Y1); NetMessage.SendTileRange(Main.myPlayer, X0, Y0, X1 - X0, Y1 - Y1); return(pos, speed); }
public static void DefiledRib(float i, float j, float size = 16f, float thickness = 1) { ushort stoneID = (ushort)ModContent.TileType <Defiled_Stone>(); for (int x = (int)Math.Floor(i - size); x < (int)Math.Ceiling(i + size); x++) { for (int y = (int)Math.Ceiling(j + size); y >= (int)Math.Floor(j - size); y--) { if (Main.tile[x, y].active() && Main.tileSolid[Main.tile[x, y].type]) { continue; } float diff = (float)Math.Sqrt((((y - j) * (y - j)) + (x - i) * (x - i)) * (GenRunners.GetWallDistOffset((float)Math.Atan2(y - j, x - i) * 4 + x + y) * 0.0316076058772687986171132238548f + 1)); if (diff > size + thickness || diff < size - thickness) { continue; } Main.tile[x, y].ResetToType(stoneID); } } }
public static void DefiledRibs(float i, float j, float sizeMult = 1f) { ushort stoneID = (ushort)ModContent.TileType <Defiled_Stone>(); for (int x = (int)Math.Floor(i - (28 * sizeMult + 5)); x < (int)Math.Ceiling(i + (28 * sizeMult + 5)); x++) { for (int y = (int)Math.Ceiling(j + (28 * sizeMult + 4)); y >= (int)Math.Floor(j - (28 * sizeMult + 4)); y--) { float diff = (float)Math.Sqrt((((y - j) * (y - j)) + (x - i) * (x - i)) * (GenRunners.GetWallDistOffset((float)Math.Atan2(y - j, x - i) * 4 + x + y) * 0.0316076058772687986171132238548f + 1)); if (diff > 16 * sizeMult) { continue; } if (Math.Cos(diff * 0.7f) <= 0.1f) { Main.tile[x, y].ResetToType(stoneID); } else { Main.tile[x, y].active(false); } } } }