public WeatherSimulationRegion(WeatherSystemBase ws, int regionX, int regionZ) { this.ws = ws; this.regionX = regionX; this.regionZ = regionZ; int regsize = ws.api.World.BlockAccessor.RegionSize; cloudTilebasePosX = (regionX * regsize) / ws.CloudTileSize; cloudTilebasePosZ = (regionZ * regsize) / ws.CloudTileSize; regionCenterPos = new BlockPos(regionX * regsize + regsize / 2, 0, regionZ * regsize + regsize / 2); Rand = new LCGRandom(ws.api.World.Seed); Rand.InitPositionSeed(regionX / 3, regionZ / 3); weatherData.Ambient = new AmbientModifier().EnsurePopulated(); if (ws.api.Side == EnumAppSide.Client) { capi = ws.api as ICoreClientAPI; weatherData.Ambient.FogColor = capi.Ambient.Base.FogColor.Clone(); } else { wsServer = ws as WeatherSystemServer; } ReloadPatterns(ws.api.World.Seed); }
public WeatherSimulationRegion(WeatherSystemBase ws, int regionX, int regionZ) { this.ws = ws; this.regionX = regionX; this.regionZ = regionZ; this.SnowAccumSnapshots = new RingArray <SnowAccumSnapshot>((int)(ws.api.World.Calendar.DaysPerYear * ws.api.World.Calendar.HoursPerDay) + 1); int regsize = ws.api.World.BlockAccessor.RegionSize; LastUpdateTotalHours = ws.api.World.Calendar.TotalHours; cloudTilebasePosX = (regionX * regsize) / ws.CloudTileSize; cloudTilebasePosZ = (regionZ * regsize) / ws.CloudTileSize; regionCenterPos = new BlockPos(regionX * regsize + regsize / 2, 0, regionZ * regsize + regsize / 2); Rand = new LCGRandom(ws.api.World.Seed); Rand.InitPositionSeed(regionX / 3, regionZ / 3); weatherData.Ambient = new AmbientModifier().EnsurePopulated(); if (ws.api.Side == EnumAppSide.Client) { capi = ws.api as ICoreClientAPI; weatherData.Ambient.FogColor = capi.Ambient.Base.FogColor.Clone(); } else { wsServer = ws as WeatherSystemServer; } ReloadPatterns(ws.api.World.Seed); }
private void rainStopFunc(IServerPlayer player, int groupId, bool skipForward = false) { WeatherSystemServer wsys = api.ModLoader.GetModSystem <WeatherSystemServer>(); if (wsys.OverridePrecipitation != null) { player.SendMessage(groupId, string.Format("Override precipitation set, rain pattern will not change. Fix by typing /weather setprecip auto."), EnumChatType.CommandSuccess); return; } Vec3d pos = player.Entity.Pos.XYZ; float days = 0; float daysrainless = 0f; float firstRainLessDay = 0f; bool found = false; while (days < 21) { float precip = wsys.GetPrecipitation(pos.X, pos.Y, pos.Z, sapi.World.Calendar.TotalDays + days); if (precip < 0.04f) { if (!found) { firstRainLessDay = days; } found = true; daysrainless += 1f / sapi.World.Calendar.HoursPerDay; } else { if (found) { break; } } days += 1f / sapi.World.Calendar.HoursPerDay; } if (daysrainless > 0) { if (skipForward) { wsys.RainCloudDaysOffset += daysrainless; player.SendMessage(groupId, string.Format("Ok, forwarded rain simulation by {0:0.##} days. The rain should stop for about {1:0.##} days now", firstRainLessDay, daysrainless), EnumChatType.CommandSuccess); return; } player.SendMessage(groupId, string.Format("In about {0:0.##} days the rain should stop for about {1:0.##} days", firstRainLessDay, daysrainless), EnumChatType.CommandSuccess); } else { player.SendMessage(groupId, string.Format("No rain less days found for the next 3 in-game weeks :O"), EnumChatType.CommandSuccess); } }
public AiTaskButterflyRest(EntityAgent entity) : base(entity) { (entity.Api as ICoreServerAPI).Event.DidBreakBlock += Event_DidBreakBlock; wsys = entity.Api.ModLoader.GetModSystem <WeatherSystemServer>(); }
private void cmdWeatherServer(IServerPlayer player, int groupId, CmdArgs args) { WeatherSystemServer wsysServer = sapi.ModLoader.GetModSystem <WeatherSystemServer>(); int regionX = (int)player.Entity.Pos.X / sapi.World.BlockAccessor.RegionSize; int regionZ = (int)player.Entity.Pos.Z / sapi.World.BlockAccessor.RegionSize; string arg = args.PopWord(); if (arg == "setprecip") { if (args.Length == 0) { if (wsysServer.OverridePrecipitation == null) { player.SendMessage(groupId, "Currently no precipitation override active.", EnumChatType.CommandSuccess); } else { player.SendMessage(groupId, string.Format("Override precipitation value is currently at {0}.", wsysServer.OverridePrecipitation), EnumChatType.CommandSuccess); } return; } string val = args.PopWord(); if (val == "auto") { wsysServer.OverridePrecipitation = null; player.SendMessage(groupId, "Ok auto precipitation on", EnumChatType.CommandSuccess); } else { float level = val.ToFloat(0); wsysServer.OverridePrecipitation = level; player.SendMessage(groupId, string.Format("Ok precipitation set to {0}", level), EnumChatType.CommandSuccess); } wsysServer.serverChannel.BroadcastPacket(new WeatherConfigPacket() { OverridePrecipitation = wsysServer.OverridePrecipitation, RainCloudDaysOffset = wsysServer.RainCloudDaysOffset }); return; } if (arg == "cloudypos" || arg == "cyp") { if (args.Length == 0) { player.SendMessage(groupId, "Cloud level rel = " + wsysServer.CloudLevelRel, EnumChatType.CommandSuccess); return; } wsysServer.CloudLevelRel = (float)args.PopDouble(0.95f); wsysServer.serverChannel.BroadcastPacket(new WeatherCloudYposPacket() { CloudYRel = wsysServer.CloudLevelRel }); player.SendMessage(groupId, string.Format("Cloud level rel {0:0.##} set. (y={1})", wsysServer.CloudLevelRel, (int)(wsysServer.CloudLevelRel * wsysServer.api.World.BlockAccessor.MapSizeY)), EnumChatType.CommandSuccess); return; } if (arg == "stoprain") { rainStopFunc(player, groupId, true); wsysServer.broadCastConfigUpdate(); return; } if (arg == "acp") { wsysServer.autoChangePatterns = !wsysServer.autoChangePatterns; player.SendMessage(groupId, "Ok autochange weather patterns now " + (wsysServer.autoChangePatterns ? "on" : "off"), EnumChatType.CommandSuccess); return; } if (arg == "lp") { string patterns = string.Join(", ", wsysServer.WeatherConfigs.Select(c => c.Code)); player.SendMessage(groupId, "Patterns: " + patterns, EnumChatType.CommandSuccess); return; } if (arg == "t") { foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.TriggerTransition(); } player.SendMessage(groupId, "Ok transitioning to another weather pattern", EnumChatType.CommandSuccess); return; } if (arg == "c") { foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.TriggerTransition(1f); } player.SendMessage(groupId, "Ok selected another weather pattern", EnumChatType.CommandSuccess); return; } if (arg == "setw") { wsysServer.ReloadConfigs(); string code = args.PopWord(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.ReloadPatterns(api.World.Seed); ok &= val.Value.SetWindPattern(code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such wind pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok wind pattern set", EnumChatType.CommandSuccess); } return; } if (arg == "setev" || arg == "setevr" || arg == "setevf") { wsysServer.ReloadConfigs(); string code = args.PopWord(); WeatherSimulationRegion weatherSim; if (arg == "setevr") { long index2d = wsysServer.MapRegionIndex2D(regionX, regionZ); wsysServer.weatherSimByMapRegion.TryGetValue(index2d, out weatherSim); if (weatherSim == null) { player.SendMessage(groupId, "Weather sim not loaded (yet) for this region", EnumChatType.CommandError); return; } if (weatherSim.SetWeatherEvent(code, true)) { weatherSim.CurWeatherEvent.AllowStop = arg != "setevf"; weatherSim.CurWeatherEvent.OnBeginUse(); weatherSim.TickEvery25ms(0.025f); player.SendMessage(groupId, "Ok weather event for this region set", EnumChatType.CommandSuccess); } else { player.SendMessage(groupId, "No such weather event found", EnumChatType.CommandError); } } else { bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { ok &= val.Value.SetWeatherEvent(code, true); val.Value.CurWeatherEvent.AllowStop = arg != "setevf"; if (ok) { val.Value.CurWeatherEvent.OnBeginUse(); val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such weather event found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok weather event set for all loaded regions", EnumChatType.CommandSuccess); } } return; } if (arg == "set" || arg == "seti") { wsysServer.ReloadConfigs(); string code = args.PopWord(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.ReloadPatterns(api.World.Seed); ok &= val.Value.SetWeatherPattern(code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok weather pattern set for all loaded regions", EnumChatType.CommandSuccess); } return; } if (arg == "setirandom") { wsysServer.ReloadConfigs(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { ok &= val.Value.SetWeatherPattern(val.Value.RandomWeatherPattern().config.Code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok random weather pattern set", EnumChatType.CommandSuccess); } return; } if (arg == "setir") { wsysServer.ReloadConfigs(); string code = args.PopWord(); WeatherSimulationRegion weatherSim; long index2d = wsysServer.MapRegionIndex2D(regionX, regionZ); wsysServer.weatherSimByMapRegion.TryGetValue(index2d, out weatherSim); if (weatherSim == null) { player.SendMessage(groupId, "Weather sim not loaded (yet) for this region", EnumChatType.CommandError); return; } if (weatherSim.SetWeatherPattern(code, true)) { weatherSim.TickEvery25ms(0.025f); player.SendMessage(groupId, "Ok weather pattern set for current region", EnumChatType.CommandSuccess); } else { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } return; } string text = getWeatherInfo <WeatherSystemServer>(player); player.SendMessage(groupId, text, EnumChatType.CommandSuccess); }
private void cmdPrecTestServer(IServerPlayer player, int groupId, CmdArgs args) { WeatherSystemServer wsys = api.ModLoader.GetModSystem <WeatherSystemServer>(); EntityPos pos = player.Entity.Pos; int wdt = 400; float hourStep = 4f; float days = 1f; float posStep = 2f; double totaldays = api.World.Calendar.TotalDays; string subarg = args.PopWord(); bool climateTest = subarg == "climate"; if (subarg == "pos") { float precip = wsys.GetPrecipitation(pos.X, pos.Y, pos.Z, totaldays); player.SendMessage(groupId, "Prec here: " + precip, EnumChatType.CommandSuccess); return; } ClimateCondition conds = api.World.BlockAccessor.GetClimateAt(new BlockPos((int)pos.X, (int)pos.Y, (int)pos.Z), EnumGetClimateMode.WorldGenValues, totaldays); int offset = wdt / 2; Bitmap bmp; int[] pixels; if (subarg == "here") { wdt = 400; bmp = new Bitmap(wdt, wdt, PixelFormat.Format32bppArgb); pixels = new int[wdt * wdt]; posStep = 3f; offset = wdt / 2; for (int dx = 0; dx < wdt; dx++) { for (int dz = 0; dz < wdt; dz++) { float x = dx * posStep - offset; float z = dz * posStep - offset; if ((int)x == 0 && (int)z == 0) { pixels[dz * wdt + dx] = ColorUtil.ColorFromRgba(255, 0, 0, 255); continue; } float precip = wsys.GetPrecipitation(pos.X + x, pos.Y, pos.Z + z, totaldays); int precipi = (int)GameMath.Clamp(255 * precip, 0, 254); pixels[dz * wdt + dx] = ColorUtil.ColorFromRgba(precipi, precipi, precipi, 255); } } bmp.SetPixels(pixels); bmp.Save("preciphere.png"); player.SendMessage(groupId, "Ok exported", EnumChatType.CommandSuccess); return; } bmp = new Bitmap(wdt, wdt, PixelFormat.Format32bppArgb); pixels = new int[wdt * wdt]; using (var gif = AnimatedGif.AnimatedGif.Create("precip.gif", 100, -1)) { for (int i = 0; i < days * 24f; i++) { if (climateTest) { for (int dx = 0; dx < wdt; dx++) { for (int dz = 0; dz < wdt; dz++) { conds.Rainfall = (float)i / (days * 24f); float precip = wsys.GetRainCloudness(conds, pos.X + dx * posStep - offset, pos.Z + dz * posStep - offset, api.World.Calendar.TotalDays); int precipi = (int)GameMath.Clamp(255 * precip, 0, 254); pixels[dz * wdt + dx] = ColorUtil.ColorFromRgba(precipi, precipi, precipi, 255); } } } else { for (int dx = 0; dx < wdt; dx++) { for (int dz = 0; dz < wdt; dz++) { float precip = wsys.GetPrecipitation(pos.X + dx * posStep - offset, pos.Y, pos.Z + dz * posStep - offset, totaldays); int precipi = (int)GameMath.Clamp(255 * precip, 0, 254); pixels[dz * wdt + dx] = ColorUtil.ColorFromRgba(precipi, precipi, precipi, 255); } } } totaldays += hourStep / 24f; bmp.SetPixels(pixels); gif.AddFrame(bmp, 100, GifQuality.Grayscale); } } player.SendMessage(groupId, "Ok exported", EnumChatType.CommandSuccess); }
private void cmdSnowAccum(IServerPlayer player, int groupId, CmdArgs args) { WeatherSystemServer wsys = api.ModLoader.GetModSystem <WeatherSystemServer>(); string cmd = args.PopWord(); if (cmd == "on") { wsys.snowSimSnowAccu.ProcessChunks = true; player.SendMessage(groupId, "Snow accum process chunks on", EnumChatType.CommandSuccess); return; } if (cmd == "off") { wsys.snowSimSnowAccu.ProcessChunks = false; player.SendMessage(groupId, "Snow accum process chunks off", EnumChatType.CommandSuccess); return; } if (cmd == "processhere") { BlockPos plrPos = player.Entity.Pos.AsBlockPos; int chunksize = api.World.BlockAccessor.ChunkSize; Vec2i chunkPos = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize); wsys.snowSimSnowAccu.AddToCheckQueue(chunkPos); player.SendMessage(groupId, "Ok, added to check queue", EnumChatType.CommandSuccess); return; } if (cmd == "info") { BlockPos plrPos = player.Entity.Pos.AsBlockPos; int chunksize = api.World.BlockAccessor.ChunkSize; Vec2i chunkPos = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize); IServerMapChunk mc = sapi.WorldManager.GetMapChunk(chunkPos.X, chunkPos.Y); double lastSnowAccumUpdateTotalHours = mc.GetModdata <double>("lastSnowAccumUpdateTotalHours"); player.SendMessage(groupId, "lastSnowAccumUpdateTotalHours: " + lastSnowAccumUpdateTotalHours, EnumChatType.CommandSuccess); int regionX = (int)player.Entity.Pos.X / sapi.World.BlockAccessor.RegionSize; int regionZ = (int)player.Entity.Pos.Z / sapi.World.BlockAccessor.RegionSize; WeatherSystemServer wsysServer = sapi.ModLoader.GetModSystem <WeatherSystemServer>(); long index2d = wsysServer.MapRegionIndex2D(regionX, regionZ); WeatherSimulationRegion simregion; wsysServer.weatherSimByMapRegion.TryGetValue(index2d, out simregion); int reso = WeatherSimulationRegion.snowAccumResolution; SnowAccumSnapshot sumsnapshot = new SnowAccumSnapshot() { //SumTemperatureByRegionCorner = new API.FloatDataMap3D(reso, reso, reso), SnowAccumulationByRegionCorner = new FloatDataMap3D(reso, reso, reso) }; float[] sumdata = sumsnapshot.SnowAccumulationByRegionCorner.Data; // Can't grow bigger than one full snow block float max = 3 + 0.5f; int len = simregion.SnowAccumSnapshots.Length; int i = simregion.SnowAccumSnapshots.Start; // This code here causes wacky snow patterns // The lerp itself is fine!!! while (len-- > 0) { SnowAccumSnapshot hoursnapshot = simregion.SnowAccumSnapshots[i]; i = (i + 1) % simregion.SnowAccumSnapshots.Length; float[] snowaccumdata = hoursnapshot.SnowAccumulationByRegionCorner.Data; for (int j = 0; j < snowaccumdata.Length; j++) { sumdata[j] = GameMath.Clamp(sumdata[j] + snowaccumdata[j], -max, max); } lastSnowAccumUpdateTotalHours = Math.Max(lastSnowAccumUpdateTotalHours, hoursnapshot.TotalHours); } for (int j = 0; j < sumdata.Length; j++) { player.SendMessage(groupId, j + ": " + sumdata[j], EnumChatType.CommandSuccess); } return; } if (cmd == "here") { float amount = (float)args.PopFloat(0); BlockPos plrPos = player.Entity.Pos.AsBlockPos; int chunksize = api.World.BlockAccessor.ChunkSize; Vec2i chunkPos = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize); IServerMapChunk mc = sapi.WorldManager.GetMapChunk(chunkPos.X, chunkPos.Y); int reso = WeatherSimulationRegion.snowAccumResolution; SnowAccumSnapshot sumsnapshot = new SnowAccumSnapshot() { SumTemperatureByRegionCorner = new FloatDataMap3D(reso, reso, reso), SnowAccumulationByRegionCorner = new FloatDataMap3D(reso, reso, reso) }; sumsnapshot.SnowAccumulationByRegionCorner.Data.Fill(amount); var updatepacket = wsys.snowSimSnowAccu.UpdateSnowLayer(sumsnapshot, true, mc, chunkPos, null); wsys.snowSimSnowAccu.accum = 1f; var ba = sapi.World.GetBlockAccessorBulkMinimalUpdate(true, false); ba.UpdateSnowAccumMap = false; wsys.snowSimSnowAccu.processBlockUpdates(mc, updatepacket, ba); ba.Commit(); player.SendMessage(groupId, "Ok, test snow accum gen complete", EnumChatType.CommandSuccess); return; } }
private void cmdWeatherServer(IServerPlayer player, int groupId, CmdArgs args) { WeatherSystemServer wsysServer = sapi.ModLoader.GetModSystem <WeatherSystemServer>(); int regionX = (int)player.Entity.Pos.X / sapi.World.BlockAccessor.RegionSize; int regionZ = (int)player.Entity.Pos.Z / sapi.World.BlockAccessor.RegionSize; string arg = args.PopWord(); if (arg == "acp") { wsysServer.autoChangePatterns = !wsysServer.autoChangePatterns; player.SendMessage(groupId, "Ok autochange weather patterns now " + (wsysServer.autoChangePatterns ? "on" : "off"), EnumChatType.CommandSuccess); return; } if (arg == "lp") { string patterns = string.Join(", ", wsysServer.weatherConfigs.Select(c => c.Code)); player.SendMessage(groupId, "Patterns: " + patterns, EnumChatType.CommandSuccess); return; } if (arg == "t") { foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.TriggerTransition(); } player.SendMessage(groupId, "Ok transitioning to another weather pattern", EnumChatType.CommandSuccess); return; } if (arg == "c") { foreach (var val in wsysServer.weatherSimByMapRegion) { val.Value.TriggerTransition(1f); } player.SendMessage(groupId, "Ok selected another weather pattern", EnumChatType.CommandSuccess); return; } if (arg == "setw") { wsysServer.ReloadConfigs(); string code = args.PopWord(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { ok &= val.Value.SetWindPattern(code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such wind pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok wind pattern set", EnumChatType.CommandSuccess); } return; } if (arg == "set" || arg == "seti") { wsysServer.ReloadConfigs(); string code = args.PopWord(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { ok &= val.Value.SetWeatherPattern(code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok weather pattern set", EnumChatType.CommandSuccess); } return; } if (arg == "setirandom") { wsysServer.ReloadConfigs(); bool ok = true; foreach (var val in wsysServer.weatherSimByMapRegion) { ok &= val.Value.SetWeatherPattern(val.Value.RandomWeatherPattern().config.Code, true); if (ok) { val.Value.TickEvery25ms(0.025f); } } if (!ok) { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } else { player.SendMessage(groupId, "Ok weather pattern set", EnumChatType.CommandSuccess); } return; } if (arg == "setir") { wsysServer.ReloadConfigs(); string code = args.PopWord(); WeatherSimulationRegion weatherSim; long index2d = wsysServer.MapRegionIndex2D(regionX, regionZ); wsysServer.weatherSimByMapRegion.TryGetValue(index2d, out weatherSim); if (weatherSim == null) { player.SendMessage(groupId, "Weather sim not loaded (yet) for this region", EnumChatType.CommandError); return; } if (weatherSim.SetWeatherPattern(code, true)) { weatherSim.TickEvery25ms(0.025f); player.SendMessage(groupId, "Ok weather pattern set", EnumChatType.CommandSuccess); } else { player.SendMessage(groupId, "No such weather pattern found", EnumChatType.CommandError); } return; } string text = getWeatherInfo <WeatherSystemServer>(player); player.SendMessage(groupId, text, EnumChatType.CommandSuccess); }