public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel) { if (byEntity.World is IClientWorldAccessor) { ModelTransform tf = new ModelTransform(); tf.EnsureDefaultValues(); float nowx = 0, nowy = 0; if (secondsUsed > 0.3f) { int cnt = (int)(secondsUsed * 10); rnd.InitPositionSeed(cnt, 0); float targetx = 3f * (rnd.NextFloat() - 0.5f); float targety = 1.5f * (rnd.NextFloat() - 0.5f); float dt = secondsUsed - prevSecUsed; nowx = (curX - targetx) * dt * 2; nowy = (curY - targety) * dt * 2; } tf.Translation.Set(nowx - Math.Min(1.5f, secondsUsed * 4), nowy, 0); byEntity.Controls.UsingHeldItemTransformBefore = tf; curX = nowx; curY = nowy; prevSecUsed = secondsUsed; } if (api.World.Side == EnumAppSide.Server) { return(true); } return(secondsUsed < 4.6f); }
public override bool TryPlaceBlockForWorldGen(IBlockAccessor blockAccessor, BlockPos pos, BlockFacing onBlockFace, LCGRandom worldgenRandom) { var dBlock = blockAccessor.GetBlock(pos.X, pos.Y - 1, pos.Z); if (dBlock.Fertility <= 20) { return(false); } var climate = blockAccessor.GetClimateAt(pos, EnumGetClimateMode.WorldGenValues); int rnd = worldgenRandom.NextInt(WorldGenConds.Length); int len = WorldGenConds.Length; for (int i = 0; i < len; i++) { var conds = WorldGenConds[(i + rnd) % len]; if (conds.MinTemp <= climate.Temperature && conds.MaxTemp >= climate.Temperature && conds.MinRain <= climate.Rainfall && conds.MaxRain >= climate.Rainfall && worldgenRandom.NextFloat() <= conds.Chance) { blockAccessor.SetBlock(BlockId, pos); blockAccessor.SpawnBlockEntity(EntityClass, pos); var be = blockAccessor.GetBlockEntity(pos) as BlockEntityFruitTreeBranch; be.TreeType = conds.Type; be.InitAfterWorldGen = true; return(true); } } return(false); }
private void CarveTunnel(IServerChunk[] chunks, int chunkX, int chunkZ, double posX, double posY, double posZ, float horAngle, float vertAngle, float horizontalSize, float verticalSize, int currentIteration, int maxIterations, int branchLevel, bool extraBranchy = false, float curviness = 0.1f, bool largeNearLavaLayer = false) { blockId = airBlockId; ushort[] terrainheightmap = chunks[0].MapChunk.WorldGenTerrainHeightMap; ushort[] rainheightmap = chunks[0].MapChunk.RainHeightMap; float horAngleChange = 0; float vertAngleChange = 0; float horRadiusGain = 0; float horRadiusLoss = 0; float horRadiusGainAccum = 0; float horRadiusLossAccum = 0; float verHeightGain = 0; float verHeightLoss = 0; float verHeightGainAccum = 0; float verHeightLossAccum = 0; float sizeChangeSpeedAccum = 0.15f; float sizeChangeSpeedGain = 0f; float relPos; int branchRand = (branchLevel + 1) * (extraBranchy ? 12 : 25); while (currentIteration++ < maxIterations) { relPos = (float)currentIteration / maxIterations; float horRadius = 1.5f + GameMath.FastSin(relPos * GameMath.PI) * horizontalSize + horRadiusGainAccum; horRadius = Math.Min(horRadius, Math.Max(1, horRadius - horRadiusLossAccum)); float vertRadius = 1.5f + GameMath.FastSin(relPos * GameMath.PI) * (verticalSize + horRadiusLossAccum / 4) + verHeightGainAccum; // - horRadiusGainAccum / 2 vertRadius = Math.Min(vertRadius, Math.Max(0.6f, vertRadius - verHeightLossAccum)); float advanceHor = GameMath.FastCos(vertAngle); float advanceVer = GameMath.FastSin(vertAngle); // Caves get bigger near y=12 if (largeNearLavaLayer) { horRadius *= 1 + Math.Max(0, (10 - (float)Math.Abs(posY - 12)) / 10f); vertRadius *= 1 + Math.Max(0, (10 - (float)Math.Abs(posY - 12)) / 10f); } if (vertRadius < 1) { vertAngle *= 0.1f; } posX += GameMath.FastCos(horAngle) * advanceHor; posY += GameMath.Clamp(advanceVer, -vertRadius, vertRadius); posZ += GameMath.FastSin(horAngle) * advanceHor; vertAngle *= 0.8f; if (caveRand.NextInt(80) == 0) { sizeChangeSpeedGain = (caveRand.NextFloat() * caveRand.NextFloat()) / 2; } int rnd = caveRand.NextInt(10000); // Calls to caveRand are not too cheap, so lets just use one for all those random variation changes // 1/330 * 10k = 30 // 1/130 * 10k = 76 // 1/100 * 10k = 100 // 1/120 * 10k = 83 // 1/800 * 10k = 12 // Rarely change direction if ((rnd -= 30) <= 0) { horAngle = caveRand.NextFloat() * GameMath.TWOPI; } else // Rarely change direction somewhat if ((rnd -= 76) <= 0) { horAngle += caveRand.NextFloat() * GameMath.PI - GameMath.PIHALF; } else // Rarely go pretty wide if ((rnd -= 60) <= 0) { horRadiusGain = caveRand.NextFloat() * caveRand.NextFloat() * 3.5f; } else // Rarely go thin if ((rnd -= 60) <= 0) { horRadiusLoss = caveRand.NextFloat() * caveRand.NextFloat() * 10; } else // Rarely go flat if ((rnd -= 50) <= 0) { if (posY < TerraGenConfig.seaLevel - 10) { verHeightLoss = caveRand.NextFloat() * caveRand.NextFloat() * 12; horRadiusGain = Math.Max(horRadiusGain, caveRand.NextFloat() * caveRand.NextFloat() * 3); } } else // Very rarely go really wide if ((rnd -= 9) <= 0) { if (posY < TerraGenConfig.seaLevel - 20) { horRadiusGain = 1 + caveRand.NextFloat() * caveRand.NextFloat() * 5f; } } else // Very rarely go really tall if ((rnd -= 9) <= 0) { verHeightGain = 2 + caveRand.NextFloat() * caveRand.NextFloat() * 7; } else // Rarely large lava caverns if ((rnd -= 100) <= 0) { if (posY < 19) { verHeightGain = 2 + caveRand.NextFloat() * caveRand.NextFloat() * 5; horRadiusGain = 4 + caveRand.NextFloat() * caveRand.NextFloat() * 9; } } sizeChangeSpeedAccum = Math.Max(0.1f, sizeChangeSpeedAccum + sizeChangeSpeedGain * 0.05f); sizeChangeSpeedGain -= 0.02f; horRadiusGainAccum = Math.Max(0, horRadiusGainAccum + horRadiusGain * sizeChangeSpeedAccum); horRadiusGain -= 0.45f; horRadiusLossAccum = Math.Max(0, horRadiusLossAccum + horRadiusLoss * sizeChangeSpeedAccum); horRadiusLoss -= 0.4f; verHeightGainAccum = Math.Max(0, verHeightGainAccum + verHeightGain * sizeChangeSpeedAccum); verHeightGain -= 0.45f; verHeightLossAccum = Math.Max(0, verHeightLossAccum + verHeightLoss * sizeChangeSpeedAccum); verHeightLoss -= 0.4f; horAngle += curviness * horAngleChange; vertAngle += curviness * vertAngleChange; vertAngleChange = 0.9f * vertAngleChange + (caveRand.NextFloat() - caveRand.NextFloat()) * caveRand.NextFloat() * 3; horAngleChange = 0.9f * horAngleChange + (caveRand.NextFloat() - caveRand.NextFloat()) * caveRand.NextFloat() * 1; if (caveRand.NextInt(140) == 0) { horAngleChange *= caveRand.NextFloat() * 6; } // Horizontal branch int brand = branchRand + 2 * Math.Max(0, (int)posY - (TerraGenConfig.seaLevel - 20)); // Lower chance of branches above sealevel because Saraty does not like strongly cut out mountains if ((vertRadius > 1 || horRadius > 1) && branchLevel < 3 && caveRand.NextInt(brand) == 0) { CarveTunnel( chunks, chunkX, chunkZ, posX, posY + verHeightGainAccum / 2, posZ, horAngle + (caveRand.NextFloat() + caveRand.NextFloat() - 1) + GameMath.PI, vertAngle + (caveRand.NextFloat() - 0.5f) * (caveRand.NextFloat() - 0.5f), horizontalSize, verticalSize + verHeightGainAccum, currentIteration, maxIterations - (int)(caveRand.NextFloat() * 0.5 * maxIterations), branchLevel + 1 ); } // Vertical branch if (horRadius > 3 && posY > 60 && branchLevel < 1 && caveRand.NextInt(60) == 0) { CarveShaft( chunks, chunkX, chunkZ, posX, posY + verHeightGainAccum / 2, posZ, horAngle + (caveRand.NextFloat() + caveRand.NextFloat() - 1) + GameMath.PI, -GameMath.PI / 2 - 0.1f + 0.2f * caveRand.NextFloat(), Math.Min(3.5f, horRadius - 1), verticalSize + verHeightGainAccum, currentIteration, maxIterations - (int)(caveRand.NextFloat() * 0.5 * maxIterations) + (int)((posY / 5) * (0.5f + 0.5f * caveRand.NextFloat())), branchLevel ); branchLevel++; } if (horRadius >= 2 && caveRand.NextInt(5) == 0) { continue; } // Check just to prevent unnecessary calculations // As long as we are outside the currently generating chunk, we don't need to generate anything if (posX <= -horRadius * 2 || posX >= chunksize + horRadius * 2 || posZ <= -horRadius * 2 || posZ >= chunksize + horRadius * 2) { continue; } SetBlocks(chunks, horRadius, vertRadius + verHeightGainAccum, posX, posY + verHeightGainAccum / 2, posZ, terrainheightmap, rainheightmap, chunkX, chunkZ); } }
public void TriggerTransition() { TriggerTransition(30 + Rand.NextFloat() * 60 * 60 / ws.api.World.Calendar.SpeedOfTime); }