deleteobjects work
This commit is contained in:
parent
2afbc8216b
commit
b236c6d7d8
@ -49,6 +49,7 @@ fn to_cmd_line_args<'a>(tup: &(ArgType, &'a str))
|
||||
];
|
||||
}
|
||||
vec![match arg {
|
||||
// TODO: Remove unused conditions here.
|
||||
ArgType::InputMapPath =>
|
||||
Arg::with_name("input_map")
|
||||
.required(true)
|
||||
@ -90,6 +91,16 @@ fn to_cmd_line_args<'a>(tup: &(ArgType, &'a str))
|
||||
Arg::with_name("param2_val")
|
||||
.required(true)
|
||||
.help(help),
|
||||
ArgType::Object(req) =>
|
||||
Arg::with_name("object")
|
||||
.long("obj")
|
||||
.takes_value(true)
|
||||
.required(req)
|
||||
.help(help),
|
||||
ArgType::Items =>
|
||||
Arg::with_name("items")
|
||||
.long("items")
|
||||
.help(help)
|
||||
}]
|
||||
}
|
||||
|
||||
@ -146,6 +157,8 @@ fn parse_cmd_line_args() -> anyhow::Result<InstArgs> {
|
||||
new_node: sub_matches.value_of("new_node").map(str::to_string),
|
||||
param2_val: sub_matches.value_of("param2_val")
|
||||
.map(|v| v.parse().unwrap()),
|
||||
object: sub_matches.value_of("object").map(str::to_string),
|
||||
items: sub_matches.is_present("items"),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
use super::Command;
|
||||
|
||||
use crate::instance::{ArgType, InstBundle};
|
||||
use crate::map_block::{MapBlock};
|
||||
use crate::map_block::{MapBlock, LuaEntityData};
|
||||
use crate::utils::{query_keys, fmt_big_num};
|
||||
|
||||
use memmem::{Searcher, TwoWaySearcher};
|
||||
|
||||
|
||||
macro_rules! unwrap_or {
|
||||
($res:expr, $alt:expr) => {
|
||||
@ -16,11 +18,20 @@ macro_rules! unwrap_or {
|
||||
|
||||
|
||||
fn delete_objects(inst: &mut InstBundle) {
|
||||
const ITEM_ENT_NAME: &'static [u8] = b"__builtin:item";
|
||||
let search_obj = if inst.args.items {
|
||||
Some(String::from_utf8(ITEM_ENT_NAME.to_vec()).unwrap())
|
||||
} else {
|
||||
inst.args.object.clone()
|
||||
};
|
||||
let keys = query_keys(&mut inst.db, &mut inst.status,
|
||||
None, inst.args.area, inst.args.invert, true);
|
||||
search_obj.clone(), inst.args.area, inst.args.invert, true);
|
||||
|
||||
inst.status.begin_editing();
|
||||
|
||||
let item_searcher = search_obj.as_ref().filter(|_| inst.args.items)
|
||||
.map(|s| TwoWaySearcher::new(format!("[itemstring]=\"{}\"", s)));
|
||||
|
||||
let mut count: u64 = 0;
|
||||
for key in keys {
|
||||
inst.status.inc_done();
|
||||
@ -31,6 +42,7 @@ fn delete_objects(inst: &mut InstBundle) {
|
||||
for i in (0..block.static_objects.list.len()).rev() {
|
||||
let obj = &block.static_objects.list[i];
|
||||
|
||||
// Check area requirements
|
||||
if let Some(area) = inst.args.area {
|
||||
const DIV_FAC: i32 = 10_000;
|
||||
let rounded_pos = obj.f_pos.map(
|
||||
@ -40,6 +52,26 @@ fn delete_objects(inst: &mut InstBundle) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check name requirements
|
||||
let le_data = unwrap_or!(LuaEntityData::deserialize(&obj),
|
||||
continue);
|
||||
if inst.args.items {
|
||||
if le_data.name != ITEM_ENT_NAME {
|
||||
continue;
|
||||
}
|
||||
if let Some(searcher) = &item_searcher {
|
||||
if searcher.search_in(&le_data.data).is_none() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(sobj) = &search_obj {
|
||||
if le_data.name != sobj.as_bytes() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block.static_objects.list.remove(i);
|
||||
modified = true;
|
||||
count += 1;
|
||||
@ -62,6 +94,10 @@ pub fn get_command() -> Command {
|
||||
args: vec![
|
||||
(ArgType::Area(false), "Area in which to delete objects"),
|
||||
(ArgType::Invert, "Delete all objects outside the area"),
|
||||
(ArgType::Object(false),
|
||||
"Name of object (or item with --item) to search for."),
|
||||
(ArgType::Items,
|
||||
"Delete dropped items using object name as item name."),
|
||||
],
|
||||
help: "Delete certain objects (entities)."
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ pub enum ArgType {
|
||||
Node(bool),
|
||||
NewNode(bool),
|
||||
Param2Val(bool),
|
||||
Object(bool),
|
||||
Items,
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +34,8 @@ pub struct InstArgs {
|
||||
pub node: Option<String>,
|
||||
pub new_node: Option<String>,
|
||||
pub param2_val: Option<u8>,
|
||||
pub object: Option<String>,
|
||||
pub items: bool,
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ pub use map_block::{MapBlock, is_valid_generated};
|
||||
pub use compression::ZlibContainer;
|
||||
pub use node_data::NodeData;
|
||||
pub use metadata::NodeMetadataList;
|
||||
pub use static_object::{StaticObject, StaticObjectList};
|
||||
pub use static_object::{StaticObject, StaticObjectList, LuaEntityData};
|
||||
pub use node_timer::{NodeTimer, NodeTimerList};
|
||||
pub use name_id_map::NameIdMap;
|
||||
|
||||
|
@ -62,3 +62,25 @@ impl StaticObjectList {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct LuaEntityData {
|
||||
pub name: Vec<u8>,
|
||||
pub data: Vec<u8>
|
||||
}
|
||||
|
||||
impl LuaEntityData {
|
||||
pub fn deserialize(src: &StaticObject) -> Result<Self, MapBlockError> {
|
||||
if src.obj_type != 7 {
|
||||
return Err(MapBlockError::Other);
|
||||
}
|
||||
let mut src_data = Cursor::new(src.data.as_slice());
|
||||
if src_data.read_u8()? != 1 {
|
||||
return Err(MapBlockError::Other);
|
||||
}
|
||||
|
||||
let name = read_string16(&mut src_data)?;
|
||||
let data = read_string32(&mut src_data)?;
|
||||
Ok(Self {name, data})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user