Use SpriteInteract state for toggling lights

This commit is contained in:
Joshua Barretto 2024-01-21 21:25:14 +00:00
parent 4a89d88e9b
commit d836461f8d
8 changed files with 51 additions and 21 deletions

View File

@ -1420,8 +1420,8 @@ impl Client {
} }
pub fn toggle_sprite_light(&mut self, pos: VolumePos, enable: bool) { pub fn toggle_sprite_light(&mut self, pos: VolumePos, enable: bool) {
self.send_msg(ClientGeneral::ControlEvent( self.control_action(ControlAction::InventoryAction(
ControlEvent::ToggleSpriteLight(pos, enable), InventoryAction::ToggleSpriteLight(pos, enable),
)); ));
} }

View File

@ -40,6 +40,9 @@ pub enum InventoryAction {
Use(Slot), Use(Slot),
Sort, Sort,
Collect(Vec3<i32>), Collect(Vec3<i32>),
// TODO: Not actually inventory-related: refactor to allow sprite interaction without
// inventory manipulation!
ToggleSpriteLight(VolumePos, bool),
} }
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
@ -159,7 +162,6 @@ pub enum ControlEvent {
new_ability: ability::AuxiliaryAbility, new_ability: ability::AuxiliaryAbility,
}, },
ActivatePortal(Uid), ActivatePortal(Uid),
ToggleSpriteLight(VolumePos, bool),
} }
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -340,7 +340,7 @@ pub enum ServerEvent {
}, },
ToggleSpriteLight { ToggleSpriteLight {
entity: EcsEntity, entity: EcsEntity,
pos: VolumePos, pos: Vec3<i32>,
enable: bool, enable: bool,
}, },
} }

View File

@ -117,8 +117,19 @@ impl CharacterBehavior for Data {
sprite_pos: self.static_data.sprite_pos, sprite_pos: self.static_data.sprite_pos,
required_item: inv_slot, required_item: inv_slot,
}; };
output_events
.emit_server(ServerEvent::InventoryManip(data.entity, inv_manip)); match self.static_data.sprite_kind {
SpriteInteractKind::ToggleLight(enable) => {
output_events.emit_server(ServerEvent::ToggleSpriteLight {
entity: data.entity,
pos: self.static_data.sprite_pos,
enable,
})
},
_ => output_events
.emit_server(ServerEvent::InventoryManip(data.entity, inv_manip)),
}
if matches!(self.static_data.sprite_kind, SpriteInteractKind::Unlock) { if matches!(self.static_data.sprite_kind, SpriteInteractKind::Unlock) {
output_events.emit_local(LocalEvent::CreateOutcome( output_events.emit_local(LocalEvent::CreateOutcome(
Outcome::SpriteUnlocked { Outcome::SpriteUnlocked {

View File

@ -20,6 +20,7 @@ use crate::{
}, },
consts::{FRIC_GROUND, GRAVITY, MAX_PICKUP_RANGE}, consts::{FRIC_GROUND, GRAVITY, MAX_PICKUP_RANGE},
event::{LocalEvent, ServerEvent}, event::{LocalEvent, ServerEvent},
mounting::Volume,
outcome::Outcome, outcome::Outcome,
states::{behavior::JoinData, utils::CharacterState::Idle, *}, states::{behavior::JoinData, utils::CharacterState::Idle, *},
terrain::{Block, TerrainGrid, UnlockKind}, terrain::{Block, TerrainGrid, UnlockKind},
@ -1140,6 +1141,29 @@ pub fn handle_manipulate_loadout(
let inv_manip = InventoryManip::Use(slot); let inv_manip = InventoryManip::Use(slot);
output_events.emit_server(ServerEvent::InventoryManip(data.entity, inv_manip)); output_events.emit_server(ServerEvent::InventoryManip(data.entity, inv_manip));
}, },
InventoryAction::ToggleSpriteLight(pos, enable) => {
if matches!(pos.kind, Volume::Terrain) {
let sprite_interact = sprite_interact::SpriteInteractKind::ToggleLight(enable);
let (buildup_duration, use_duration, recover_duration) =
sprite_interact.durations();
update.character = CharacterState::SpriteInteract(sprite_interact::Data {
static_data: sprite_interact::StaticData {
buildup_duration,
use_duration,
recover_duration,
sprite_pos: pos.pos,
sprite_kind: sprite_interact,
was_wielded: data.character.is_wield(),
was_sneak: data.character.is_stealthy(),
required_item: None,
},
timer: Duration::default(),
stage_section: StageSection::Buildup,
});
}
},
} }
} }

View File

@ -160,7 +160,7 @@ macro_rules! sprites {
} }
#[inline] pub(super) fn to_initial_bytes(self) -> [u8; 3] { #[inline] pub(super) fn to_initial_bytes(self) -> [u8; 3] {
let sprite_bytes = (*self as u32).to_be_bytes(); let sprite_bytes = (self as u32).to_be_bytes();
let block = Block::from_raw(super::BlockKind::Air, [sprite_bytes[1], sprite_bytes[2], sprite_bytes[3]]); let block = Block::from_raw(super::BlockKind::Air, [sprite_bytes[1], sprite_bytes[2], sprite_bytes[3]]);
match self.category() { match self.category() {
$(Category::$category_name => block$($(.with_attr($attr::default()).unwrap())*)?,)* $(Category::$category_name => block$($(.with_attr($attr::default()).unwrap())*)?,)*

View File

@ -140,13 +140,6 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::StartTeleporting { entity, portal }); server_emitter.emit(ServerEvent::StartTeleporting { entity, portal });
} }
}, },
ControlEvent::ToggleSpriteLight(pos, enable) => {
server_emitter.emit(ServerEvent::ToggleSpriteLight {
entity,
pos,
enable,
});
},
} }
} }
} }

