Merge branch 'juliancoffee/be_npc' into 'master'

/be_npc && /alignment commands

See merge request veloren/veloren!4300
This commit is contained in:
Illia Denysenko 2024-02-06 17:46:36 +00:00
commit fea7ed1d63
2 changed files with 138 additions and 17 deletions

View File

@ -340,6 +340,7 @@ pub enum ServerChatCommand {
GroupPromote,
Health,
Help,
IntoNpc,
JoinFaction,
Jump,
Kick,
@ -465,6 +466,16 @@ impl ServerChatCommand {
None,
),
ServerChatCommand::IntoNpc => cmd(
vec![AssetPath(
"entity_config",
"common.entity.",
ENTITY_CONFIGS.clone(),
Required,
)],
"Convert yourself to an NPC. Be careful!",
Some(Admin),
),
ServerChatCommand::Body => cmd(
vec![Enum("body", ENTITIES.clone(), Required)],
"Change your body to different species",
@ -507,12 +518,12 @@ impl ServerChatCommand {
ServerChatCommand::DebugColumn => cmd(
vec![Integer("x", 15000, Required), Integer("y", 15000, Required)],
"Prints some debug information about a column",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::DebugWays => cmd(
vec![Integer("x", 15000, Required), Integer("y", 15000, Required)],
"Prints some debug information about a column's ways",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::DisconnectAllPlayers => cmd(
vec![Any("confirm", Required)],
@ -823,18 +834,18 @@ impl ServerChatCommand {
Boolean("Dismount from ship", "true".to_string(), Optional),
],
"Teleport to an rtsim npc",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::RtsimInfo => cmd(
vec![Integer("npc index", 0, Required)],
"Display information about an rtsim NPC",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::RtsimNpc => cmd(
vec![Any("query", Required), Integer("max number", 20, Optional)],
"List rtsim NPCs that fit a given query (e.g: simulated,merchant) in order of \
distance",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::RtsimPurge => cmd(
vec![Boolean(
@ -848,7 +859,7 @@ impl ServerChatCommand {
ServerChatCommand::RtsimChunk => cmd(
vec![],
"Display information about the current chunk from rtsim",
Some(Moderator),
Some(Admin),
),
ServerChatCommand::Unban => cmd(
vec![PlayerName(Required)],
@ -941,15 +952,15 @@ impl ServerChatCommand {
ServerChatCommand::Adminify => "adminify",
ServerChatCommand::Airship => "airship",
ServerChatCommand::Alias => "alias",
ServerChatCommand::AreaAdd => "area_add",
ServerChatCommand::AreaList => "area_list",
ServerChatCommand::AreaRemove => "area_remove",
ServerChatCommand::Ban => "ban",
ServerChatCommand::BattleMode => "battlemode",
ServerChatCommand::BattleModeForce => "battlemode_force",
ServerChatCommand::Body => "body",
ServerChatCommand::Buff => "buff",
ServerChatCommand::Build => "build",
ServerChatCommand::AreaAdd => "area_add",
ServerChatCommand::AreaList => "area_list",
ServerChatCommand::AreaRemove => "area_remove",
ServerChatCommand::Campfire => "campfire",
ServerChatCommand::DebugColumn => "debug_column",
ServerChatCommand::DebugWays => "debug_ways",
@ -963,11 +974,11 @@ impl ServerChatCommand {
ServerChatCommand::Group => "group",
ServerChatCommand::GroupInvite => "group_invite",
ServerChatCommand::GroupKick => "group_kick",
ServerChatCommand::GroupPromote => "group_promote",
ServerChatCommand::GroupLeave => "group_leave",
ServerChatCommand::GroupPromote => "group_promote",
ServerChatCommand::Health => "health",
ServerChatCommand::Help => "help",
ServerChatCommand::Respawn => "respawn",
ServerChatCommand::IntoNpc => "into_npc",
ServerChatCommand::JoinFaction => "join_faction",
ServerChatCommand::Jump => "jump",
ServerChatCommand::Kick => "kick",
@ -975,6 +986,7 @@ impl ServerChatCommand {
ServerChatCommand::KillNpcs => "kill_npcs",
ServerChatCommand::Kit => "kit",
ServerChatCommand::Lantern => "lantern",
ServerChatCommand::Respawn => "respawn",
ServerChatCommand::Light => "light",
ServerChatCommand::MakeBlock => "make_block",
ServerChatCommand::MakeNpc => "make_npc",

View File

@ -15,6 +15,7 @@ use crate::{
wiring::OutputFormula,
Server, Settings, StateExt,
};
use assets::AssetExt;
use authc::Uuid;
use chrono::{NaiveTime, Timelike, Utc};
@ -34,7 +35,8 @@ use common::{
},
invite::InviteKind,
misc::PortalData,
AdminRole, ChatType, Content, Inventory, Item, LightEmitter, WaypointArea,
AdminRole, ChatType, Content, Inventory, Item, LightEmitter, Presence, PresenceKind,
WaypointArea,
},
depot,
effect::Effect,
@ -49,7 +51,7 @@ use common::{
rtsim::{Actor, Role},
terrain::{Block, BlockKind, CoordinateConversions, SpriteKind, TerrainChunkSize},
tether::Tethered,
uid::Uid,
uid::{IdMaps, Uid},
vol::ReadVol,
weather, Damage, DamageKind, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
};
@ -127,15 +129,15 @@ fn do_command(
ServerChatCommand::Adminify => handle_adminify,
ServerChatCommand::Airship => handle_spawn_airship,
ServerChatCommand::Alias => handle_alias,
ServerChatCommand::AreaAdd => handle_area_add,
ServerChatCommand::AreaList => handle_area_list,
ServerChatCommand::AreaRemove => handle_area_remove,
ServerChatCommand::Ban => handle_ban,
ServerChatCommand::BattleMode => handle_battlemode,
ServerChatCommand::BattleModeForce => handle_battlemode_force,
ServerChatCommand::Body => handle_body,
ServerChatCommand::Buff => handle_buff,
ServerChatCommand::Build => handle_build,
ServerChatCommand::AreaAdd => handle_area_add,
ServerChatCommand::AreaList => handle_area_list,
ServerChatCommand::AreaRemove => handle_area_remove,
ServerChatCommand::Campfire => handle_spawn_campfire,
ServerChatCommand::DebugColumn => handle_debug_column,
ServerChatCommand::DebugWays => handle_debug_ways,
@ -153,7 +155,7 @@ fn do_command(
ServerChatCommand::GroupPromote => handle_group_promote,
ServerChatCommand::Health => handle_health,
ServerChatCommand::Help => handle_help,
ServerChatCommand::Respawn => handle_respawn,
ServerChatCommand::IntoNpc => handle_into_npc,
ServerChatCommand::JoinFaction => handle_join_faction,
ServerChatCommand::Jump => handle_jump,
ServerChatCommand::Kick => handle_kick,
@ -173,6 +175,7 @@ fn do_command(
ServerChatCommand::Region => handle_region,
ServerChatCommand::ReloadChunks => handle_reload_chunks,
ServerChatCommand::RemoveLights => handle_remove_lights,
ServerChatCommand::Respawn => handle_respawn,
ServerChatCommand::RevokeBuild => handle_revoke_build,
ServerChatCommand::RevokeBuildAll => handle_revoke_build_all,
ServerChatCommand::Safezone => handle_safezone,
@ -614,6 +617,112 @@ fn handle_make_block(
}
}
fn handle_into_npc(
server: &mut Server,
client: EcsEntity,
target: EcsEntity,
args: Vec<String>,
action: &ServerChatCommand,
) -> CmdResult<()> {
if client != target {
server.notify_client(
client,
ServerGeneral::server_msg(
ChatType::CommandInfo,
Content::Plain("I hope you aren't abusing this!".to_owned()),
),
);
}
let Some(entity_config) = parse_cmd_args!(args, String) else {
return Err(Content::Plain(action.help_string()));
};
let config = match EntityConfig::load(&entity_config) {
Ok(asset) => asset.read(),
Err(_err) => {
return Err(Content::localized_with_args(
"command-entity-load-failed",
[("config", entity_config)],
));
},
};
let mut loadout_rng = thread_rng();
let dummy = Vec3::zero();
let entity_info = EntityInfo::at(dummy).with_entity_config(
config.clone(),
Some(&entity_config),
&mut loadout_rng,
None,
);
match NpcData::from_entity_info(entity_info) {
NpcData::Data {
inventory,
stats,
skill_set,
poise,
health,
body,
scale,
// changing alignments is cool idea, but needs more work
alignment: _,
// we aren't interested in these (yet?)
pos: _,
agent: _,
loot: _,
} => {
// Should do basically what StateExt::create_npc does
insert_or_replace_component(server, target, inventory, "player")?;
insert_or_replace_component(server, target, stats, "player")?;
insert_or_replace_component(server, target, skill_set, "player")?;
insert_or_replace_component(server, target, poise, "player")?;
if let Some(health) = health {
insert_or_replace_component(server, target, health, "player")?;
}
insert_or_replace_component(server, target, body, "player")?;
insert_or_replace_component(server, target, body.mass(), "player")?;
insert_or_replace_component(server, target, body.density(), "player")?;
insert_or_replace_component(server, target, body.collider(), "player")?;
insert_or_replace_component(server, target, scale, "player")?;
},
NpcData::Waypoint(_) => {
return Err(Content::localized("command-unimplemented-waypoint-spawn"));
},
NpcData::Teleporter(_, _) => {
return Err(Content::localized("command-unimplemented-teleporter-spawn"));
},
}
// Black magic
//
// Mainly needed to disable persistence
{
// TODO: let Imbris work out some edge-cases:
// - error on PresenseKind::LoadingCharacter
// - handle active inventory actions
let ecs = server.state.ecs();
let mut presences = ecs.write_storage::<Presence>();
let presence = presences.get_mut(target);
if let Some(presence) = presence
&& let PresenceKind::Character(id) = presence.kind
{
server.state.ecs().write_resource::<IdMaps>().remove_entity(
Some(target),
None,
Some(id),
None,
);
presence.kind = PresenceKind::Possessor;
}
}
// End of black magic
Ok(())
}
fn handle_make_npc(
server: &mut Server,
client: EcsEntity,