From 0175aded790093b7b61c73be552ab407ff73ceb4 Mon Sep 17 00:00:00 2001 From: David Vierra Date: Tue, 6 Sep 2016 23:53:37 -1000 Subject: [PATCH] Document "Editing Entities" --- doc/plugin_basics.rst | 4 +- doc/plugin_tasks.rst | 85 ++++++++++++++++++++++++++++++++++++++++- doc/plugins/command.rst | 11 ++++-- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/doc/plugin_basics.rst b/doc/plugin_basics.rst index 0f30579..ce80ca9 100644 --- a/doc/plugin_basics.rst +++ b/doc/plugin_basics.rst @@ -25,8 +25,8 @@ installation. Undo History ------------ -NOTE: The following only applies to plugin types other than `SimpleCommandPlugin`. Plugins -derived from `SimpleCommandPlugin` will automatically manage the undo history for you. +NOTE: The following mainly applies to the full-featured `CommandPlugin`. Plugins derived from +`SimpleCommandPlugin` or `BrushMode` will automatically manage the undo history for you. Plugins that edit the world must make it possible for these edits to be undone. This is done by enclosing your editing commands within a call to `editorSession.beginSimpleCommand`. diff --git a/doc/plugin_tasks.rst b/doc/plugin_tasks.rst index cd178d3..13d8d84 100644 --- a/doc/plugin_tasks.rst +++ b/doc/plugin_tasks.rst @@ -36,6 +36,89 @@ use the string of text, for both readability and for compatibility. NOTE: When using block types added by mods, you *must* use the text identifier, because the integer IDs will vary from world to world. +Alternately, you may pass a BlockType instance. A BlockType instance may be obtained +by presenting a block type input to the user (e.g. using an option with `type="blocktype"` +in a `SimpleCommandPlugin` or by constructing a `BlockTypeButton` yourself). BlockTypes +may also be found by looking up a textual or numeric ID in the dimension's `blocktypes`. +To wit:: + + stone = dimension.blocktypes['minecraft:stone'] + granite = dimension.blocktypes['minecraft:stone[variant=granite]'] + cobblestone = dimension.blocktypes[1] # don't do this! + podzol = dimension.blocktypes[3, 2] # don't do this either! + + dimension.setBlock(0, 0, 0, granite) # etc. + +To discover which block is at a given position, call `dimension.getBlock`, which will return +a `BlockType` instance. + +.. automethod:: mceditlib.worldeditor.WorldEditorDimension.getBlock + To change the block at a given position, call `dimension.setBlock` -.. automethod:: mceditlib.worldeditor.WorldEditorDimension.setBlock \ No newline at end of file +.. automethod:: mceditlib.worldeditor.WorldEditorDimension.setBlock + +Array-based, high performance variants of these two methods are available. When given +parallel arrays of x, y, z coordinates, `dimension.getBlocks` will return an array of the +same size containing the block IDs at those coordinates. If requested, it will also return +the block metadata values, light values, and/or biome values for those coordinates at the +same time. + +Likewise, `dimension.setBlocks` may be given parallel arrays of x, y, z coordinates along +with arrays of any of the following: block IDs, block metadata values, light values, +biome values. To set all coordinates to the same value, you may pass a single value +instead of an array. + +.. automethod:: mceditlib.worldeditor.WorldEditorDimension.getBlocks +.. automethod:: mceditlib.worldeditor.WorldEditorDimension.setBlocks + +Editing Entities +---------------- + +Entities are the free-roaming elements of a Minecraft world. They are not bound to the +block grid, they may be present at any position in the world, and may even overlap. Animals, +monsters, items, and experience orbs are examples of entities. + +Since entities may be at any position, you cannot specify an entity with a single x, y, z +coordinate triple. Instead, you may create a BoundingBox (or any other SelectionBox object) +and ask MCEdit to find all of the entities within it. You may even ask it to find only +the entities which have specific attributes, such as `id="Pig"` to find only Pigs, or +`name="Notch"` to find entities named "Notch". This is all done by calling +`dimension.getEntities` + +.. automethod:: mceditlib.worldeditor.WorldEditorDimension.getEntities + +It is important to know that this function only returns an iterator over the found entities. +If you assign one of these entities to another variable (or put it into a container such +as a `list` or `dict`) then that entity will keep its containing chunk loaded, which may +possibly lead to out-of-memory errors. Thus, it is best to simply modify the entities +in-place while iterating through them rather than hold references to them. + +The entities are returned as instances of `EntityRef`. An `EntityRef` is a wrapper around +the underlying NBT Compound Tag that contains the entity's data. The `EntityRef` allows you +to change the values of the entity's attributes without having to deal with the individual +tags and tag types that represent those attributes. + +In other words, instead of writing:: + + entity["Name"] = nbt.TAG_String("codewarrior0") + +You only have to write:: + + entity.Name = "codewarrior0" + +However, it may occasionally be useful to access the entity's NBT tags directly. This can +be done using the `entity.raw_tag` attribute. After modifying the `raw_tag`, you must always +mark the entity as dirty by doing `entity.dirty = True` to ensure your changes are saved:: + + import nbt + tag = entity.raw_tag() + tag["Name"] = nbt.TAG_String("codewarrior0") + entity.dirty = True + + +Creating entities +----------------- + +TODO: Describe creating entities, either by calling `dimension.worldEditor.EntityRef.create(entityID)` or +by crafting the entity's tag by hand. diff --git a/doc/plugins/command.rst b/doc/plugins/command.rst index 5a2b81b..36a4217 100644 --- a/doc/plugins/command.rst +++ b/doc/plugins/command.rst @@ -31,10 +31,10 @@ A basic command plugin:: "The current dimension contains " "%d chunks") % chunkCount) -You can do nearly anything you want in the `perform()` function. To operate on the world -and dimension being edited and the current selection, use `self.editorSession`. See -:doc:`editorsession`, :doc:`worldeditor`, and :ref:`world-editor-dimension` for details -about what can be edited and how. +You can do nearly anything you want in the `perform()` function. The currently edited +dimension can be accessed as `self.editorSession.currentDimension`. See +:doc:`plugin_tasks` for an overview of the dimension object. If you need to modify the +world, be sure to read :ref:`undo-history` first. Simple Commands =============== @@ -50,6 +50,9 @@ it opens a dialog box with a list of options defined by the class; when the user are defined by a Python data structure, making it possible to create a simple UI for your plugin without having to learn any of Qt's UI widgets. +`SimpleCommandPlugin` also manages the undo history automatically. There is no need to +call `beginCommand()` here, and to do so is an error. + A minimal SimpleCommandPlugin:: from mcedit2.plugins import registerPluginCommand, SimpleCommandPlugin