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

View File

@ -15,6 +15,7 @@ use crate::{
wiring::OutputFormula, wiring::OutputFormula,
Server, Settings, StateExt, Server, Settings, StateExt,
}; };
use assets::AssetExt; use assets::AssetExt;
use authc::Uuid; use authc::Uuid;
use chrono::{NaiveTime, Timelike, Utc}; use chrono::{NaiveTime, Timelike, Utc};
@ -34,7 +35,8 @@ use common::{
}, },
invite::InviteKind, invite::InviteKind,
misc::PortalData, misc::PortalData,
AdminRole, ChatType, Content, Inventory, Item, LightEmitter, WaypointArea, AdminRole, ChatType, Content, Inventory, Item, LightEmitter, Presence, PresenceKind,
WaypointArea,
}, },
depot, depot,
effect::Effect, effect::Effect,
@ -49,7 +51,7 @@ use common::{
rtsim::{Actor, Role}, rtsim::{Actor, Role},
terrain::{Block, BlockKind, CoordinateConversions, SpriteKind, TerrainChunkSize}, terrain::{Block, BlockKind, CoordinateConversions, SpriteKind, TerrainChunkSize},
tether::Tethered, tether::Tethered,
uid::Uid, uid::{IdMaps, Uid},
vol::ReadVol, vol::ReadVol,
weather, Damage, DamageKind, DamageSource, Explosion, LoadoutBuilder, RadiusEffect, weather, Damage, DamageKind, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
}; };
@ -127,15 +129,15 @@ fn do_command(
ServerChatCommand::Adminify => handle_adminify, ServerChatCommand::Adminify => handle_adminify,
ServerChatCommand::Airship => handle_spawn_airship, ServerChatCommand::Airship => handle_spawn_airship,
ServerChatCommand::Alias => handle_alias, ServerChatCommand::Alias => handle_alias,
ServerChatCommand::AreaAdd => handle_area_add,
ServerChatCommand::AreaList => handle_area_list,
ServerChatCommand::AreaRemove => handle_area_remove,
ServerChatCommand::Ban => handle_ban, ServerChatCommand::Ban => handle_ban,
ServerChatCommand::BattleMode => handle_battlemode, ServerChatCommand::BattleMode => handle_battlemode,
ServerChatCommand::BattleModeForce => handle_battlemode_force, ServerChatCommand::BattleModeForce => handle_battlemode_force,
ServerChatCommand::Body => handle_body, ServerChatCommand::Body => handle_body,
ServerChatCommand::Buff => handle_buff, ServerChatCommand::Buff => handle_buff,
ServerChatCommand::Build => handle_build, 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::Campfire => handle_spawn_campfire,
ServerChatCommand::DebugColumn => handle_debug_column, ServerChatCommand::DebugColumn => handle_debug_column,
ServerChatCommand::DebugWays => handle_debug_ways, ServerChatCommand::DebugWays => handle_debug_ways,
@ -153,7 +155,7 @@ fn do_command(
ServerChatCommand::GroupPromote => handle_group_promote, ServerChatCommand::GroupPromote => handle_group_promote,
ServerChatCommand::Health => handle_health, ServerChatCommand::Health => handle_health,
ServerChatCommand::Help => handle_help, ServerChatCommand::Help => handle_help,
ServerChatCommand::Respawn => handle_respawn, ServerChatCommand::IntoNpc => handle_into_npc,
ServerChatCommand::JoinFaction => handle_join_faction, ServerChatCommand::JoinFaction => handle_join_faction,
ServerChatCommand::Jump => handle_jump, ServerChatCommand::Jump => handle_jump,
ServerChatCommand::Kick => handle_kick, ServerChatCommand::Kick => handle_kick,
@ -173,6 +175,7 @@ fn do_command(
ServerChatCommand::Region => handle_region, ServerChatCommand::Region => handle_region,
ServerChatCommand::ReloadChunks => handle_reload_chunks, ServerChatCommand::ReloadChunks => handle_reload_chunks,
ServerChatCommand::RemoveLights => handle_remove_lights, ServerChatCommand::RemoveLights => handle_remove_lights,
ServerChatCommand::Respawn => handle_respawn,
ServerChatCommand::RevokeBuild => handle_revoke_build, ServerChatCommand::RevokeBuild => handle_revoke_build,
ServerChatCommand::RevokeBuildAll => handle_revoke_build_all, ServerChatCommand::RevokeBuildAll => handle_revoke_build_all,
ServerChatCommand::Safezone => handle_safezone, 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( fn handle_make_npc(
server: &mut Server, server: &mut Server,
client: EcsEntity, client: EcsEntity,