Various changes

master
random-geek 2021-01-30 23:50:14 -08:00
parent 7913843bb7
commit 2b2ec33f19
5 changed files with 78 additions and 57 deletions

View File

@ -20,7 +20,7 @@ only SQLite format maps are currently supported.
## General usage
`mapedit [-h] <map> <subcommand>`
`mapeditr [-h] <map> <subcommand>`
Arguments:
@ -166,25 +166,30 @@ mapblocks can be copied verbatim.
### replaceininv
Usage: `replaceininv [--deletemeta] [--node <node>] [--p1 x y z] [--p2 x y z] [--invert] <item> <new_item>`
Usage: `replaceininv [--delete] [--deletemeta] [--nodes <nodes>] [--p1 x y z]
[--p2 x y z] [--invert] <item> [new_item]`
Replace a certain item with another in node inventories. To delete items
instead of replacing them, use "Empty" (with a capital E) for `replacename`.
Replace or delete certain items in node inventories.
Arguments:
- `item`: Name of item to replace
- `new_item`: Name of new item to replace with
- `--deletemeta`: Delete metadata of replaced items. If not specified, any item
metadata will remain unchanged.
- `--node`: Name of node to to replace in. If not specified, the item will be
replaced in all node inventories.
- `--p1, --p2`: Area in which to search for nodes. If not specified, items will
be replaced across the entire map.
- `--invert`: Only search for nodes *outside* the given area.
- `item`: Name of item to replace/delete
- `new_item`: Name of new item, if replacing items.
- `--delete`: Delete items instead of replacing them.
- `--deletemeta`: Delete metadata of items. May be used with or without
`new_item`, depending on whether items should also be replaced.
- `--nodes`: Names of one or more nodes to replace in. If not specified, the
item will be replaced in all node inventories.
- `--p1, --p2`: Area in which to modify node inventories. If not specified,
items will be replaced in all node inventories.
- `--invert`: Only modify node inventories *outside* the given area.
**Tip:** To only delete metadata without replacing the nodes, use the
`--deletemeta` flag, and make `new_item` the same as `item`.
Examples:
Replace all written books in chests with unwritten books, deleting metadata:
`replaceininv default:book_written default:book --deletemeta --nodes
default:chest default:chest_locked`
### replacenodes

View File

