Skip to content

Commit

Permalink
Change the direction of the entities
Browse files Browse the repository at this point in the history
  • Loading branch information
kokosha authored and hasenbanck committed Dec 28, 2024
1 parent f61cb4d commit 15b20ac
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 46 deletions.
6 changes: 4 additions & 2 deletions korangar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use korangar_util::texture_atlas::AtlasAllocation;
#[cfg(not(feature = "debug"))]
use ragnarok_packets::handler::NoPacketCallback;
use ragnarok_packets::{
BuyShopItemsResult, CharacterId, CharacterInformation, CharacterServerInformation, DisappearanceReason, Friend, HotbarSlot,
BuyShopItemsResult, CharacterId, CharacterInformation, CharacterServerInformation, Direction, DisappearanceReason, Friend, HotbarSlot,
SellItemsResult, SkillId, SkillType, TilePosition, UnitId, WorldPosition,
};
use renderer::InterfaceRenderer;
Expand Down Expand Up @@ -964,7 +964,7 @@ impl Client {
&mut self.path_finder,
saved_login_data.account_id,
character_information,
WorldPosition { x: 0, y: 0 },
WorldPosition::origin(),
client_tick,
);
let player = Entity::Player(player);
Expand Down Expand Up @@ -1589,6 +1589,7 @@ impl Client {
let _ = self.networking_system.player_move(WorldPosition {
x: destination.x,
y: destination.y,
direction: Direction::N,
});
}
}
Expand All @@ -1604,6 +1605,7 @@ impl Client {
WorldPosition {
x: position.x,
y: position.y,
direction: Direction::N,
}
}),
_ => Ok(()),
Expand Down
16 changes: 8 additions & 8 deletions korangar/src/world/animation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use cgmath::{Array, Matrix4, Point3, Transform, Vector2, Vector3, Zero};
use korangar_interface::elements::PrototypeElement;
use korangar_util::container::Cacheable;
use ragnarok_packets::EntityId;
use ragnarok_packets::{Direction, EntityId};

#[cfg(feature = "debug")]
use crate::graphics::DebugRectangleInstruction;
Expand Down Expand Up @@ -82,10 +82,10 @@ impl Default for AnimationFramePart {
}

