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 {
|
vec![match arg {
|
||||||
|
// TODO: Remove unused conditions here.
|
||||||
ArgType::InputMapPath =>
|
ArgType::InputMapPath =>
|
||||||
Arg::with_name("input_map")
|
Arg::with_name("input_map")
|
||||||
.required(true)
|
.required(true)
|
||||||
@ -90,6 +91,16 @@ fn to_cmd_line_args<'a>(tup: &(ArgType, &'a str))
|
|||||||
Arg::with_name("param2_val")
|
Arg::with_name("param2_val")
|
||||||
.required(true)
|
.required(true)
|
||||||
.help(help),
|
.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),
|
new_node: sub_matches.value_of("new_node").map(str::to_string),
|
||||||
param2_val: sub_matches.value_of("param2_val")
|
param2_val: sub_matches.value_of("param2_val")
|
||||||
.map(|v| v.parse().unwrap()),
|
.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 super::Command;
|
||||||
|
|
||||||
use crate::instance::{ArgType, InstBundle};
|
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 crate::utils::{query_keys, fmt_big_num};
|
||||||
|
|
||||||
|
use memmem::{Searcher, TwoWaySearcher};
|
||||||
|
|
||||||
|
|
||||||
macro_rules! unwrap_or {
|
macro_rules! unwrap_or {
|
||||||
($res:expr, $alt:expr) => {
|
($res:expr, $alt:expr) => {
|
||||||
@ -16,11 +18,20 @@ macro_rules! unwrap_or {
|
|||||||
|
|
||||||
|
|
||||||
fn delete_objects(inst: &mut InstBundle) {
|
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,
|
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();
|
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;
|
let mut count: u64 = 0;
|
||||||
for key in keys {
|
for key in keys {
|
||||||
inst.status.inc_done();
|
inst.status.inc_done();
|
||||||
@ -31,6 +42,7 @@ fn delete_objects(inst: &mut InstBundle) {
|
|||||||
for i in (0..block.static_objects.list.len()).rev() {
|
for i in (0..block.static_objects.list.len()).rev() {
|
||||||
let obj = &block.static_objects.list[i];
|
let obj = &block.static_objects.list[i];
|
||||||
|
|
||||||
|
// Check area requirements
|
||||||
if let Some(area) = inst.args.area {
|
if let Some(area) = inst.args.area {
|
||||||
const DIV_FAC: i32 = 10_000;
|
const DIV_FAC: i32 = 10_000;
|
||||||
let rounded_pos = obj.f_pos.map(
|
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);
|
block.static_objects.list.remove(i);
|
||||||
modified = true;
|
modified = true;
|
||||||
count += 1;
|
count += 1;
|
||||||
@ -62,6 +94,10 @@ pub fn get_command() -> Command {
|
|||||||
args: vec![
|
args: vec![
|
||||||
(ArgType::Area(false), "Area in which to delete objects"),
|
(ArgType::Area(false), "Area in which to delete objects"),
|
||||||
(ArgType::Invert, "Delete all objects outside the area"),
|
(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)."
|
help: "Delete certain objects (entities)."
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ pub enum ArgType {
|
|||||||
Node(bool),
|
Node(bool),
|
||||||
NewNode(bool),
|
NewNode(bool),
|
||||||
Param2Val(bool),
|
Param2Val(bool),
|
||||||
|
Object(bool),
|
||||||
|
Items,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -32,6 +34,8 @@ pub struct InstArgs {
|
|||||||
pub node: Option<String>,
|
pub node: Option<String>,
|
||||||
pub new_node: Option<String>,
|
pub new_node: Option<String>,
|
||||||
pub param2_val: Option<u8>,
|
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 compression::ZlibContainer;
|
||||||
pub use node_data::NodeData;
|
pub use node_data::NodeData;
|
||||||
pub use metadata::NodeMetadataList;
|
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 node_timer::{NodeTimer, NodeTimerList};
|
||||||
pub use name_id_map::NameIdMap;
|
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