Skip to content

Commit 02fa0e8

Browse files
world/viewer.go: Allow for more complex entity animations to be played (#940)
1 parent f660027 commit 02fa0e8

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

server/session/world.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,12 @@ func (s *Session) ViewEntityState(e world.Entity) {
976976
}
977977

978978
// ViewEntityAnimation ...
979-
func (s *Session) ViewEntityAnimation(e world.Entity, animationName string) {
979+
func (s *Session) ViewEntityAnimation(e world.Entity, a world.EntityAnimation) {
980980
s.writePacket(&packet.AnimateEntity{
981-
Animation: animationName,
981+
Animation: a.Name(),
982+
NextState: a.NextState(),
983+
StopCondition: a.StopCondition(),
984+
Controller: a.Controller(),
982985
EntityRuntimeIDs: []uint64{
983986
s.entityRuntimeID(e),
984987
},

server/world/entity_animation.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package world
2+
3+
// EntityAnimation represents an animation that may be played on an entity from an active resource pack on
4+
// the client.
5+
type EntityAnimation struct {
6+
name string
7+
nextState string
8+
controller string
9+
stopCondition string
10+
}
11+
12+
// NewEntityAnimation returns a new animation that can be played on an entity. If no controller or stop
13+
// condition is set, the animation will play for its full duration, including looping. Controllers can be set
14+
// to manage multiple states of animations. It is also possible to use vanilla animations/controllers if they
15+
// work for your entity, i.e. "animation.pig.baby_transform".
16+
func NewEntityAnimation(name string) EntityAnimation {
17+
return EntityAnimation{name: name}
18+
}
19+
20+
// Name returns the name of the animation to be played.
21+
func (a EntityAnimation) Name() string {
22+
return a.name
23+
}
24+
25+
// Controller returns the name of the controller to be used for the animation.
26+
func (a EntityAnimation) Controller() string {
27+
return a.controller
28+
}
29+
30+
// WithController returns a copy of the EntityAnimation with the provided animation controller. An animation
31+
// controller with the same name must be defined in a resource pack for it to work.
32+
func (a EntityAnimation) WithController(controller string) EntityAnimation {
33+
a.controller = controller
34+
return a
35+
}
36+
37+
// NextState returns the state to transition to after the animation has finished playing within the
38+
// animation controller.
39+
func (a EntityAnimation) NextState() string {
40+
return a.nextState
41+
}
42+
43+
// WithNextState returns a copy of the EntityAnimation with the provided state to transition to after the
44+
// animation has finished playing within the animation controller.
45+
func (a EntityAnimation) WithNextState(state string) EntityAnimation {
46+
a.nextState = state
47+
return a
48+
}
49+
50+
// StopCondition returns the condition that must be met for the animation to stop playing. This is often
51+
// a Molang expression that can be used to query various entity properties to determine when the animation
52+
// should stop playing.
53+
func (a EntityAnimation) StopCondition() string {
54+
return a.stopCondition
55+
}
56+
57+
// WithStopCondition returns a copy of the EntityAnimation with the provided stop condition. The stop condition
58+
// is a Molang expression that can be used to query various entity properties to determine when the animation
59+
// should stop playing.
60+
func (a EntityAnimation) WithStopCondition(condition string) EntityAnimation {
61+
a.stopCondition = condition
62+
return a
63+
}

server/world/tx.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ func (tx *Tx) AddParticle(pos mgl64.Vec3, p Particle) {
158158
tx.World().addParticle(pos, p)
159159
}
160160

161+
// PlayEntityAnimation plays an animation on an entity in the World. The animation is played for all viewers
162+
// of the entity.
163+
func (tx *Tx) PlayEntityAnimation(e Entity, a EntityAnimation) {
164+
for _, viewer := range tx.World().viewersOf(e.Position()) {
165+
viewer.ViewEntityAnimation(e, a)
166+
}
167+
}
168+
161169
// PlaySound plays a sound at a specific position in the World. Viewers of that
162170
// position will be able to hear the sound if they are close enough.
163171
func (tx *Tx) PlaySound(pos mgl64.Vec3, s Sound) {

server/world/viewer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ type Viewer interface {
4949
// ViewEntityState views the current state of an Entity. It is called whenever an Entity changes its
5050
// physical appearance, for example when sprinting.
5151
ViewEntityState(e Entity)
52-
// ViewEntityAnimation starts viewing an animation performed by an Entity. The animation has to be from a resource pack.
53-
ViewEntityAnimation(e Entity, animationName string)
52+
// ViewEntityAnimation starts viewing an animation performed by an Entity.
53+
ViewEntityAnimation(e Entity, a EntityAnimation)
5454
// ViewParticle views a particle spawned at a given position in the world. It is called when a particle,
5555
// for example a block breaking particle, is spawned near the player.
5656
ViewParticle(pos mgl64.Vec3, p Particle)
@@ -91,7 +91,7 @@ func (NopViewer) ViewEntityItems(Entity)
9191
func (NopViewer) ViewEntityArmour(Entity) {}
9292
func (NopViewer) ViewEntityAction(Entity, EntityAction) {}
9393
func (NopViewer) ViewEntityState(Entity) {}
94-
func (NopViewer) ViewEntityAnimation(Entity, string) {}
94+
func (NopViewer) ViewEntityAnimation(Entity, EntityAnimation) {}
9595
func (NopViewer) ViewParticle(mgl64.Vec3, Particle) {}
9696
func (NopViewer) ViewSound(mgl64.Vec3, Sound) {}
9797
func (NopViewer) ViewBlockUpdate(cube.Pos, Block, int) {}

0 commit comments

Comments
 (0)