impl AnimationData {
pub fn get_frame(&self, animation_state: &AnimationState, camera: &dyn Camera, head_direction: usize) -> &AnimationFrame {
pub fn get_frame(&self, animation_state: &AnimationState, camera: &dyn Camera, direction: Direction) -> &AnimationFrame {
let camera_direction = camera.camera_direction();
let direction = (camera_direction + head_direction) % 8;
let animation_action_index = animation_state.action as usize * 8 + direction;
let direction_usize = (camera_direction + usize::from(direction)) & 7;
let animation_action_index = animation_state.action as usize * 8 + direction_usize;

let delay_index = animation_action_index % self.delays.len();
let animation_index = animation_action_index % self.animations.len();
Expand Down Expand Up @@ -143,9 +143,9 @@ impl AnimationData {
entity_id: EntityId,
entity_position: Point3<f32>,
animation_state: &AnimationState,
head_direction: usize,
direction: Direction,
) {
let frame = self.get_frame(animation_state, camera, head_direction);
let frame = self.get_frame(animation_state, camera, direction);
let world_matrix = self.calculate_world_matrix(camera, frame, entity_position);

for (index, frame_part) in frame.frame_parts.iter().enumerate() {
Expand Down Expand Up @@ -187,11 +187,11 @@ impl AnimationData {
camera: &dyn Camera,
entity_position: Point3<f32>,
animation_state: &AnimationState,
head_direction: usize,
direction: Direction,
color_external: Color,
color_internal: Color,
) {
let frame = self.get_frame(animation_state, camera, head_direction);
let frame = self.get_frame(animation_state, camera, direction);
let world_matrix = self.calculate_world_matrix(camera, frame, entity_position);
instructions.push(DebugRectangleInstruction {
world: world_matrix,
Expand Down
23 changes: 8 additions & 15 deletions korangar/src/world/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use korangar_networking::EntityData;
use korangar_util::pathing::{PathFinder, MAX_WALK_PATH_SIZE};
#[cfg(feature = "debug")]
use korangar_util::texture_atlas::AtlasAllocation;
use ragnarok_packets::{AccountId, CharacterInformation, ClientTick, EntityId, Sex, StatusType, WorldPosition};
use ragnarok_packets::{AccountId, CharacterInformation, ClientTick, Direction, EntityId, Sex, StatusType, WorldPosition};
#[cfg(feature = "debug")]
use wgpu::{BufferUsages, Device, Queue};

Expand Down Expand Up @@ -115,6 +115,7 @@ pub struct Common {
pub health_points: usize,
pub maximum_health_points: usize,
pub movement_speed: usize,
pub direction: Direction,
pub head_direction: usize,
pub sex: Sex,

Expand Down Expand Up @@ -345,6 +346,7 @@ impl Common {
let grid_position = Vector2::new(grid_position.x, grid_position.y);
let position = map.get_world_position(grid_position);
let head_direction = entity_data.head_direction;
let direction = entity_data.position.direction;

let movement_speed = entity_data.movement_speed as usize;
let health_points = entity_data.health_points as usize;
Expand Down Expand Up @@ -375,6 +377,7 @@ impl Common {
position,
entity_id,
job_id,
direction,
head_direction,
sex,
active_movement,
Expand Down Expand Up @@ -414,7 +417,7 @@ impl Common {
self.update_movement(map, client_tick);
self.animation_state.update(client_tick);

let frame = self.animation_data.get_frame(&self.animation_state, camera, self.head_direction);
let frame = self.animation_data.get_frame(&self.animation_state, camera, self.direction);
match frame.event {
Some(ActionEvent::Sound { key }) => {
self.sound_state.update(audio_engine, self.position, key, client_tick);
Expand Down Expand Up @@ -449,17 +452,7 @@ impl Common {

let array = last_step_position - next_step_position;
let array: &[isize; 2] = array.as_ref();
self.head_direction = match array {
[0, 1] => 0,
[1, 1] => 1,
[1, 0] => 2,
[1, -1] => 3,
[0, -1] => 4,
[-1, -1] => 5,
[-1, 0] => 6,
[-1, 1] => 7,
_ => panic!("impossible step"),
};
self.direction = (*array).into();

let last_step_position = map.get_world_position(last_step.arrival_position).to_vec();
let next_step_position = map.get_world_position(next_step.arrival_position).to_vec();
Expand Down Expand Up @@ -762,7 +755,7 @@ impl Common {
self.entity_id,
self.position,
&self.animation_state,
self.head_direction,
self.direction,
);
}

Expand All @@ -773,7 +766,7 @@ impl Common {
camera,
self.position,
&self.animation_state,
self.head_direction,
self.direction,
Color::rgb_u8(255, 0, 0),
Color::rgb_u8(0, 255, 0),
);
Expand Down
2 changes: 1 addition & 1 deletion ragnarok_packets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use ragnarok_procedural::{CharacterServer, ClientPacket, LoginServer, MapSer
#[cfg(not(feature = "derive"))]
use ragnarok_procedural::{CharacterServer, ClientPacket, LoginServer, MapServer, Packet, ServerPacket};

pub use self::position::{WorldPosition, WorldPosition2};
pub use self::position::{Direction, WorldPosition, WorldPosition2};

// To make proc macros work in korangar_interface.
extern crate self as ragnarok_packets;
Expand Down
121 changes: 101 additions & 20 deletions ragnarok_packets/src/position.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,77 @@
use ragnarok_bytes::{ByteReader, ConversionResult, FromBytes, ToBytes};
use ragnarok_bytes::{ByteConvertable, ByteReader, ConversionResult, FromBytes, ToBytes};

#[derive(Debug, Copy, Clone, ByteConvertable)]
#[cfg_attr(feature = "interface", derive(korangar_interface::elements::PrototypeElement))]
pub enum Direction {
N = 0,
NE = 1,
E = 2,
SE = 3,
S = 4,
SW = 5,
W = 6,
NW = 7,
}

impl From<Direction> for usize {
fn from(value: Direction) -> Self {
value as usize
}
}

impl From<usize> for Direction {
fn from(value: usize) -> Self {
let value = value & 7;

match value {
0 => Direction::N,
1 => Direction::NE,
2 => Direction::E,
3 => Direction::SE,
4 => Direction::S,
5 => Direction::SW,
6 => Direction::W,
7 => Direction::NW,
_ => unreachable!(),
}
}
}

impl From<[isize; 2]> for Direction {
fn from(value: [isize; 2]) -> Self {
match value {
[0, 1] => Direction::N,
[1, 1] => Direction::NE,
[1, 0] => Direction::E,
[1, -1] => Direction::SE,
[0, -1] => Direction::S,
[-1, -1] => Direction::SW,
[-1, 0] => Direction::W,
[-1, 1] => Direction::NW,
_ => panic!("impossible direction"),
}
}
}

#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "interface", derive(korangar_interface::elements::PrototypeElement))]
pub struct WorldPosition {
pub x: usize,
pub y: usize,
pub direction: Direction,
}

impl WorldPosition {
pub fn new(x: usize, y: usize) -> Self {
Self { x, y }
pub fn new(x: usize, y: usize, direction: Direction) -> Self {
Self { x, y, direction }
}

pub fn origin() -> Self {
Self {
x: 0,
y: 0,
direction: Direction::N,
}
}
}

Expand All @@ -19,19 +81,25 @@ impl FromBytes for WorldPosition {

let x = (coordinates[1] >> 6) | (coordinates[0] << 2);
let y = (coordinates[2] >> 4) | ((coordinates[1] & 0b111111) << 4);
//let direction = ...
let mut direction = coordinates[2] & 0b1111;
direction = (8 - direction + 4) & 7;

Ok(Self { x, y })
Ok(Self {
x,
y,
direction: direction.into(),
})
}
}

impl ToBytes for WorldPosition {
fn to_bytes(&self) -> ConversionResult<Vec<u8>> {
let mut coordinates = vec![0, 0, 0];
let direction = (8 - usize::from(self.direction) + 4) & 7;

coordinates[0] = (self.x >> 2) as u8;
coordinates[1] = ((self.x << 6) as u8) | (((self.y >> 4) & 0x3F) as u8);
coordinates[2] = (self.y << 4) as u8;
coordinates[2] = (self.y << 4) as u8 | (direction & 0xF) as u8;

Ok(coordinates)
}
Expand All @@ -44,18 +112,33 @@ pub struct WorldPosition2 {
pub y1: usize,
pub x2: usize,
pub y2: usize,
pub unknown: usize,
}

impl WorldPosition2 {
pub fn new(x1: usize, y1: usize, x2: usize, y2: usize) -> Self {
Self { x1, y1, x2, y2 }
Self {
x1,
y1,
x2,
y2,
unknown: 0,
}
}

pub fn to_origin_destination(self) -> (WorldPosition, WorldPosition) {
(WorldPosition { x: self.x1, y: self.y1 }, WorldPosition {
x: self.x2,
y: self.y2,
})
(
WorldPosition {
x: self.x1,
y: self.y1,
direction: Direction::N,
},
WorldPosition {
x: self.x2,
y: self.y2,
direction: Direction::N,
},
)
}
}

Expand All @@ -67,9 +150,9 @@ impl FromBytes for WorldPosition2 {
let y1 = (coordinates[2] >> 4) | ((coordinates[1] & 0b111111) << 4);
let x2 = (coordinates[3] >> 2) | ((coordinates[2] & 0b1111) << 6);
let y2 = coordinates[4] | ((coordinates[3] & 0b11) << 8);
//let direction = ...
let unknown = coordinates[5];

Ok(Self { x1, y1, x2, y2 })
Ok(Self { x1, y1, x2, y2, unknown })
}
}

Expand All @@ -82,6 +165,7 @@ impl ToBytes for WorldPosition2 {
bytes[2] = ((self.y1 << 4) as u8) | ((self.x2 >> 6) as u8);
bytes[3] = ((self.x2 << 2) as u8) | ((self.y2 >> 8) as u8);
bytes[4] = self.y2 as u8;
bytes[5] = self.unknown as u8;

Ok(bytes)
}
Expand All @@ -95,10 +179,9 @@ mod conversion {

#[test]
fn world_position() {
// Since we don't save the orientation when deserializing, this is a lossy
// operation. So we construct some test cases that igonore the bits in
// question.
let cases = [[255, 0, 0], [0, 255, 0], [0, 0, 240]];
// The direction must be between 0 and 7 inclusive.
let direction = [0, 3, 7];
let cases = [[255, 0, 0 + direction[0]], [0, 255, 0 + direction[1]], [0, 0, 240 + direction[2]]];

for case in cases {
let mut byte_reader = ragnarok_bytes::ByteReader::without_metadata(&case);
Expand All @@ -112,15 +195,13 @@ mod conversion {

#[test]
fn world_position_2() {
// Since we don't save the orientation when deserializing, this is a lossy
// operation. So we construct some test cases that igonore the bits in
// question.
let cases = [
[255, 0, 0, 0, 0, 0],
[0, 255, 0, 0, 0, 0],
[0, 0, 255, 0, 0, 0],
[0, 0, 0, 255, 0, 0],
[0, 0, 0, 0, 255, 0],
[0, 0, 0, 0, 0, 255],
];

for case in cases {
Expand Down

0 comments on commit 15b20ac

Please sign in to comment.