View File

@ -20,7 +20,7 @@ use common::{
}, },
event::EventBus, event::EventBus,
link::Is, link::Is,
mounting::{Mount, Mounting, Rider, Volume, VolumeMounting, VolumePos, VolumeRider}, mounting::{Mount, Mounting, Rider, VolumeMounting, VolumePos, VolumeRider},
outcome::Outcome, outcome::Outcome,
rtsim::RtSimEntity, rtsim::RtSimEntity,
terrain::{Block, SpriteKind}, terrain::{Block, SpriteKind},
@ -473,23 +473,23 @@ pub fn handle_tame_pet(server: &mut Server, pet_entity: EcsEntity, owner_entity:
pub fn handle_toggle_sprite_light( pub fn handle_toggle_sprite_light(
server: &mut Server, server: &mut Server,
entity: EcsEntity, entity: EcsEntity,
pos: VolumePos, pos: Vec3<i32>,
enable: bool, enable: bool,
) { ) {
let state = server.state_mut(); let state = server.state_mut();
// TODO: Implement toggling lights on volume entities // TODO: Implement toggling lights on volume entities
if let Some(entity_pos) = state.ecs().read_storage::<Pos>().get(entity) if let Some(entity_pos) = state.ecs().read_storage::<Pos>().get(entity)
&& matches!(&pos.kind, Volume::Terrain) && entity_pos.0.distance_squared(pos.as_()) < MAX_INTERACT_RANGE.powi(2)
&& entity_pos.0.distance_squared(pos.pos.as_()) < MAX_INTERACT_RANGE.powi(2) && state.can_set_block(pos)
&& state.can_set_block(pos.pos)
{ {
if let Some(new_block) = state if let Some(new_block) = state
.terrain() .terrain()
.get(pos.pos) .get(pos)
.ok() .ok()
.and_then(|block| block.with_toggle_light(enable)) .and_then(|block| block.with_toggle_light(enable))
{ {
state.set_block(pos.pos, new_block); state.set_block(pos, new_block);
// TODO: Emit outcome
} }
} }
} }