Skip to content

Flying and Ceiling Actors

Actors can be positioned in the air or attached to the ceiling. Both require specific flags and movement functions.

Flying actors

Set ACTOR_FLAG_FLYING on the blueprint to make the actor airborne:

export ActorBlueprint blueprint = {
    .flags = ACTOR_FLAG_FLYING,
    // ...
};

Flying actors use different movement functions than ground actors:

Ground functionFlying equivalent
RunToGoalFlyToGoal
IdleRunToGoalIdleFlyToGoal
// flying movement (in EVS_Idle or EVS_TakeTurn)
Call(SetActorSpeed,actorID ACTOR_SELF,moveSpeed Float(6.0))
Call(FlyToGoal,
    actorID ACTOR_SELF,duration 0,arcHeight -4,easing EASING_LINEAR)

The third argument to FlyToGoal is the arc height (negative = bob downward), and the fourth is the easing function.

Knockdown

A flying actor can be grounded by attacks. Handle EVENT_FALL_TRIGGER in EVS_HandleEvent to trigger a knockdown sequence:

CaseEq(EVENT_FALL_TRIGGER)
    SetConst(LVar0, PRT_FLYING)
    SetConst(LVar1, ANIM_Paragoomba_Hurt)
    ExecWait(EVS_Enemy_Hit)
    ExecWait(EVS_KnockDown)

A knockdown typically involves:

  • Swapping visible parts (hide flying body, show grounded body)
  • Removing the ACTOR_FLAG_FLYING flag
  • Changing the status table
  • Moving the actor's home position to the ground tier
  • Rebinding scripts to downed versions

See src/battle/actor/paragoomba.c for a complete flying-to-grounded transition.

Ceiling actors

Set ACTOR_FLAG_UPSIDE_DOWN to make an actor hang from the ceiling:

export ActorBlueprint blueprint = {
    .flags = ACTOR_FLAG_UPSIDE_DOWN,
    // ...
    .statusIconOffset = { -10, -20 },
    .statusTextOffset = { 10, -20 },
};

You can toggle the flag at runtime when the actor detaches from the ceiling:

// detach from ceiling
Call(SetActorFlagBits,
    actorID ACTOR_SELF,flags ACTOR_FLAG_UPSIDE_DOWN,mode false)

Ceiling + spiky

Ceiling actors are often combined with spiky flags. For example, Spike Top uses both ACTOR_FLAG_UPSIDE_DOWN and ACTOR_EVENT_FLAG_SPIKY_TOP:

export ActorBlueprint blueprint = {
    .flags = ACTOR_FLAG_UPSIDE_DOWN,
    // ...
};

ActorPartBlueprint ActorParts[] = {
    {
        // ...
        .eventFlags = ACTOR_EVENT_FLAG_SPIKY_TOP | ACTOR_EVENT_FLAG_FLIPABLE,
    },
};

For ceiling actor examples, see src/battle/actor/swooper.c (simple) and src/battle/actor/spike_top.c (ceiling + spiky + flipable).