use bindings::core_ue::Object;
use bindings::engine::GameplayStatics;
use bindings::prelude::*;
use rusteal_runtime::runtime::{CommandContext, RustealResult, UObjectRef, console};
use crate::component::{{ plugin }}Component;
use crate::item::{{ plugin }}Item;
use crate::subsystem::{{ plugin }}Subsystem;
fn player_inventory(world: UObjectRef<World>) -> RustealResult<{{ plugin }}Component> {
let world = world.upcast_to::<Object>();
let pawn = GameplayStatics::get_player_pawn(world, 0).upcast_to();
let mut subsystem = {{ plugin }}Subsystem::get(world)?;
{{ plugin }}Component::from_obj(subsystem.inventory_of(pawn, true))
}
fn load_item(path: &str) -> RustealResult<UObjectRef<{{ plugin }}Item>> {
let full = match path.rsplit('/').next() {
Some(name) if !name.contains('.') => format!("{path}.{name}"),
_ => path.to_string(),
};
load_object::<{{ plugin }}Item>(&full)
}
fn item_name(item: UObjectRef<{{ plugin }}Item>) -> String {
{{ plugin }}Item::from_obj(item)
.map(|i| i.display_name())
.ok()
.filter(|name| !name.is_empty())
.or_else(|| item.get_name().ok())
.unwrap_or_default()
}
fn give_or_take(args: &[&str], context: &CommandContext, give: bool) -> RustealResult<()> {
let path = args.first().copied().unwrap_or_default();
let count = args.get(1).and_then(|c| c.parse().ok()).unwrap_or(1);
let item = load_item(path)?;
let mut inventory = player_inventory(context.world()?)?;
let moved = if give {
inventory.add_item(item, count)
} else {
inventory.remove_item(item, count)
};
let verb = if give { "added" } else { "removed" };
log::info!(
"[{{ plugin }}] {verb} {moved} {}: {} now",
item_name(item),
inventory.count_of(item)
);
Ok(())
}
fn startup() {
let prefix = "{{ crate_name | replace(from="-", to="_") }}";
let commands: [(&str, &str, fn(&[&str], &CommandContext) -> RustealResult<()>); 3] = [
(
"give",
"Give the player an item: give <item path> [count]",
|args, context| give_or_take(args, context, true),
),
(
"take",
"Take an item from the player: take <item path> [count]",
|args, context| give_or_take(args, context, false),
),
("list", "List the player's items", |_, context| {
let inventory = player_inventory(context.world()?)?;
let stacks = inventory.stacks()?;
log::info!(
"[{{ plugin }}] {} stacks, weight {}",
stacks.len(),
inventory.total_weight()
);
for (item, count) in stacks {
log::info!("[{{ plugin }}] {} x{count}", item_name(item));
}
Ok(())
}),
];
for (name, help, run) in commands {
let full = format!("{prefix}.{name}");
let label = full.clone();
let result = console::register_command(&full, help, move |args, context| {
if let Err(e) = run(args, context) {
log::error!("[{{ plugin }}] {label}: {e:?}");
}
});
if let Err(e) = result {
log::error!("[{{ plugin }}] {full}: {e:?}");
}
}
}
rusteal_runtime::on_load!(startup);