# SPG:Special Abilities

Notes:

## Spindash (Sonic 2, 3, & K)

```//Variables
spinrev: the amount a spindash has been charged

```

When you first begin the Spindash, spinrev is set to 0. With every press of the button, spinrev is increased by 2, up to a maximum of 8. Furthermore, during the entire time the Spindash is charging, spinrev is being affected by the following calculation:

```spinrev -= ((p div 0.125) / 256)   // "div" is division ignoring any remainder

```

This is exactly like the air drag calculation.

What this means is that the higher spinrev is, the faster it bleeds away toward zero.

When you release the Down button, the character launches forward at a speed of 8, plus floor(spinrev) - i.e. spinrev minus its fractional part (everything after the decimal point) - divided by 2.

```Ground Speed = 8 + (floor(spinrev) / 2)   // this would be negative if the character were facing left, of course

```

Because the higher spinrev is, the faster it depletes, it is nearly impossible to get maximum thrust from a Spindash without the aid of a Turbo controller or frame-by-frame play. However, if you were able to, the highest speed achievable through the Spindash is 12.

Note: Water has no effect on the release speed.

### Spindash (Sonic CD)

The Sonic CD style Spindash is much simpler. Many Sonic players may find it inferior to the Sonic 2 style, though, so you may not want to use it in your engine. Or, if you do, you might include a choice in the control options which one to use.

Once the button is pressed, Sonic will begin charging the Spindash. After 45 steps have passed, he is ready to go. When the Down button is released, Sonic launches at a speed of 12. If the Down button is released early, nothing happens.

### Drop Dash (Mania)

Constant Value Description
drpspd 8 The base speed for a drop dash.
drpmax 12 The top speed for a drop dash.
drpspdsup 12 The base speed for a drop dash while super.
drpmaxsup 13 The top speed for a drop dash while super.

The drop dash in Sonic Mania isn't simply an instant landing Spindash.

To charge Sonic up you release then hold the jump button while already jumping. The dash will take 20 frames to charge and once charged, when Sonic reaches the ground, your ground speed will be set. If the jump button is released before Sonic hits the ground, the move is cancelled.

As Sonic hits the ground, Sonic's Ground Speed is calculated as normal, this new Ground Speed will be used in calculating the drop dash speed.

The game checks if you were moving backwards in the air. By backwards, I mean opposite to the way you were facing/pushing. For example, if your X Speed was positive but you were holding & facing at the time this would count as backwards, same for the other direction. In either case, Sonic's actual direction is then set to that which you are facing/holding.

#### If you were moving forwards

Sonic's Ground Speed is set to his Ground Speed divided by 4, plus (or minus, depending on direction) drpspd. This speed is limited to drpmax.

`Ground Speed = (Ground Speed / 4) + (drpspd * direction)   //direction is either 1 (right) or -1 (left), this speed would then be limited between the min and max values of -drpmax and drpmax`

#### If you were going backwards

If Sonic's ang is 0 (flat), his Ground Speed is simply set to drpspd (or negative drpspd)

`Ground Speed = drpspd * direction`

Otherwise, on slopes, his Ground Speed is set in the same way as normal, but divided by 2 rather than 4. Of course, because you were moving backwards your Ground Speed will be opposite direction of that which the dash is trying to propel you, so this results in a rather slow dash.

`Ground Speed = (Ground Speed / 2) + (drpspd * direction)   // this speed would then be limited between the min and max values of -drpmax and drpmax`

A similar Camera Lag effect to that used when spin dashing is used here too, to make the move more dramatic.

## Dash (Super Peel Out)

Once the button is pressed, Sonic will begin charging the Dash. After 30 frames have passed, he is ready to go. When the Up button is released, Sonic launches at a speed of 12. If the Up button is released early, nothing happens.

## Insta-Shield

The Insta-Shield expands Sonic's hitbox giving it a width radius of 24 and a height radius of 24, resulting in an overall height of 49 x 49. This lasts for 14 frames.

