Added allow_players flag to Transform character state

This commit is contained in:
crabman 2024-02-28 15:56:12 +00:00
parent a14c2f054c
commit c50f1047f7
No known key found for this signature in database
6 changed files with 46 additions and 9 deletions

View File

@ -3,4 +3,5 @@ Transform(
recover_duration: 0.5,
target: "common.entity.wild.peaceful.crab",
specifier: Some(Evolve),
allow_players: true,
)

View File

@ -1004,6 +1004,10 @@ pub enum CharacterAbility {
target: String,
#[serde(default)]
specifier: Option<transform::FrontendSpecifier>,
/// Only set to `true` for admin only abilities since this disables
/// persistence and is not intended to be used by regular players
#[serde(default)]
allow_players: bool,
#[serde(default)]
meta: AbilityMeta,
},
@ -1678,6 +1682,7 @@ impl CharacterAbility {
ref mut recover_duration,
target: _,
specifier: _,
allow_players: _,
meta: _,
} => {
*buildup_duration /= stats.speed;
@ -2964,12 +2969,14 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
recover_duration,
target,
specifier,
allow_players,
meta: _,
} => CharacterState::Transform(transform::Data {
static_data: transform::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
recover_duration: Duration::from_secs_f32(*recover_duration),
specifier: *specifier,
allow_players: *allow_players,
target: target.to_owned(),
ability_info,
},

View File

@ -261,7 +261,13 @@ pub struct SetPetStayEvent(pub EcsEntity, pub EcsEntity, pub bool);
pub struct PossessEvent(pub Uid, pub Uid);
pub struct TransformEvent(pub Uid, pub EntityInfo);
pub struct TransformEvent {
pub target_entity: Uid,
pub entity_info: EntityInfo,
/// If set to false, players wont be transformed unless with a Possessor
/// presence kind
pub allow_players: bool,
}
pub struct InitializeCharacterEvent {
pub entity: EcsEntity,

View File

@ -32,6 +32,8 @@ pub struct StaticData {
/// The entity configuration you will be transformed into
pub target: String,
pub ability_info: AbilityInfo,
/// Whether players are allowed to transform
pub allow_players: bool,
/// Used to specify the transformation to the frontend
pub specifier: Option<FrontendSpecifier>,
}
@ -95,7 +97,11 @@ impl CharacterBehavior for Data {
}
}
output_events.emit_server(TransformEvent(*data.uid, entity_info));
output_events.emit_server(TransformEvent {
target_entity: *data.uid,
entity_info,
allow_players: self.static_data.allow_players,
});
update.character = CharacterState::Transform(Data {
static_data: self.static_data.clone(),
timer: Duration::default(),

View File

@ -662,7 +662,7 @@ fn handle_into_npc(
None,
);
transform_entity(server, target, entity_info).map_err(|error| match error {
transform_entity(server, target, entity_info, true).map_err(|error| match error {
TransformEntityError::EntityDead => {
Content::localized_with_args("command-entity-dead", [("entity", "target")])
},
@ -675,6 +675,11 @@ fn handle_into_npc(
TransformEntityError::LoadingCharacter => {
Content::localized("command-transform-invalid-presence")
},
TransformEntityError::EntityIsPlayer => {
unreachable!(
"Transforming players must be valid as we explicitly allowed player transformation"
);
},
})
}

View File

@ -2101,13 +2101,20 @@ impl ServerEvent for StartTeleportingEvent {
}
}
pub fn handle_transform(server: &mut Server, TransformEvent(uid, info): TransformEvent) {
let Some(entity) = server.state().ecs().entity_from_uid(uid) else {
pub fn handle_transform(
server: &mut Server,
TransformEvent {
target_entity,
entity_info,
allow_players,
}: TransformEvent,
) {
let Some(entity) = server.state().ecs().entity_from_uid(target_entity) else {
return;
};
if let Err(error) = transform_entity(server, entity, info) {
error!(?error, ?uid, "Failed transform entity");
if let Err(error) = transform_entity(server, entity, entity_info, allow_players) {
error!(?error, ?target_entity, "Failed transform entity");
}
}
@ -2117,19 +2124,21 @@ pub enum TransformEntityError {
UnexpectedNpcWaypoint,
UnexpectedNpcTeleporter,
LoadingCharacter,
EntityIsPlayer,
}
pub fn transform_entity(
server: &mut Server,
entity: Entity,
info: EntityInfo,
entity_info: EntityInfo,
allow_players: bool,
) -> Result<(), TransformEntityError> {
let is_player = server
.state()
.read_storage::<comp::Player>()
.contains(entity);
match NpcData::from_entity_info(info) {
match NpcData::from_entity_info(entity_info) {
NpcData::Data {
inventory,
stats,
@ -2174,6 +2183,9 @@ pub fn transform_entity(
Some(PresenceKind::Spectator | PresenceKind::LoadingCharacter(_)) => {
return Err(TransformEntityError::LoadingCharacter);
},
Some(PresenceKind::Character(_)) if !allow_players => {
return Err(TransformEntityError::EntityIsPlayer);
},
Some(PresenceKind::Possessor | PresenceKind::Character(_)) => {},
None => break 'persist,
}