@ -87,31 +87,34 @@ fn to_cmd_line_args<'a>(tup: &(ArgType, &'a str))
.takes_value(true)
.required(true)
.help(help),
ArgType::Item =>
Arg::with_name("item")
.takes_value(true)
.required(true)
.help(help),
ArgType::NewItem =>
Arg::with_name("new_item")
.takes_value(true)
.required(true)
.help(help),
ArgType::Param2Val =>
Arg::with_name("param2_val")
.required(true)
.help(help),
ArgType::Object =>
Arg::with_name("object")
.long("obj")
.takes_value(true)
.help(help),
ArgType::Item =>
Arg::with_name("item")
.takes_value(true)
.required(true)
.help(help),
ArgType::Items =>
Arg::with_name("items")
.long("items")
.min_values(0)
.max_values(1)
.help(help),
ArgType::NewItem =>
Arg::with_name("new_item")
.takes_value(true)
.help(help),
ArgType::DeleteMeta =>
Arg::with_name("delete_meta")
.long("deletemeta")
.help(help),
ArgType::DeleteItem =>
Arg::with_name("delete_item")
.long("delete")
.help(help),
ArgType::Key =>
Arg::with_name("key")
.takes_value(true)
@ -122,9 +125,9 @@ fn to_cmd_line_args<'a>(tup: &(ArgType, &'a str))
.takes_value(true)
.required(true)
.help(help),
ArgType::DeleteMeta =>
Arg::with_name("delete_meta")
.long("deletemeta")
ArgType::Param2Val =>
Arg::with_name("param2_val")
.required(true)
.help(help),
}]
}
@ -161,8 +164,8 @@ fn parse_cmd_line_args() -> anyhow::Result<InstArgs> {
let sub_matches = matches.subcommand_matches(&sub_name).unwrap();
Ok(InstArgs {
map_path: matches.value_of("map").unwrap().to_string(),
command: sub_name,
map_path: matches.value_of("map").unwrap().to_string(),
input_map_path: sub_matches.value_of("input_map").map(str::to_string),
area: {
let p1_maybe = sub_matches.values_of("p1").map(arg_to_pos)
@ -182,17 +185,17 @@ fn parse_cmd_line_args() -> anyhow::Result<InstArgs> {
nodes: sub_matches.values_of("nodes").iter_mut().flatten()
.map(str::to_string).collect(),
new_node: sub_matches.value_of("new_node").map(str::to_string),
item: sub_matches.value_of("item").map(str::to_string),
new_item: sub_matches.value_of("new_item").map(str::to_string),
param2_val: sub_matches.value_of("param2_val")
.map(|val| val.parse().context("Invalid param2 value."))
.transpose().context("Invalid param2 value.")?,
object: sub_matches.value_of("object").map(str::to_string),
item: sub_matches.value_of("item").map(str::to_string),
items: sub_matches.values_of("items")
.map(|v| v.map(str::to_string).collect()),
new_item: sub_matches.value_of("new_item").map(str::to_string),
delete_meta: sub_matches.is_present("delete_meta"),
delete_item: sub_matches.is_present("delete_item"),
key: sub_matches.value_of("key").map(str::to_string),
value: sub_matches.value_of("value").map(str::to_string),
delete_meta: sub_matches.is_present("delete_meta"),
param2_val: sub_matches.value_of("param2_val").map(|val| val.parse())
.transpose().context("Invalid param2 value.")?,
})
}

View File

@ -2,7 +2,7 @@ use super::Command;
use crate::unwrap_or;
use crate::spatial::Vec3;
use crate::instance::{ArgType, InstBundle};
use crate::instance::{ArgType, InstArgs, InstBundle};
use crate::map_block::{MapBlock, NodeMetadataList};
use crate::utils::{query_keys, to_bytes, fmt_big_num};
@ -65,9 +65,10 @@ fn do_replace(inv: &mut Vec<u8>, item: &[u8], new_item: &[u8], del_meta: bool)
fn replace_in_inv(inst: &mut InstBundle) {
let item = to_bytes(inst.args.item.as_ref().unwrap());
let new_item = to_bytes(inst.args.new_item.as_ref().unwrap());
let nodes: Vec<_> = inst.args.nodes.iter().map(to_bytes).collect();
let new_item = inst.args.new_item.as_ref().map(to_bytes)
.unwrap_or(if inst.args.delete_item { vec![] } else { item.clone() });
let nodes: Vec<_> = inst.args.nodes.iter().map(to_bytes).collect();
let keys = query_keys(&mut inst.db, &mut inst.status,
&nodes, inst.args.area, inst.args.invert, true);
@ -128,18 +129,29 @@ fn replace_in_inv(inst: &mut InstBundle) {
}
fn verify_args(args: &InstArgs) -> anyhow::Result<()> {
if args.new_item.is_none() && !args.delete_item && !args.delete_meta {
anyhow::bail!(
"new_item is required unless --delete or --deletemeta is used.")
} else if args.new_item.is_some() && args.delete_item {
anyhow::bail!("Cannot delete items if new_item is specified.");
}
Ok(())
}
pub fn get_command() -> Command {
Command {
func: replace_in_inv,
verify_args: None,
verify_args: Some(verify_args),
args: vec![
(ArgType::Item, "Name of the item to replace"),
(ArgType::NewItem, "Name of the new item. Use an empty string \
(\"\") to delete items."),
(ArgType::Item, "Name of the item to replace/delete"),
(ArgType::NewItem, "Name of the new item, if replacing items."),
(ArgType::DeleteMeta, "Delete metadata of affected items."),
(ArgType::DeleteItem, "Delete items instead of replacing them."),
(ArgType::Area(false), "Area in which to modify inventories"),
(ArgType::Invert, "Modify inventories outside the given area."),
(ArgType::Nodes, "Names of nodes to modify inventories of"),
(ArgType::DeleteMeta, "Delete metadata of affected items."),
],
help: "Replace or delete items in node inventories."
}

View File

@ -18,14 +18,15 @@ pub enum ArgType {
Node(bool),
Nodes,
NewNode,
Item,
NewItem,
Param2Val,
Object,
Item,
Items,
NewItem,
DeleteMeta,
DeleteItem,
Key,
Value,
DeleteMeta,
Param2Val,
}
@ -40,14 +41,15 @@ pub struct InstArgs {
pub node: Option<String>,
pub nodes: Vec<String>,
pub new_node: Option<String>,
pub item: Option<String>,
pub new_item: Option<String>,
pub param2_val: Option<u8>,
pub object: Option<String>,
pub item: Option<String>,
pub items: Option<Vec<String>>,
pub new_item: Option<String>,
pub delete_meta: bool,
pub delete_item: bool,
pub key: Option<String>,
pub value: Option<String>,
pub delete_meta: bool,
pub param2_val: Option<u8>,
}

View File

@ -3,6 +3,5 @@
{
"path": "."
}
],
"settings": {}
]
}