From 776f5199e95a40be4dc47c358065605dde66c899 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Mon, 7 Oct 2024 06:32:57 +0300 Subject: [PATCH] character: Add start to idle animation sequence If "start" and "start_to_idle" animations are set up, put the character in "start" until motion controls wake it up and play "start_to_idle" before transitioning to "idle" and motion controls become available. Signed-off-by: Alexander Shishkin --- core/character.c | 22 ++++++++++++++++++++++ core/character.h | 7 +++++++ core/scene.c | 8 ++++++++ 3 files changed, 37 insertions(+) diff --git a/core/character.c b/core/character.c index 8a64244..5d5e8ea 100644 --- a/core/character.c +++ b/core/character.c @@ -159,6 +159,15 @@ bool character_is_grounded(struct character *ch, struct scene *s) return false; } +static void character_idle(struct scene *s, void *priv) +{ + struct character *c = priv; + + c->state = CS_AWAKE; + anictl_set_state(&c->anictl, 0); + animation_push_by_name(c->entity, s, "idle", true, true); +} + void character_move(struct character *ch, struct scene *s) { struct phys_body *body = ch->entity->phys_body; @@ -185,6 +194,18 @@ void character_move(struct character *ch, struct scene *s) } ch->ragdoll = body ? !phys_body_ground_collide(body) : 0; + + if (ch->state == CS_START) { + if (ch->mctl.ls_dx || ch->mctl.ls_dy) { + ch->state = CS_WAKING; + animation_push_by_name(ch->entity, s, "start_to_idle", true, false); + animation_set_end_callback(ch->entity, character_idle, ch); + } + return; + } else if (ch->state < CS_AWAKE) { + return; + } + if (ch->ragdoll) { dJointSetLMotorParam(body->lmotor, dParamVel1, 0); dJointSetLMotorParam(body->lmotor, dParamVel2, 0); @@ -453,6 +474,7 @@ struct character *character_new(struct model3dtx *txm, struct scene *s) c->entity->priv = c; c->orig_update = c->entity->update; c->entity->update = character_update; + c->state = CS_AWAKE; list_append(&s->characters, &c->entry); motion_reset(&c->mctl, s); diff --git a/core/character.h b/core/character.h index 0b48e9b..2a9871b 100644 --- a/core/character.h +++ b/core/character.h @@ -31,6 +31,12 @@ struct motionctl { bool jump; }; +enum character_state { + CS_START = 0, + CS_WAKING, + CS_AWAKE +}; + struct character { struct ref ref; struct entity3d *entity; @@ -55,6 +61,7 @@ struct character { int stuck; bool dashing; bool jumping; + enum character_state state; }; static inline struct entity3d *character_entity(struct character *c) diff --git a/core/scene.c b/core/scene.c index 5a8d856..09bdc9a 100644 --- a/core/scene.c +++ b/core/scene.c @@ -587,6 +587,14 @@ static int model_new_from_json(struct scene *scene, JsonNode *node) free(m->anis.x[idx].name); m->anis.x[idx].name = strdup(p->key); } + + if (c && + animation_by_name(e->txmodel->model, "start") >= 0 && + animation_by_name(e->txmodel->model, "start_to_idle") >= 0) { + c->anictl.state = UINT_MAX; + c->state = CS_START; + animation_push_by_name(e, scene, "start", true, true); + } } } } else {