public override void OnBuild(WorldEdit worldEdit, int oldBlockId, BlockSelection blockSel, ItemStack withItemStack) { if (blockDatas == null) { LoadBlockdatas(worldEdit.sapi); } if (blockDatas.Length == 0) { return; } worldEdit.sapi.World.BlockAccessor.SetBlock(oldBlockId, blockSel.Position); BlockSchematic blockData = blockDatas[nextRnd]; nextRnd = rand.Next(blockDatas.Length); BlockPos originPos = blockData.GetStartPos(blockSel.Position, Origin); blockData.Init(blockAccessRev); blockData.Place(blockAccessRev, worldEdit.sapi.World, originPos, ReplaceMode, worldEdit.ReplaceMetaBlocks); blockAccessRev.SetHistoryStateBlock(blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, oldBlockId, blockAccessRev.GetStagedBlockId(blockSel.Position)); blockAccessRev.Commit(); blockData.PlaceEntitiesAndBlockEntities(blockAccessRev, worldEdit.sapi.World, originPos); blockData.PlaceDecors(blockAccessRev, originPos, true); blockAccessRev.CommitBlockEntityData(); if (RandomRotate) { SetRandomAngle(worldEdit.sapi.World); } workspace.ResendBlockHighlights(worldEdit); }
private void ExportArea(string filename, BlockPos start, BlockPos end, IServerPlayer sendToPlayer = null) { BlockSchematic blockdata = CopyArea(start, end); int exported = blockdata.BlockIds.Count; string outfilepath = Path.Combine(exportFolderPath, filename); if (sendToPlayer != null) { serverChannel.SendPacket <SchematicJsonPacket>(new SchematicJsonPacket() { Filename = filename, JsonCode = blockdata.ToJson() }, sendToPlayer); Good(exported + " blocks schematic sent to client."); } else { string error = blockdata.Save(outfilepath); if (error != null) { Good("Failed exporting: " + error); } else { Good(exported + " blocks exported."); } } }
private void HandleRotateCommand(int?maybeangle, string centerarg) { //EnumOrigin origin = (centerarg != null && centerarg.StartsWith("c")) ? EnumOrigin.BottomCenter : EnumOrigin.StartPos; if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Start marker or end marker not set"); return; } int angle = 90; if (maybeangle != null) { if (((int)maybeangle / 90) * 90 != (int)maybeangle) { Bad("Only intervals of 90 degrees are allowed angles"); return; } } EnumOrigin origin = EnumOrigin.BottomCenter; BlockPos mid = (workspace.StartMarker + workspace.EndMarker) / 2; BlockSchematic schematic = CopyArea(workspace.StartMarker, workspace.EndMarker); schematic.TransformWhilePacked(sapi.World, origin, angle, null); FillArea(null, workspace.StartMarker, workspace.EndMarker); PasteBlockData(schematic, mid, origin); ResendBlockHighlights(); }
private void Event_FileDrop(FileDropEvent ev) { FileInfo info = null; long bytes = 0; try { info = new FileInfo(ev.Filename); bytes = info.Length; } catch (Exception ex) { capi.TriggerIngameError(this, "importfailed", string.Format("Unable to import schematic: ", ex)); return; } if (ownWorkspace != null && ownWorkspace.ToolsEnabled && ownWorkspace.ToolName == "Import") { int schematicMaxUploadSizeKb = capi.Settings.Int.Get("schematicMaxUploadSizeKb", 150); // Limit the file size if (bytes / 1024 > schematicMaxUploadSizeKb) { capi.TriggerIngameError(this, "schematictoolarge", Lang.Get("Importing of schematics above {0} KB disabled, adjust config schematicMaxUploadSizeKb to change.", schematicMaxUploadSizeKb)); return; } string err = null; BlockSchematic schematic = BlockSchematic.LoadFromFile(ev.Filename, ref err); if (err != null) { capi.TriggerIngameError(this, "importerror", err); return; } string json = ""; using (TextReader textReader = new StreamReader(ev.Filename)) { json = textReader.ReadToEnd(); textReader.Close(); } if (json.Length < 1024 * 100) { capi.World.Player.ShowChatNotification(Lang.Get("Sending {0} bytes of schematicdata to the server...", json.Length)); } else { capi.World.Player.ShowChatNotification(Lang.Get("Sending {0} bytes of schematicdata to the server, this may take a while...", json.Length)); } capi.Event.RegisterCallback((dt) => { clientChannel.SendPacket <SchematicJsonPacket>(new SchematicJsonPacket() { Filename = info.Name, JsonCode = json }); }, 20); } }
private void ExportArea(string filename, BlockPos start, BlockPos end) { int exported = 0; IBlockAccessor blockAcccessor = api.WorldManager.GetBlockAccessor(false, false, false); BlockPos startPos = new BlockPos(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z)); BlockPos finalPos = new BlockPos(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z)); BlockSchematic blockdata = new BlockSchematic(); for (int x = startPos.X; x < finalPos.X; x++) { for (int y = startPos.Y; y < finalPos.Y; y++) { for (int z = startPos.Z; z < finalPos.Z; z++) { BlockPos pos = new BlockPos(x, y, z); ushort blockid = blockAcccessor.GetBlockId(pos); if (blockid == 0) { continue; } blockdata.BlocksUnpacked[pos] = blockid; exported++; } } } blockdata.Pack(blockAcccessor, startPos); string outfilepath = Path.Combine(exportFolderPath, filename); if (!outfilepath.EndsWith(".json")) { outfilepath += ".json"; } try { using (TextWriter textWriter = new StreamWriter(outfilepath)) { textWriter.Write(JsonConvert.SerializeObject(blockdata, Formatting.None)); textWriter.Close(); } } catch (IOException e) { Good("Failed exporting: " + e.Message); return; } Good(exported + " blocks exported."); }
private BlockSchematic CopyArea(BlockPos start, BlockPos end) { BlockPos startPos = new BlockPos(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z)); BlockPos finalPos = new BlockPos(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z)); BlockSchematic blockdata = new BlockSchematic(); blockdata.AddArea(sapi.World, start, end); blockdata.Pack(sapi.World, startPos); return(blockdata); }
private void ImportArea(string filename, BlockPos startPos, EnumOrigin origin) { string infilepath = Path.Combine(exportFolderPath, filename); if (!File.Exists(infilepath) && File.Exists(infilepath + ".json")) { infilepath += ".json"; } if (!File.Exists(infilepath)) { Bad("Can't import " + filename + ", it does not exist"); return; } BlockSchematic blockdata = null; try { using (TextReader textReader = new StreamReader(infilepath)) { blockdata = JsonConvert.DeserializeObject <BlockSchematic>(textReader.ReadToEnd()); textReader.Close(); } } catch (IOException e) { Good("Failed loading " + filename + " : " + e.Message); return; } BlockPos originPos = startPos.Copy(); if (origin == EnumOrigin.TopCenter) { originPos.X -= blockdata.SizeX / 2; originPos.Y -= blockdata.SizeY; originPos.Z -= blockdata.SizeZ / 2; } if (origin == EnumOrigin.BottomCenter) { originPos.X -= blockdata.SizeX / 2; originPos.Z -= blockdata.SizeZ / 2; } IBlockAccessor blockAcccessor = api.WorldManager.GetBlockAccessorBulkUpdate(true, true, false); blockdata.Place(blockAcccessor, api.World, originPos); blockAcccessor.Commit(); }
private void ImportArea(string filename, BlockPos startPos, EnumOrigin origin) { string infilepath = Path.Combine(exportFolderPath, filename); BlockSchematic blockData; string error = ""; blockData = BlockSchematic.LoadFromFile(infilepath, ref error); if (blockData == null) { Bad(error); return; } PasteBlockData(blockData, startPos, origin); }
/// <summary> /// Creates a new central control panel using a given core /// </summary> public ControlPanel(StreamlineCore core) { Core = core; InitializeComponent(); // Don't show debug if not a dev if (!Core.Settings.DebugMode) { debugToolStripMenuItem.Dispose(); } // Hide the components until something is selected BlockViewer.Hide(); IOBlockViewer.Hide(); // Set up the block editor BlockSchematic.SetCore(Core); BlockSchematic.OnBlockSelected += DetermineViewingComponent; }
public override List <BlockPos> GetBlockHighlights(WorldEdit worldEdit) { if (blockDatas == null) { LoadBlockdatas(worldEdit.sapi, worldEdit); } if (blockDatas.Length == 0) { return(new List <BlockPos>()); } BlockSchematic blockData = blockDatas[nextRnd]; BlockPos origin = blockData.GetStartPos(new BlockPos(), Origin); BlockPos[] pos = blockData.GetJustPositions(origin); return(new List <BlockPos>(pos)); }
private void HandleRotateCommand(int?maybeangle, string centerarg) { //EnumOrigin origin = (centerarg != null && centerarg.StartsWith("c")) ? EnumOrigin.BottomCenter : EnumOrigin.StartPos; if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Start marker or end marker not set"); return; } int angle = 90; if (maybeangle != null) { if (((int)maybeangle / 90) * 90 != (int)maybeangle) { Bad("Only intervals of 90 degrees are allowed angles"); return; } } EnumOrigin origin = EnumOrigin.BottomCenter; BlockPos mid = (workspace.StartMarker + workspace.EndMarker) / 2; mid.Y = workspace.StartMarker.Y; BlockSchematic schematic = CopyArea(workspace.StartMarker, workspace.EndMarker); workspace.revertableBlockAccess.BeginMultiEdit(); schematic.TransformWhilePacked(sapi.World, origin, angle, null); FillArea(null, workspace.StartMarker, workspace.EndMarker); PasteBlockData(schematic, mid, origin); workspace.StartMarker = schematic.GetStartPos(mid, origin); workspace.EndMarker = workspace.StartMarker.AddCopy(schematic.SizeX, schematic.SizeY, schematic.SizeZ); workspace.revertableBlockAccess.EndMultiEdit(); workspace.HighlightSelectedArea(); }
private void PasteBlockData(BlockSchematic blockData, BlockPos startPos, EnumOrigin origin) { BlockPos originPos = blockData.GetStartPos(startPos, origin); EnumAxis?axis = null; if (workspace.ImportFlipped) { axis = EnumAxis.Y; } BlockSchematic rotated = blockData.ClonePacked(); rotated.TransformWhilePacked(sapi.World, origin, workspace.ImportAngle, axis); rotated.Init(workspace.revertableBlockAccess); rotated.Place(workspace.revertableBlockAccess, sapi.World, originPos, EnumReplaceMode.ReplaceAll, ReplaceMetaBlocks); workspace.revertableBlockAccess.Commit(); blockData.PlaceEntitiesAndBlockEntities(workspace.revertableBlockAccess, sapi.World, originPos); }
public void LoadBlockdatas(ICoreServerAPI api, WorldEdit worldEdit = null) { this.blockDatas = new BlockSchematic[0]; if (BlockDataFilenames == null) { return; } string[] filenames = BlockDataFilenames.Split(','); List <BlockSchematic> blockDatas = new List <BlockSchematic>(); string exportFolderPath = api.GetOrCreateDataPath("WorldEdit"); int failed = 0; for (int i = 0; i < filenames.Length; i++) { string infilepath = Path.Combine(exportFolderPath, filenames[i]); string error = ""; BlockSchematic blockData = BlockSchematic.LoadFromFile(infilepath, ref error); if (blockData == null) { worldEdit?.Bad(error); failed++; } else { blockDatas.Add(blockData); } } if (failed > 0) { worldEdit?.Bad(failed + " schematics couldn't be loaded."); } this.blockDatas = blockDatas.ToArray(); }
private void OnReceivedSchematic(IServerPlayer fromPlayer, SchematicJsonPacket networkMessage) { WorldEditWorkspace workspace = GetOrCreateWorkSpace(fromPlayer); if (workspace.ToolsEnabled && workspace.ToolInstance is ImportTool) { ImportTool impTool = workspace.ToolInstance as ImportTool; string error = null; BlockSchematic schematic = BlockSchematic.LoadFromString(networkMessage.JsonCode, ref error); if (error == null) { this.fromPlayer = fromPlayer; impTool.SetBlockDatas(this, new BlockSchematic[] { schematic }); fromPlayer.SendMessage(GlobalConstants.CurrentChatGroup, Lang.Get("Ok, schematic loaded into clipboard."), EnumChatType.CommandSuccess); } else { fromPlayer.SendMessage(GlobalConstants.CurrentChatGroup, Lang.Get("Error loading schematic: {0}", error), EnumChatType.CommandError); } } }
public override void StartServerSide(ICoreServerAPI api) { base.StartServerSide(api); this.sapi = api; api.RegisterCommand("tpimp", ConstantsCore.ModPrefix + "Import teleport schematic", "[list|paste]", (IServerPlayer player, int groupId, CmdArgs args) => { switch (args?.PopWord()) { case "help": player.SendMessage(groupId, "/tpimp [list|paste]", EnumChatType.CommandError); break; case "list": List <IAsset> schematics = api.Assets.GetMany(Constants.TELEPORT_SCHEMATIC_PATH); if (schematics == null || schematics.Count == 0) { player.SendMessage(groupId, Lang.Get("Not found"), EnumChatType.CommandError); break; } StringBuilder list = new StringBuilder(); foreach (var sch in schematics) { list.AppendLine(sch.Name.Remove(sch.Name.Length - 5)); } player.SendMessage(groupId, list.ToString(), EnumChatType.CommandSuccess); break; case "paste": string name = args.PopWord(); if (name == null || name.Length == 0) { player.SendMessage(groupId, "/tpimp paste [name]", EnumChatType.CommandError); break; } IAsset schema = api.Assets.TryGet($"{Constants.TELEPORT_SCHEMATIC_PATH}/{name}.json"); if (schema == null) { player.SendMessage(groupId, Lang.Get("Not found"), EnumChatType.CommandError); break; } string error = null; BlockSchematic schematic = BlockSchematic.LoadFromFile( schema.Origin.OriginPath + "/" + "game" + "/" + schema.Location.Path, ref error); if (error != null) { player.SendMessage(groupId, error, EnumChatType.CommandError); break; } PasteSchematic(schematic, player.Entity.Pos.AsBlockPos.Add(0, -1, 0)); break; default: player.SendMessage(groupId, "/tpimp [list|paste]", EnumChatType.CommandError); break; } }, Privilege.controlserver ); api.RegisterCommand("rndtp", ConstantsCore.ModPrefix + "Teleport player to random location", "[range]", (IServerPlayer player, int groupId, CmdArgs args) => { RandomTeleport(player, (int)args.PopInt(-1)); }, Privilege.tp ); api.RegisterCommand("tpnetconfig", ConstantsCore.ModPrefix + "Config for TPNet", "[shared|unbreakable]", (IServerPlayer player, int groupId, CmdArgs args) => { switch (args?.PopWord()) { case "help": player.SendMessage(groupId, "/tpnetconfig [shared|unbreakable]", EnumChatType.CommandError); break; case "shared": Config.Current.SharedTeleports.Val = !Config.Current.SharedTeleports.Val; api.StoreModConfig <Config>(Config.Current, api.GetWorldId() + "/" + ConstantsCore.ModId); player.SendMessage(groupId, Lang.Get("Shared teleports now is " + (Config.Current.SharedTeleports.Val ? "on" : "off")), EnumChatType.CommandSuccess); break; case "unbreakable": Config.Current.Unbreakable.Val = !Config.Current.Unbreakable.Val; api.StoreModConfig <Config>(Config.Current, api.GetWorldId() + "/" + ConstantsCore.ModId); player.SendMessage(groupId, Lang.Get("Unbreakable teleports now is " + (Config.Current.Unbreakable.Val ? "on" : "off")), EnumChatType.CommandSuccess); break; default: player.SendMessage(groupId, "/tpnetconfig [shared|unbreakable]", EnumChatType.CommandError); break; } }, Privilege.tp ); }
private void PasteSchematic(BlockSchematic blockData, BlockPos startPos, EnumOrigin origin = EnumOrigin.MiddleCenter) { BlockPos originPos = blockData.GetStartPos(startPos, origin); blockData.Place(sapi.World.BlockAccessor, sapi.World, originPos); }