package proto import ( "github.com/go-gl/mathgl/mgl32" "github.com/sandertv/gophertunnel/minecraft/protocol" ) // CameraPreset represents a basic preset that can be extended upon by more complex instructions. type CameraPreset struct { // Name is the name of the preset. Each preset must have their own unique name. Name string // Parent is the name of the preset that this preset extends upon. This can be left empty. Parent string // PosX is the default X position of the camera. PosX protocol.Optional[float32] // PosY is the default Y position of the camera. PosY protocol.Optional[float32] // PosZ is the default Z position of the camera. PosZ protocol.Optional[float32] // RotX is the default pitch of the camera. RotX protocol.Optional[float32] // RotY is the default yaw of the camera. RotY protocol.Optional[float32] // RotationSpeed is the speed at which the camera should rotate. RotationSpeed protocol.Optional[float32] // SnapToTarget determines whether the camera should snap to the target entity or not. SnapToTarget protocol.Optional[bool] // HorizontalRotationLimit is the horizontal rotation limit of the camera. HorizontalRotationLimit protocol.Optional[mgl32.Vec2] // VerticalRotationLimit is the vertical rotation limit of the camera. VerticalRotationLimit protocol.Optional[mgl32.Vec2] // ContinueTargeting determines whether the camera should continue targeting when using aim assist. ContinueTargeting protocol.Optional[bool] // TrackingRadius is the radius around the camera that the aim assist should track targets. TrackingRadius protocol.Optional[float32] // ViewOffset is only used in a follow_orbit camera and controls an offset based on a pivot point to the // player, causing it to be shifted in a certain direction. ViewOffset protocol.Optional[mgl32.Vec2] // EntityOffset controls the offset from the entity that the camera should be rendered at. EntityOffset protocol.Optional[mgl32.Vec3] // Radius is only used in a follow_orbit camera and controls how far away from the player the camera should // be rendered. Radius protocol.Optional[float32] // MinYawLimit is the minimum yaw limit of the camera. MinYawLimit protocol.Optional[float32] // MaxYawLimit is the maximum yaw limit of the camera. MaxYawLimit protocol.Optional[float32] // AudioListener defines where the audio should be played from when using this preset. This is one of the // constants above. AudioListener protocol.Optional[byte] // PlayerEffects is currently unknown. PlayerEffects protocol.Optional[bool] // AlignTargetAndCameraForward determines whether the camera should align the target and the camera forward // or not. AlignTargetAndCameraForward protocol.Optional[bool] // AimAssist defines the aim assist to use when using this preset. AimAssist protocol.Optional[protocol.CameraPresetAimAssist] // ControlScheme is the control scheme that the client should use in this camera. It is one of the following: // - ControlSchemeLockedPlayerRelativeStrafe is the default behaviour, this cannot be set when the client // is in a custom camera. // - ControlSchemeCameraRelative makes movement relative to the camera's transform, with the client's // rotation being relative to the client's movement. // - ControlSchemeCameraRelativeStrafe makes movement relative to the camera's transform, with the // client's rotation being locked. // - ControlSchemePlayerRelative makes movement relative to the player's transform, meaning holding // left/right will make the player turn in a circle. // - ControlSchemePlayerRelativeStrafe makes movement the same as the default behaviour, but can be // used in a custom camera. ControlScheme protocol.Optional[byte] } func (x *CameraPreset) FromLatest(cp protocol.CameraPreset) CameraPreset { x.Name = cp.Name x.Parent = cp.Parent x.PosX = cp.PosX x.PosY = cp.PosY x.PosZ = cp.PosZ x.RotX = cp.RotX x.RotY = cp.RotY x.RotationSpeed = cp.RotationSpeed x.SnapToTarget = cp.SnapToTarget x.HorizontalRotationLimit = cp.HorizontalRotationLimit x.VerticalRotationLimit = cp.VerticalRotationLimit x.ContinueTargeting = cp.ContinueTargeting x.TrackingRadius = cp.TrackingRadius x.ViewOffset = cp.ViewOffset x.EntityOffset = cp.EntityOffset x.Radius = cp.Radius x.AudioListener = cp.AudioListener x.PlayerEffects = cp.PlayerEffects x.AimAssist = cp.AimAssist x.ControlScheme = cp.ControlScheme return *x } func (x *CameraPreset) ToLatest() protocol.CameraPreset { return protocol.CameraPreset{ Name: x.Name, Parent: x.Parent, PosX: x.PosX, PosY: x.PosY, PosZ: x.PosZ, RotX: x.RotX, RotY: x.RotY, RotationSpeed: x.RotationSpeed, SnapToTarget: x.SnapToTarget, HorizontalRotationLimit: x.HorizontalRotationLimit, VerticalRotationLimit: x.VerticalRotationLimit, ContinueTargeting: x.ContinueTargeting, TrackingRadius: x.TrackingRadius, ViewOffset: x.ViewOffset, EntityOffset: x.EntityOffset, Radius: x.Radius, MinYawLimit: x.MinYawLimit, MaxYawLimit: x.MaxYawLimit, AudioListener: x.AudioListener, PlayerEffects: x.PlayerEffects, AimAssist: x.AimAssist, ControlScheme: x.ControlScheme, } } // Marshal encodes/decodes a CameraPreset. func (x *CameraPreset) Marshal(r protocol.IO) { r.String(&x.Name) r.String(&x.Parent) protocol.OptionalFunc(r, &x.PosX, r.Float32) protocol.OptionalFunc(r, &x.PosY, r.Float32) protocol.OptionalFunc(r, &x.PosZ, r.Float32) protocol.OptionalFunc(r, &x.RotX, r.Float32) protocol.OptionalFunc(r, &x.RotY, r.Float32) if IsProtoGTE(r, ID729) { protocol.OptionalFunc(r, &x.RotationSpeed, r.Float32) protocol.OptionalFunc(r, &x.SnapToTarget, r.Bool) } if IsProtoGTE(r, ID748) { protocol.OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2) protocol.OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2) protocol.OptionalFunc(r, &x.ContinueTargeting, r.Bool) } if IsProtoGTE(r, ID766) { protocol.OptionalFunc(r, &x.TrackingRadius, r.Float32) } if IsProtoGTE(r, ID776) { protocol.OptionalFunc(r, &x.MinYawLimit, r.Float32) protocol.OptionalFunc(r, &x.MaxYawLimit, r.Float32) } protocol.OptionalFunc(r, &x.ViewOffset, r.Vec2) if IsProtoGTE(r, ID729) { protocol.OptionalFunc(r, &x.EntityOffset, r.Vec3) } protocol.OptionalFunc(r, &x.Radius, r.Float32) protocol.OptionalFunc(r, &x.AudioListener, r.Uint8) protocol.OptionalFunc(r, &x.PlayerEffects, r.Bool) if IsProtoGTE(r, ID748) && IsProtoLT(r, ID818) { protocol.OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool) } if IsProtoGTE(r, ID766) { protocol.OptionalMarshaler(r, &x.AimAssist) } if IsProtoGTE(r, ID800) { protocol.OptionalFunc(r, &x.ControlScheme, r.Uint8) } } // CameraInstructionSet represents a camera instruction that sets the camera to a specified preset and can be extended // with easing functions and translations to the camera's position and rotation. type CameraInstructionSet struct { // Preset is the index of the preset in the CameraPresets packet sent to the player. Preset uint32 // Ease represents the easing function that is used by the instruction. Ease protocol.Optional[protocol.CameraEase] // Position represents the position of the camera. Position protocol.Optional[mgl32.Vec3] // Rotation represents the rotation of the camera. Rotation protocol.Optional[mgl32.Vec2] // Facing is a vector that the camera will always face towards during the duration of the instruction. Facing protocol.Optional[mgl32.Vec3] // ViewOffset is an offset based on a pivot point to the player, causing the camera to be shifted in a // certain direction. ViewOffset protocol.Optional[mgl32.Vec2] // EntityOffset is an offset from the entity that the camera should be rendered at. EntityOffset protocol.Optional[mgl32.Vec3] // Default determines whether the camera is a default camera or not. Default protocol.Optional[bool] // IgnoreStartingValuesComponent behavior is currently unknown. IgnoreStartingValuesComponent bool } func (x *CameraInstructionSet) FromLatest(cis protocol.CameraInstructionSet) CameraInstructionSet { x.Preset = cis.Preset x.Ease = cis.Ease x.Position = cis.Position x.Rotation = cis.Rotation x.Facing = cis.Facing x.ViewOffset = cis.ViewOffset x.EntityOffset = cis.EntityOffset x.Default = cis.Default x.IgnoreStartingValuesComponent = cis.IgnoreStartingValuesComponent return *x } func (x *CameraInstructionSet) ToLatest() protocol.CameraInstructionSet { return protocol.CameraInstructionSet{ Preset: x.Preset, Ease: x.Ease, Position: x.Position, Rotation: x.Rotation, Facing: x.Facing, ViewOffset: x.ViewOffset, EntityOffset: x.EntityOffset, Default: x.Default, IgnoreStartingValuesComponent: x.IgnoreStartingValuesComponent, } } // Marshal encodes/decodes a CameraInstructionSet. func (x *CameraInstructionSet) Marshal(r protocol.IO) { r.Uint32(&x.Preset) protocol.OptionalMarshaler(r, &x.Ease) protocol.OptionalFunc(r, &x.Position, r.Vec3) protocol.OptionalFunc(r, &x.Rotation, r.Vec2) protocol.OptionalFunc(r, &x.Facing, r.Vec3) protocol.OptionalFunc(r, &x.ViewOffset, r.Vec2) protocol.OptionalFunc(r, &x.EntityOffset, r.Vec3) protocol.OptionalFunc(r, &x.Default, r.Bool) if IsProtoGTE(r, ID818) { r.Bool(&x.IgnoreStartingValuesComponent) } }