Files
legacy-version/legacyver/proto/camera.go
2025-06-20 02:11:25 +07:00

231 lines
9.5 KiB
Go

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)
}
}