The Insta-Shield does nothing to Sonic's X Speed or Y Speed. It does however allow him to control a rolling jump.

## Flying

When Tails begins to fly, his Y Speed is unaffected. However, since Tails has to release the button in order to press it again to fly, he can't possibly fly up faster than -4.

While flying, the variables are much like a standard jump. He accelerates at 0.09375 (24 subpixels), and there is no separate deceleration value. The normal air drag calculation is performed, which means Tails can't fly horizontally as fast while moving upward than when moving downward. The air drag cancels out the acceleration at an X Speed of 3. There is no air drag while moving down, though, so he can reach an 'X Speed' of 6, the normal maximum.

While flying, Gravity is 0.03125 (8 subpixels). Pressing Up or Down doesn't decrease or increase it.

Pressing the button doesn't cause an immediate loss of vertical speed (like a double-jump), but instead a temporary change in gravity. Gravity becomes -0.125 (-32 subpixels), and remains so until Y Speed is less than -1. Then Gravity returns to normal in the next step and Tails begins to fly back down. If Y Speed is already less than -1, pressing the button does nothing.

Tails can only fly for 480 frames, or 8 seconds, before getting tired. The only difference being tired makes (besides the pooped-out expression) is that pressing the button doesn't have any effect anymore. Gravity, and all other variables, remain the same.

As stated above if you have negative gravity, a Y Speed smaller than -1 is needed to return to positive gravity. This can cause issues when you hit a ceiling and your Y Speed is set to 0. Your Gravity will remain negative and you will be stuck. In your engine, to prevent Tails from being stuck in negative gravity, you should reset Gravity to the positive value when a ceiling is detected.

### Flying Attack

Tails' tails can be used to attack enemies while he is flying. They also deflect projectiles (just like the Shields do). When an enemy/projectile touches Tails' normal hitbox while he is flying, the angle between the enemy/projectile's X/Y Position and Tails' X/Y Position is measured. If and that angle is within 46° (223) to 135° (160) inclusive (a 90 degree slice directly above Tails). the enemy will be destroyed (or projectile bounced).

## Gliding

When Knuckles first begins gliding, his X Speed is set to 4 in the direction he is facing. Y Speed is set to 0, but only if it was negative at the time, otherwise it is unaffected. X Speed then accelerates by 0.015625 (4 subpixels) every step.

Gliding has a top speed of 24. This top speed is so high that it is unreachable anywhere in the game -- except for Mushroom Hill Zone Act 1, where Super/Hyper Knuckles can glide across the top of the level to achieve this speed.

During the glide, gravity is 0.125 (32 subpixels), which is weaker than usual. Also, unlike a normal jump, gravity is only added while Y Speed is less than 0.5 (128 subpixels). If Y Speed is higher than that (say Knuckles was falling quickly when he began to glide), gravity is subtracted from Y Speed instead, slowing his descent.

```if (Y Speed < 0.5) Y Speed += 0.125;
if (Y Speed > 0.5) Y Speed -= 0.125;```

When you let go of the button, Knuckles drops, and his X Speed is multiplied by 0.25. When he hits the ground, it is set to 0. While dropping from a glide, Gravity is the normal value.

If you don't release the button, but allow Knuckles to glide into the ground he will begin to slide.

If Knuckles hits a wall while gliding, he catches on, and can climb it. He will catch on even if he's turning around, as long as his X Speed is still in the direction of the wall.

### Turning Around

When Knuckles is gliding, you can turn him around simply by tapping the or button. Even if you let go, he will continue to make a full turn. You can, however, reverse your decision and turn him back in the original direction before he makes a full turn.

You might think that turning around while gliding would be much like turning around while running on the ground. X Speed would be steadily decreased until it reached zero, and then would start adding in the other direction. This is not the case, though, and a special method is used that preserves Knuckles' gliding speed.

When Knuckles is gliding, there is a value, which we'll call a, that is 0 when he's gliding to the right, and 180 when he's gliding to the left.

When Knuckles begins to turn, his X Speed is stored - let's call the stored value t. If he's turning from the left to the right, a is decreased by 2.8125 (2 pixels and 208 subpixels) until it reaches 0 (which takes 64 steps). If he's turning from right to left, a is increased by 2.8125 (2 pixels and 208 subpixels) until it reaches 180. During the turn X speed is made to equal t times the cosine of a.

```a += 2.8125 * -sign(t);
X Speed = t * cosine(a);```

So, no matter how fast Knuckles is gliding, he turns around in the same amount of time, and his speed reverses fully. During the turn, there is no acceleration. It kicks back in once he's finished turning all the way around.

### Gliding Rebound

An interesting side-effect of the fact that Knuckles' Y Speed is not immediately blunted when he begins gliding while falling quickly is the "Gliding Rebound". If you press the button to begin gliding just as Knuckles connects with an enemy or item monitor, his Y Speed is reversed from the rebound just as he begins to glide. Since gliding gravity is weaker than standard gravity, he goes soaring up into the air. This is not necessarily a bug - it's actually kind of fun.

Once Knuckles is already gliding, rebound operates normally. Since he can't exceed a Y Speed of 0.5 (128 subpixels) while gliding, though, the effect is rather weak.

### Underwater

Strangely enough, Knuckles' gliding and climbing physics are totally unaffected by water. I suspect this is because the code performed when entering and exiting the water simply changes the acceleration, deceleration, and top speed constants (this is why falling in water nullifies Super Fast Shoes). Because Knuckles' gliding and climbing code operates irrespective of these values, his abilities couldn't be affected by water without rewriting the water entry and exit code. In your engine you may wish to halve some of Knuckles' speeds when submerged to be more realistic, unless you want to remain 100% true to the original games.

### Sliding

When you finish a glide by sliding on the ground, the game doesn't set Knuckles' grounded flag until he stops. Though, he mostly acts grounded, sticking to the floor and changing his angle as normal.

While sliding on his stomach, he has a friction value of 0.125 (32 subpixels). He starts to stand up as soon as X Speed reaches 0. If you release the button after he has begun to slide, X Speed is set to 0 immediately, and he begins to stand up. Pressing or while sliding or standing up has no effect, but you can break into the standing up animation to jump if you press the jump button again.

### Gliding Attack

Knuckles will attack enemies while he is gliding or sliding. He will also deflect projectiles (just like the Shields do).

This happens when an enemy/projectile touches Knuckles' normal hitbox any time he is in either the gliding or sliding state, no matter where the enemy is in relation.

## Climbing

He climbs up and down at a speed of 1. When Knuckles jumps off of a wall, his X Speed is set to 4 in the opposite direction of the wall, and his Y Speed is set to -4.

Interestingly, because of a pixel offset when sprites are flipped, Knuckles' feet poke 1 pixel out from the side of his size when he is on a wall to the left. This means his feet should be inside the wall a bit. Well, when on a left wall there is actually a 1 pixel gap between Knuckles' X Position - Push Radius and the wall, purely to make it look correct.

### Falling

When climbing, Knuckles will fall off the bottom of a wall if no wall is found at his Y Position + Height Radius (checking horizontally into the wall).

### Clambering

Knuckles will clamber atop a ledge if it no wall is found at his Y Position - Height Radius (checking horizontally into the wall).

When clambering, Knuckles plays a 3 sub-image animation. Each sub-image of the animation lasts 6 frames, and after the 3rd sub-image knuckles is standing on the ledge, where his X Position is the ledge X. Each frame of the animation moves knuckles to a new position as shown.

His position moves back and forth a bit as he climbs so that his sprite aligns. If your camera is set up correctly, usually the first 2 sub-images of motion will push the camera forward into place and the 3rd sub-image's backward motion won't move the camera at all, which makes it look smooth enough.

### Stopping at Floors and Ceilings

If there is a floor that meets the wall, he will stop climbing down when the floor is within around 19 pixels of his Y Position (so, his normal Height Radius).