diff --git a/.vscode/settings.json b/.vscode/settings.json index 50efcaab7..79bc37c80 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -234,7 +234,7 @@ "clear_pipe.h": "c", "slowing_snow.h": "c", "handlers_ia_pipe_horn_sequences.h": "c", - "sky_canyon_init.h": "c", + "sky_canyon_level_task.h": "c", "mon.h": "c", "kura_kura.h": "c", "star.h": "c", @@ -325,7 +325,7 @@ "kubinaga.h": "c", "propeller.h": "c", "game_3.h": "c", - "propeller_spring.h": "c", + "flying_spring.h": "c", "sprite_data.h": "c", "game_2.h": "c", "palette_loader.h": "c", diff --git a/data/sa2/maps/zone_5/act_1/entities/interactables.csv b/data/sa2/maps/zone_5/act_1/entities/interactables.csv index e25716fe1..8c17bea74 100644 --- a/data/sa2/maps/zone_5/act_1/entities/interactables.csv +++ b/data/sa2/maps/zone_5/act_1/entities/interactables.csv @@ -3,20 +3,20 @@ Adv2,INTERACTABLES,65,20,,,,, 32,0,8,6,SPECIAL_RING,0,0,0,0 33,0,30,17,PLATFORM_SQUARE,0,-4,0,8 33,0,13,17,PLATFORM_SQUARE,-4,0,8,0 -34,0,11,20,PROPELLER_SPRING,0,0,0,0 -34,0,22,16,PROPELLER_SPRING,0,0,0,0 +34,0,11,20,FLYING_SPRING,0,0,0,0 +34,0,22,16,FLYING_SPRING,0,0,0,0 35,0,29,24,SPIKES__HIDING_UP,0,0,0,0 -35,0,13,24,PROPELLER_SPRING,0,0,0,0 -35,0,1,21,PROPELLER_SPRING,0,0,0,0 -36,0,11,25,PROPELLER_SPRING,0,0,0,0 -36,0,23,21,PROPELLER_SPRING,0,0,0,0 -37,0,2,26,PROPELLER_SPRING,0,0,0,0 -37,0,14,22,PROPELLER_SPRING,0,0,0,0 -37,0,26,26,PROPELLER_SPRING,0,0,0,0 +35,0,13,24,FLYING_SPRING,0,0,0,0 +35,0,1,21,FLYING_SPRING,0,0,0,0 +36,0,11,25,FLYING_SPRING,0,0,0,0 +36,0,23,21,FLYING_SPRING,0,0,0,0 +37,0,2,26,FLYING_SPRING,0,0,0,0 +37,0,14,22,FLYING_SPRING,0,0,0,0 +37,0,26,26,FLYING_SPRING,0,0,0,0 42,0,12,30,GRIND_RAIL__START_AIR,-12,-3,24,3 -46,0,22,31,PROPELLER_SPRING,0,0,0,0 -47,0,1,29,PROPELLER_SPRING,0,0,0,0 -47,0,14,31,PROPELLER_SPRING,0,0,0,0 +46,0,22,31,FLYING_SPRING,0,0,0,0 +47,0,1,29,FLYING_SPRING,0,0,0,0 +47,0,14,31,FLYING_SPRING,0,0,0,0 50,0,8,28,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,22 50,0,8,24,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,24,4 50,0,12,28,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,24 @@ -83,9 +83,9 @@ Adv2,INTERACTABLES,65,20,,,,, 50,2,20,8,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,12 51,2,30,2,SMALL_WINDMILL,15,0,0,0 53,2,11,20,TOGGLE__GOAL,0,0,0,0 -27,3,29,31,PROPELLER_SPRING,0,0,0,0 -28,3,9,28,PROPELLER_SPRING,0,0,0,0 -28,3,21,31,PROPELLER_SPRING,0,0,0,0 +27,3,29,31,FLYING_SPRING,0,0,0,0 +28,3,9,28,FLYING_SPRING,0,0,0,0 +28,3,21,31,FLYING_SPRING,0,0,0,0 29,3,17,24,RAMP,1,0,0,0 31,3,16,12,WHIRLWIND__B,0,-12,12,12 32,3,8,0,FAN__RIGHT,0,-12,12,12 @@ -228,8 +228,8 @@ Adv2,INTERACTABLES,65,20,,,,, 23,7,12,28,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,16 23,7,8,24,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,8,4 24,7,22,16,SPRING__UP,0,0,0,0 -26,7,24,11,PROPELLER_SPRING,0,0,0,0 -27,7,4,3,PROPELLER_SPRING,0,0,0,0 +26,7,24,11,FLYING_SPRING,0,0,0,0 +27,7,4,3,FLYING_SPRING,0,0,0,0 28,7,16,18,SPRING__BIG_UPRIGHT,1,0,0,0 30,7,30,16,SMALL_WINDMILL,2,0,0,0 35,7,18,28,SPRING__UP,0,0,0,0 @@ -246,20 +246,20 @@ Adv2,INTERACTABLES,65,20,,,,, 29,8,18,8,SPIKES__HIDING_UP,0,0,0,0 29,8,29,10,PROPELLER,0,0,0,0 29,8,8,10,SPRING__BIG_UPLEFT,1,0,0,0 -32,8,2,17,PROPELLER_SPRING,0,0,0,0 -32,8,14,15,PROPELLER_SPRING,0,0,0,0 -32,8,26,19,PROPELLER_SPRING,0,0,0,0 -33,8,5,14,PROPELLER_SPRING,0,0,0,0 +32,8,2,17,FLYING_SPRING,0,0,0,0 +32,8,14,15,FLYING_SPRING,0,0,0,0 +32,8,26,19,FLYING_SPRING,0,0,0,0 +33,8,5,14,FLYING_SPRING,0,0,0,0 33,8,24,14,FAN__RIGHT,0,-12,12,12 37,8,16,10,SPRING__BIG_UPRIGHT,1,0,0,0 -10,9,11,31,PROPELLER_SPRING,0,0,0,0 +10,9,11,31,FLYING_SPRING,0,0,0,0 10,9,28,19,SPECIAL_RING,0,0,0,0 -11,9,14,28,PROPELLER_SPRING,0,0,0,0 -12,9,6,28,PROPELLER_SPRING,0,0,0,0 -12,9,16,31,PROPELLER_SPRING,0,0,0,0 -20,9,13,27,PROPELLER_SPRING,0,0,0,0 -20,9,4,18,PROPELLER_SPRING,0,0,0,0 -20,9,13,8,PROPELLER_SPRING,0,0,0,0 +11,9,14,28,FLYING_SPRING,0,0,0,0 +12,9,6,28,FLYING_SPRING,0,0,0,0 +12,9,16,31,FLYING_SPRING,0,0,0,0 +20,9,13,27,FLYING_SPRING,0,0,0,0 +20,9,4,18,FLYING_SPRING,0,0,0,0 +20,9,13,8,FLYING_SPRING,0,0,0,0 20,9,28,0,BOOSTER,0,0,0,0 22,9,21,24,TOGGLE__CHECKPOINT,0,0,0,0 22,9,21,0,TOGGLE__CHECKPOINT,0,0,0,0 @@ -283,7 +283,7 @@ Adv2,INTERACTABLES,65,20,,,,, 38,9,2,12,BOOSTER,0,1,0,0 38,9,8,26,WHIRLWIND__B,0,-14,12,28 8,10,30,28,DASH_RING,1,0,0,0 -11,10,26,0,PROPELLER_SPRING,0,0,0,0 +11,10,26,0,FLYING_SPRING,0,0,0,0 12,10,20,16,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,14 12,10,16,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,14 12,10,16,12,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,8,4 @@ -304,8 +304,8 @@ Adv2,INTERACTABLES,65,20,,,,, 32,10,20,28,FAN__LEFT,-12,-12,12,12 32,10,2,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,12 32,10,20,30,SPIKES__NORMAL_RIGHT,0,0,0,0 -34,10,26,30,PROPELLER_SPRING,0,0,0,0 -35,10,6,31,PROPELLER_SPRING,0,0,0,0 +34,10,26,30,FLYING_SPRING,0,0,0,0 +35,10,6,31,FLYING_SPRING,0,0,0,0 36,10,21,28,RAMP,1,0,0,0 37,10,23,23,SMALL_WINDMILL,1,0,0,0 37,10,16,7,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,12,4 @@ -326,8 +326,8 @@ Adv2,INTERACTABLES,65,20,,,,, 25,11,26,20,SPRING__UP,2,0,0,0 26,11,2,8,BOOSTER,0,0,0,0 30,11,18,15,SMALL_WINDMILL,15,0,0,0 -32,11,31,3,PROPELLER_SPRING,0,0,0,0 -34,11,22,6,PROPELLER_SPRING,0,0,0,0 +32,11,31,3,FLYING_SPRING,0,0,0,0 +34,11,22,6,FLYING_SPRING,0,0,0,0 8,12,30,30,DASH_RING,0,0,0,0 10,12,31,0,RAMP,1,0,0,0 12,12,16,12,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,14 @@ -350,9 +350,9 @@ Adv2,INTERACTABLES,65,20,,,,, 26,12,20,12,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,24 30,12,24,29,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,4 30,12,20,29,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,4 -31,12,13,25,PROPELLER_SPRING,0,0,0,0 -31,12,27,27,PROPELLER_SPRING,0,0,0,0 -32,12,8,25,PROPELLER_SPRING,0,0,0,0 +31,12,13,25,FLYING_SPRING,0,0,0,0 +31,12,27,27,FLYING_SPRING,0,0,0,0 +32,12,8,25,FLYING_SPRING,0,0,0,0 32,12,28,24,BOUNCY_SPRING,0,0,0,0 8,13,4,21,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,4 8,13,8,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,24,4 diff --git a/data/sa2/maps/zone_5/act_2/entities/interactables.csv b/data/sa2/maps/zone_5/act_2/entities/interactables.csv index 27e59635a..1ce86b3d8 100644 --- a/data/sa2/maps/zone_5/act_2/entities/interactables.csv +++ b/data/sa2/maps/zone_5/act_2/entities/interactables.csv @@ -2,10 +2,10 @@ Adv2,INTERACTABLES,80,19,,,,, 40,0,9,24,TOGGLE__CHECKPOINT,0,0,0,0 40,0,9,0,TOGGLE__CHECKPOINT,0,0,0,0 40,1,9,16,TOGGLE__CHECKPOINT,0,0,0,0 -63,1,30,30,PROPELLER_SPRING,0,0,0,0 -64,1,14,23,PROPELLER_SPRING,0,0,0,0 -64,1,6,16,PROPELLER_SPRING,0,0,0,0 -64,1,15,9,PROPELLER_SPRING,0,0,0,0 +63,1,30,30,FLYING_SPRING,0,0,0,0 +64,1,14,23,FLYING_SPRING,0,0,0,0 +64,1,6,16,FLYING_SPRING,0,0,0,0 +64,1,15,9,FLYING_SPRING,0,0,0,0 64,1,28,1,SPECIAL_RING,0,0,0,0 65,1,16,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,13 65,1,20,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,24,4 @@ -17,14 +17,14 @@ Adv2,INTERACTABLES,80,19,,,,, 58,2,28,20,GRIND_RAIL__END_ALTERNATE,-6,-3,12,3 59,2,5,20,RAMP,1,0,0,0 62,2,14,20,SMALL_WINDMILL,1,0,0,0 -63,2,21,30,PROPELLER_SPRING,0,0,0,0 -63,2,26,15,PROPELLER_SPRING,0,0,0,0 -63,2,20,5,PROPELLER_SPRING,0,0,0,0 -64,2,14,27,PROPELLER_SPRING,0,0,0,0 -64,2,3,23,PROPELLER_SPRING,0,0,0,0 -64,2,17,12,PROPELLER_SPRING,0,0,0,0 -64,2,21,0,PROPELLER_SPRING,0,0,0,0 -64,2,10,4,PROPELLER_SPRING,0,0,0,0 +63,2,21,30,FLYING_SPRING,0,0,0,0 +63,2,26,15,FLYING_SPRING,0,0,0,0 +63,2,20,5,FLYING_SPRING,0,0,0,0 +64,2,14,27,FLYING_SPRING,0,0,0,0 +64,2,3,23,FLYING_SPRING,0,0,0,0 +64,2,17,12,FLYING_SPRING,0,0,0,0 +64,2,21,0,FLYING_SPRING,0,0,0,0 +64,2,10,4,FLYING_SPRING,0,0,0,0 67,2,28,18,SPRING__LEFT,2,0,0,0 67,2,19,8,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,13 40,3,9,0,TOGGLE__CHECKPOINT,0,0,0,0 @@ -35,9 +35,9 @@ Adv2,INTERACTABLES,80,19,,,,, 60,3,0,12,GRIND_RAIL__START_GROUND,-12,-3,24,3 62,3,30,24,SPRING__UP,0,0,0,0 62,3,8,24,GRIND_RAIL__END_ALTERNATE,-12,-3,24,3 -63,3,20,14,PROPELLER_SPRING,0,0,0,0 -64,3,2,8,PROPELLER_SPRING,0,0,0,0 -64,3,16,13,PROPELLER_SPRING,0,0,0,0 +63,3,20,14,FLYING_SPRING,0,0,0,0 +64,3,2,8,FLYING_SPRING,0,0,0,0 +64,3,16,13,FLYING_SPRING,0,0,0,0 65,3,20,10,SPRING__RIGHT,2,0,0,0 65,3,25,0,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,13 68,3,11,24,TOGGLE__GOAL,0,0,0,0 @@ -109,8 +109,8 @@ Adv2,INTERACTABLES,80,19,,,,, 49,7,31,17,PLATFORM_B,0,0,0,0 49,7,25,17,PLATFORM_B,0,0,0,0 49,7,19,17,PLATFORM_B,0,0,0,0 -52,7,25,9,PROPELLER_SPRING,0,0,0,0 -53,7,3,7,PROPELLER_SPRING,0,0,0,0 +52,7,25,9,FLYING_SPRING,0,0,0,0 +53,7,3,7,FLYING_SPRING,0,0,0,0 54,7,6,28,BOOSTER,0,0,0,0 54,7,20,31,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,21 55,7,0,31,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,9 @@ -123,10 +123,10 @@ Adv2,INTERACTABLES,80,19,,,,, 60,7,24,4,FAN__LEFT,-12,-24,12,24 60,7,0,4,GRIND_RAIL__END_GROUND,-12,-3,24,3 25,8,4,30,SPRING__RIGHT,3,0,0,0 -29,8,25,13,PROPELLER_SPRING,0,0,0,0 -29,8,13,16,PROPELLER_SPRING,0,0,0,0 -30,8,29,5,PROPELLER_SPRING,0,0,0,0 -31,8,9,1,PROPELLER_SPRING,0,0,0,0 +29,8,25,13,FLYING_SPRING,0,0,0,0 +29,8,13,16,FLYING_SPRING,0,0,0,0 +30,8,29,5,FLYING_SPRING,0,0,0,0 +31,8,9,1,FLYING_SPRING,0,0,0,0 35,8,16,21,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,19 35,8,12,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,16 36,8,20,8,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,14 @@ -178,9 +178,9 @@ Adv2,INTERACTABLES,80,19,,,,, 54,9,1,16,DASH_RING,2,0,0,0 55,9,31,30,SPRING__SMALL_UPRIGHT,3,0,0,0 57,9,30,12,SPRING__UP,3,0,0,0 -22,10,29,29,PROPELLER_SPRING,0,0,0,0 -22,10,17,22,PROPELLER_SPRING,0,0,0,0 -22,10,22,13,PROPELLER_SPRING,0,0,0,0 +22,10,29,29,FLYING_SPRING,0,0,0,0 +22,10,17,22,FLYING_SPRING,0,0,0,0 +22,10,22,13,FLYING_SPRING,0,0,0,0 22,10,28,4,FAN__RIGHT,0,-12,12,12 24,10,9,22,PLATFORM_SQUARE,0,-1,0,2 25,10,12,16,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,12 @@ -216,7 +216,7 @@ Adv2,INTERACTABLES,80,19,,,,, 41,10,8,8,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,9,4 41,10,4,4,TOGGLE_PLAYER_LAYER__BACKGROUND,0,0,4,8 41,10,15,16,SPRING__UP,3,0,0,0 -42,10,12,9,PROPELLER_SPRING,0,0,0,0 +42,10,12,9,FLYING_SPRING,0,0,0,0 43,10,19,16,BOOSTER,0,0,0,0 53,10,6,4,SPRING__UP,0,0,0,0 25,11,24,3,TOGGLE_PLAYER_LAYER__FOREGROUND,0,0,4,13 diff --git a/include/constants/sa2/interactables.h b/include/constants/sa2/interactables.h index 350123586..0b8659882 100644 --- a/include/constants/sa2/interactables.h +++ b/include/constants/sa2/interactables.h @@ -89,7 +89,7 @@ #define IA__PROPELLER 82 #define IA__SLIDY_ICE 83 #define IA__SMALL_WINDMILL 84 -#define IA__PROPELLER_SPRING 85 +#define IA__FLYING_SPRING 85 #define IA__WHIRLWIND__A 86 #define IA__FAN__LEFT 87 #define IA__FAN__RIGHT 88 diff --git a/include/game/sa2/stage/interactables/sky_canyon/propeller_spring.h b/include/game/sa2/stage/interactables/sky_canyon/flying_spring.h similarity index 100% rename from include/game/sa2/stage/interactables/sky_canyon/propeller_spring.h rename to include/game/sa2/stage/interactables/sky_canyon/flying_spring.h diff --git a/include/game/sa2/stage/interactables/sky_canyon_init.h b/include/game/sa2/stage/interactables/sky_canyon_level_task.h similarity index 60% rename from include/game/sa2/stage/interactables/sky_canyon_init.h rename to include/game/sa2/stage/interactables/sky_canyon_level_task.h index c6b3f863b..cfa89f876 100644 --- a/include/game/sa2/stage/interactables/sky_canyon_init.h +++ b/include/game/sa2/stage/interactables/sky_canyon_level_task.h @@ -8,10 +8,10 @@ typedef struct { /* 0x00 */ Sprite spring; /* 0x30 */ Sprite propellor; - /* 0x60 */ u16 unk60; - /* 0x62 */ u16 unk62; -} Sprite_OnInit_SkyCanyon; + /* 0x60 */ u16 visibleFlyingSprings; + /* 0x62 */ u16 visiblePropellers; +} SkyCanyonLevelTask; -Task *sub_80807CC(void); +Task *CreateLevelTask_SkyCanyon(void); #endif diff --git a/include/game/shared/stage/entities_manager.h b/include/game/shared/stage/entities_manager.h index 51dfb1f84..450dbc4f3 100644 --- a/include/game/shared/stage/entities_manager.h +++ b/include/game/shared/stage/entities_manager.h @@ -39,7 +39,7 @@ typedef struct { /* 0x0E|0x10 */ CamCoord prevCamY; /* 0x10|0x14 */ u8 SA2_LABEL(unk14); #if (GAME == GAME_SA2) - /* 0x18|0x18 */ Task *preInit; + /* 0x18|0x18 */ Task *levelTask; #endif } EntitiesManager; extern Task *gEntitiesManagerTask; diff --git a/sa2_ldscript.txt b/sa2_ldscript.txt index d5edd84e1..76d47089c 100644 --- a/sa2_ldscript.txt +++ b/sa2_ldscript.txt @@ -275,7 +275,7 @@ SECTIONS src/game/sa2/stage/interactables/techno_base/light_globe.o(.text); src/game/sa2/stage/interactables/sky_canyon/propeller.o(.text); src/game/sa2/stage/interactables/sky_canyon/small_windmill.o(.text); - src/game/sa2/stage/interactables/sky_canyon/propeller_spring.o(.text); + src/game/sa2/stage/interactables/sky_canyon/flying_spring.o(.text); src/game/sa2/stage/interactables/sky_canyon/whirlwind.o(.text); src/game/sa2/stage/interactables/sky_canyon/fan.o(.text); src/game/sa2/stage/interactables/egg_utopia/launcher.o(.text); @@ -286,7 +286,7 @@ SECTIONS src/game/sa2/stage/interactables/egg_utopia/speeding_platform.o(.text); src/game/sa2/stage/interactables/egg_utopia/gravity_toggle.o(.text); src/game/sa2/stage/interactables/collect_rings_lap_trigger.o(.text); - src/game/sa2/stage/interactables/sky_canyon_init.o(.text); + src/game/sa2/stage/interactables/sky_canyon_level_task.o(.text); src/game/sa2/stage/interactables/105.o(.text); src/game/sa2/stage/interactables/note_particle.o(.text); src/game/sa2/stage/interactables/special_ring.o(.text); diff --git a/src/game/sa2/stage/interactables/sky_canyon/flying_spring.c b/src/game/sa2/stage/interactables/sky_canyon/flying_spring.c new file mode 100644 index 000000000..359418d35 --- /dev/null +++ b/src/game/sa2/stage/interactables/sky_canyon/flying_spring.c @@ -0,0 +1,295 @@ +#include "global.h" + +#include "trig.h" +#include "lib/m4a/m4a.h" + +#include "game/shared/stage/entities_manager.h" + +#include "game/sa2/stage/interactables/sky_canyon/flying_spring.h" +#include "game/sa2/stage/interactables/sky_canyon_level_task.h" + +#include "game/sa2/stage/player_controls.h" +#include "game/shared/stage/player.h" +#include "game/shared/stage/camera.h" + +#include "constants/sa2/player_transitions.h" +#include "constants/sa2/songs.h" + +#define STATE_JUMPED 2 +#define STATE_MOVING_UP 1 + +typedef struct { + SpriteBase base; + Sprite sprite; + s32 x; + s32 y; + s16 qOffsetX; + s16 qOffsetY; + u8 state; + u8 step; +} Sprite_FlyingSpring; + +static bool32 sub_807C424(Sprite_FlyingSpring *); +static void sub_807C4A0(Sprite_FlyingSpring *); +static bool32 sub_807C598(Sprite_FlyingSpring *); +static void sub_807C5E0(Sprite_FlyingSpring *); +static void UpdateSharedFlyingSpringAnimation(void); +static void RenderFlyingSpring(Sprite_FlyingSpring *); +static void TaskDestructor_Interactable085(Task *); +static void sub_807C52C(Sprite_FlyingSpring *); +static void sub_807C4EC(Sprite_FlyingSpring *); +static Sprite *GetSharedFlyingSpringSprite(void); + +static void Task_Interactable085(void) +{ + Sprite_FlyingSpring *flyingSpring = TASK_DATA(gCurTask); + flyingSpring->qOffsetY = SIN_24_8(flyingSpring->step * 4) * 2; + flyingSpring->step += 2; + if (sub_807C424(flyingSpring)) { + sub_807C4A0(flyingSpring); + } + + if (sub_807C598(flyingSpring)) { + sub_807C5E0(flyingSpring); + } else { + UpdateSharedFlyingSpringAnimation(); + RenderFlyingSpring(flyingSpring); + } +} + +static void sub_807C2E0(void) +{ + s16 r1; + Sprite_FlyingSpring *flyingSpring = TASK_DATA(gCurTask); + flyingSpring->qOffsetY = SIN_24_8(flyingSpring->step * 4) * 16; + sub_807C52C(flyingSpring); + + r1 = (64 - flyingSpring->step) >> 2; + + if (r1 > 3) { + if (r1 > 6) { + r1 = 6; + } + } else { +#ifndef NON_MATCHING + do + r1 = 4; + while (0); +#else + r1 = 4; +#endif + } + flyingSpring->step += r1; + if (flyingSpring->step >= 64) { + sub_807C4EC(flyingSpring); + } + UpdateSharedFlyingSpringAnimation(); + RenderFlyingSpring(flyingSpring); +} + +static void sub_807C504(Sprite_FlyingSpring *); + +static void sub_807C360(void) +{ + Sprite_FlyingSpring *flyingSpring = TASK_DATA(gCurTask); + flyingSpring->step += 8; + if (flyingSpring->step == 128) { + sub_807C504(flyingSpring); + } else if (flyingSpring->step > 128) { + flyingSpring->qOffsetY = SIN_24_8(flyingSpring->step * 4) * 6; + } else { + flyingSpring->qOffsetY = SIN_24_8(flyingSpring->step * 4) * 3; + } + + UpdateSharedFlyingSpringAnimation(); + RenderFlyingSpring(flyingSpring); +} + +static void sub_807C3DC(Sprite_FlyingSpring *flyingSpring) +{ + if (gPlayer.frameInput & gPlayerControls.jump) { + if (!(flyingSpring->state & STATE_JUMPED)) { + if (!(flyingSpring->state & STATE_MOVING_UP)) { + flyingSpring->state |= STATE_MOVING_UP; + } else { + flyingSpring->state &= ~STATE_MOVING_UP; + flyingSpring->state |= STATE_JUMPED; + } + } + } +} + +static bool32 sub_807C424(Sprite_FlyingSpring *flyingSpring) +{ + s16 springScreenX, playerScreenX, sprintScreenY, playerScreenY; + if (gPlayer.moveState & 0x80 || gPlayer.qSpeedAirY <= 0) { + return FALSE; + } + + springScreenX = flyingSpring->x - gCamera.x; + sprintScreenY = flyingSpring->y - gCamera.y; + playerScreenX = I(gPlayer.qWorldX) - gCamera.x; + playerScreenY = I(gPlayer.qWorldY) - gCamera.y; + if (springScreenX - 20 <= playerScreenX && springScreenX + 20 >= playerScreenX) { + if (sprintScreenY - 12 <= playerScreenY && sprintScreenY + 12 >= playerScreenY) { + return TRUE; + } + } + + return FALSE; +} + +static void sub_807C4A0(Sprite_FlyingSpring *flyingSpring) +{ + gPlayer.transition = PLTRANS_PROPELLER_SPRING; + if (flyingSpring->state & 1) + gPlayer.qSpeedAirY = -Q(5.5); + else + gPlayer.qSpeedAirY = -Q(5.5); + flyingSpring->step = 0; + flyingSpring->state = 0; + m4aSongNumStart(SE_284); + gCurTask->main = sub_807C2E0; +} + +static void sub_807C6E4(void); + +static void sub_807C4EC(Sprite_FlyingSpring *flyingSpring) +{ + flyingSpring->step = 0; + gCurTask->main = sub_807C6E4; +} + +static void sub_807C504(Sprite_FlyingSpring *flyingSpring) +{ + flyingSpring->qOffsetX = 0; + flyingSpring->qOffsetY = 0; + flyingSpring->step = 0; + gCurTask->main = Task_Interactable085; +} + +static void sub_807C52C(Sprite_FlyingSpring *flyingSpring) +{ + if (gPlayer.frameInput & gPlayerControls.jump) { + flyingSpring->state |= STATE_JUMPED; + } +} + +static void RenderFlyingSpring(Sprite_FlyingSpring *flyingSpring) +{ + Sprite *sprite = GetSharedFlyingSpringSprite(); + sprite->x = flyingSpring->x - gCamera.x + I(flyingSpring->qOffsetX); + sprite->y = flyingSpring->y - gCamera.y + I(flyingSpring->qOffsetY); + + DisplaySprite(sprite); +} + +static bool32 sub_807C598(Sprite_FlyingSpring *flyingSpring) +{ + s32 springScreenX, springScreenY; + s16 x, y; + springScreenX = flyingSpring->x; + springScreenX -= gCamera.x; + springScreenY = flyingSpring->y; + springScreenY -= gCamera.y; + + x = springScreenX; + y = springScreenY; + if (x < -(CAM_REGION_WIDTH / 2) || x > (DISPLAY_WIDTH + (CAM_REGION_WIDTH / 2)) || y < -(CAM_REGION_WIDTH / 2) + || y > (DISPLAY_HEIGHT + (CAM_REGION_WIDTH / 2))) { + return TRUE; + } + + return FALSE; +} + +static void sub_807C5E0(Sprite_FlyingSpring *flyingSpring) +{ + flyingSpring->base.me->x = flyingSpring->base.meX; + TaskDestroy(gCurTask); +} + +static Sprite *GetSharedFlyingSpringSprite(void) +{ + EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); + SkyCanyonLevelTask *level = TASK_DATA(em->levelTask); + return &level->spring; +} + +static void UpdateSharedFlyingSpringAnimation(void) +{ + EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); + SkyCanyonLevelTask *level = TASK_DATA(em->levelTask); + + level->visibleFlyingSprings++; +} + +void CreateEntity_PropellerSpring(MapEntity *me, u16 spriteRegionX, u16 spriteRegionY, u8 spriteY) +{ + Task *t = TaskCreate(Task_Interactable085, sizeof(Sprite_FlyingSpring), 0x2010, 0, TaskDestructor_Interactable085); + Sprite_FlyingSpring *flyingSpring = TASK_DATA(t); + flyingSpring->x = TO_WORLD_POS(me->x, spriteRegionX); + flyingSpring->y = TO_WORLD_POS(me->y, spriteRegionY); + + flyingSpring->qOffsetX = 0; + flyingSpring->qOffsetY = 0; + flyingSpring->step = 0; + + flyingSpring->base.regionX = spriteRegionX; + flyingSpring->base.regionY = spriteRegionY; + flyingSpring->base.me = me; + flyingSpring->base.meX = me->x; + flyingSpring->base.id = spriteY; + SET_MAP_ENTITY_INITIALIZED(me); +} + +static void sub_807C72C(Sprite_FlyingSpring *); + +static void sub_807C6E4(void) +{ + Sprite_FlyingSpring *flyingSpring = TASK_DATA(gCurTask); + sub_807C3DC(flyingSpring); + + if (++flyingSpring->step > 0) { + sub_807C72C(flyingSpring); + } + + UpdateSharedFlyingSpringAnimation(); + RenderFlyingSpring(flyingSpring); +} + +static void TaskDestructor_Interactable085(Task *t) +{ + // unused +} + +static void sub_807C744(void); + +static void sub_807C72C(Sprite_FlyingSpring *flyingSpring) +{ + flyingSpring->step = 64; + gCurTask->main = sub_807C744; +} + +static void sub_807C7A0(Sprite_FlyingSpring *); + +static void sub_807C744(void) +{ + Sprite_FlyingSpring *flyingSpring = TASK_DATA(gCurTask); + flyingSpring->qOffsetY = SIN_24_8(flyingSpring->step * 4) * 16; + sub_807C3DC(flyingSpring); + + flyingSpring->step += 8; + if ((s8)flyingSpring->step < 0) { + sub_807C7A0(flyingSpring); + } + + UpdateSharedFlyingSpringAnimation(); + RenderFlyingSpring(flyingSpring); +} + +static void sub_807C7A0(Sprite_FlyingSpring *flyingSpring) +{ + flyingSpring->step = 128; + gCurTask->main = sub_807C360; +} diff --git a/src/game/sa2/stage/interactables/sky_canyon/propeller.c b/src/game/sa2/stage/interactables/sky_canyon/propeller.c index 782935f06..8875ed1a3 100644 --- a/src/game/sa2/stage/interactables/sky_canyon/propeller.c +++ b/src/game/sa2/stage/interactables/sky_canyon/propeller.c @@ -13,7 +13,7 @@ #include "game/shared/stage/camera.h" #include "game/sa2/stage/interactables/sky_canyon/propeller.h" -#include "game/sa2/stage/interactables/sky_canyon_init.h" +#include "game/sa2/stage/interactables/sky_canyon_level_task.h" #include "constants/sa2/animations.h" #include "constants/sa2/char_states.h" @@ -43,7 +43,7 @@ static void Render(Sprite_Propeller *); static void StartPlayerFloatingTask(Sprite_Propeller *); static bool32 ShouldDespawn(Sprite_Propeller *); static void DestroyPropeller(Sprite_Propeller *); -Sprite_OnInit_SkyCanyon *sub_807BA54(void); +SkyCanyonLevelTask *sub_807BA54(void); static void TaskDestructor_GiantPropeller(Task *); static bool32 sub_807B9F0(Sprite_Propeller *); @@ -314,18 +314,18 @@ static void DestroyPropeller(Sprite_Propeller *propeller) TaskDestroy(gCurTask); } -Sprite_OnInit_SkyCanyon *sub_807BA54(void) +SkyCanyonLevelTask *sub_807BA54(void) { EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); - return TASK_DATA(em->preInit); + return TASK_DATA(em->levelTask); } static void sub_807BA70(void) { EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); - Sprite_OnInit_SkyCanyon *level = TASK_DATA(em->preInit); + SkyCanyonLevelTask *level = TASK_DATA(em->levelTask); - level->unk62++; + level->visiblePropellers++; } void CreateEntity_Propeller(MapEntity *me, u16 spriteRegionX, u16 spriteRegionY, u8 spriteY) diff --git a/src/game/sa2/stage/interactables/sky_canyon/propeller_spring.c b/src/game/sa2/stage/interactables/sky_canyon/propeller_spring.c deleted file mode 100644 index ff3977732..000000000 --- a/src/game/sa2/stage/interactables/sky_canyon/propeller_spring.c +++ /dev/null @@ -1,293 +0,0 @@ -#include "global.h" - -#include "trig.h" -#include "lib/m4a/m4a.h" - -#include "game/shared/stage/entities_manager.h" - -#include "game/sa2/stage/interactables/sky_canyon/propeller_spring.h" -#include "game/sa2/stage/interactables/sky_canyon_init.h" - -#include "game/sa2/stage/player_controls.h" -#include "game/shared/stage/player.h" -#include "game/shared/stage/camera.h" - -#include "constants/sa2/player_transitions.h" -#include "constants/sa2/songs.h" - -typedef struct { - SpriteBase base; - Sprite sprite; - s32 unk3C; - s32 unk40; - s16 unk44; - s16 unk46; - u8 unk48; - u8 unk49; -} Sprite_IA85; - -static bool32 sub_807C424(Sprite_IA85 *); -static void sub_807C4A0(Sprite_IA85 *); -static bool32 sub_807C598(Sprite_IA85 *); -static void sub_807C5E0(Sprite_IA85 *); -static void sub_807C614(void); -static void sub_807C558(Sprite_IA85 *); -static void TaskDestructor_Interactable085(Task *); - -static void Task_Interactable085(void) -{ - Sprite_IA85 *ia85 = TASK_DATA(gCurTask); - ia85->unk46 = SIN_24_8(ia85->unk49 * 4) * 2; - ia85->unk49 += 2; - if (sub_807C424(ia85)) { - sub_807C4A0(ia85); - } - - if (sub_807C598(ia85)) { - sub_807C5E0(ia85); - } else { - sub_807C614(); - sub_807C558(ia85); - } -} - -static void sub_807C52C(Sprite_IA85 *); -static void sub_807C4EC(Sprite_IA85 *); - -static void sub_807C2E0(void) -{ - s16 r1; - Sprite_IA85 *ia85 = TASK_DATA(gCurTask); - ia85->unk46 = SIN_24_8(ia85->unk49 * 4) * 16; - sub_807C52C(ia85); - - r1 = (0x40 - ia85->unk49) >> 2; - - if (r1 > 3) { - if (r1 > 6) { - r1 = 6; - } - } else { -#ifndef NON_MATCHING - do - r1 = 4; - while (0); -#else - r1 = 4; -#endif - } - ia85->unk49 += r1; - if (ia85->unk49 > 63) { - sub_807C4EC(ia85); - } - sub_807C614(); - sub_807C558(ia85); -} - -static void sub_807C504(Sprite_IA85 *); - -static void sub_807C360(void) -{ - Sprite_IA85 *ia85 = TASK_DATA(gCurTask); - ia85->unk49 += 8; - if (ia85->unk49 == 0x80) { - sub_807C504(ia85); - } else if (ia85->unk49 > 0x80) { - ia85->unk46 = SIN_24_8(ia85->unk49 * 4) * 6; - } else { - ia85->unk46 = SIN_24_8(ia85->unk49 * 4) * 3; - } - - sub_807C614(); - sub_807C558(ia85); -} - -static void sub_807C3DC(Sprite_IA85 *ia85) -{ - if (gPlayer.frameInput & gPlayerControls.jump) { - if (!(ia85->unk48 & 2)) { - if (!(ia85->unk48 & 1)) { - ia85->unk48 |= 1; - } else { - ia85->unk48 &= ~0x1; - ia85->unk48 |= 2; - } - } - } -} - -static bool32 sub_807C424(Sprite_IA85 *ia85) -{ - s16 temp, temp2, temp3, temp4; - if (gPlayer.moveState & 0x80 || gPlayer.qSpeedAirY <= 0) { - return 0; - } - - temp = ia85->unk3C - gCamera.x; - temp3 = ia85->unk40 - gCamera.y; - temp2 = I(gPlayer.qWorldX) - gCamera.x; - temp4 = I(gPlayer.qWorldY) - gCamera.y; - if (temp - 0x14 <= temp2 && temp + 0x14 >= temp2) { - if (temp3 - 0xC <= temp4 && temp3 + 0xC >= temp4) { - return 1; - } - } - - return 0; -} - -static void sub_807C4A0(Sprite_IA85 *ia85) -{ - gPlayer.transition = PLTRANS_PROPELLER_SPRING; - if (ia85->unk48 & 1) - gPlayer.qSpeedAirY = -Q(5.5); - else - gPlayer.qSpeedAirY = -Q(5.5); - ia85->unk49 = 0; - ia85->unk48 = 0; - m4aSongNumStart(SE_284); - gCurTask->main = sub_807C2E0; -} - -static void sub_807C6E4(void); - -static void sub_807C4EC(Sprite_IA85 *ia85) -{ - ia85->unk49 = 0; - gCurTask->main = sub_807C6E4; -} - -static void sub_807C504(Sprite_IA85 *ia85) -{ - ia85->unk44 = 0; - ia85->unk46 = 0; - ia85->unk49 = 0; - gCurTask->main = Task_Interactable085; -} - -static void sub_807C52C(Sprite_IA85 *ia85) -{ - if (gPlayer.frameInput & gPlayerControls.jump) { - ia85->unk48 |= 2; - } -} - -static Sprite *sub_807C5F8(void); - -static void sub_807C558(Sprite_IA85 *ia85) -{ - Sprite *sprite = sub_807C5F8(); - sprite->x = ia85->unk3C - gCamera.x + I(ia85->unk44); - sprite->y = ia85->unk40 - gCamera.y + I(ia85->unk46); - - DisplaySprite(sprite); -} - -static bool32 sub_807C598(Sprite_IA85 *ia85) -{ - s32 temp1, temp; - s16 temp2, temp3; - temp1 = ia85->unk3C; - temp1 -= gCamera.x; - temp = ia85->unk40; - temp -= gCamera.y; - - temp2 = temp1; - temp3 = temp; - if (temp2 < -128 || temp2 > (DISPLAY_WIDTH + 128) || temp3 < -128 || temp3 > (DISPLAY_HEIGHT + 128)) { - return 1; - } - - return 0; -} - -static void sub_807C5E0(Sprite_IA85 *ia85) -{ - ia85->base.me->x = ia85->base.meX; - TaskDestroy(gCurTask); -} - -static Sprite *sub_807C5F8(void) -{ - EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); - Sprite_OnInit_SkyCanyon *level = TASK_DATA(em->preInit); - return &level->spring; -} - -static void sub_807C614(void) -{ - EntitiesManager *em = TASK_DATA(TASK_PARENT(gCurTask)); - Sprite_OnInit_SkyCanyon *level = TASK_DATA(em->preInit); - - level->unk60++; -} - -void CreateEntity_PropellerSpring(MapEntity *me, u16 spriteRegionX, u16 spriteRegionY, u8 spriteY) -{ - Task *t = TaskCreate(Task_Interactable085, sizeof(Sprite_IA85), 0x2010, 0, TaskDestructor_Interactable085); - Sprite_IA85 *ia85 = TASK_DATA(t); - ia85->unk3C = TO_WORLD_POS(me->x, spriteRegionX); - ia85->unk40 = TO_WORLD_POS(me->y, spriteRegionY); - - ia85->unk44 = 0; - ia85->unk46 = 0; - ia85->unk49 = 0; - - ia85->base.regionX = spriteRegionX; - ia85->base.regionY = spriteRegionY; - ia85->base.me = me; - ia85->base.meX = me->x; - ia85->base.id = spriteY; - SET_MAP_ENTITY_INITIALIZED(me); -} - -static void sub_807C72C(Sprite_IA85 *); - -static void sub_807C6E4(void) -{ - Sprite_IA85 *ia85 = TASK_DATA(gCurTask); - sub_807C3DC(ia85); - - if (++ia85->unk49 > 0) { - sub_807C72C(ia85); - } - - sub_807C614(); - sub_807C558(ia85); -} - -static void TaskDestructor_Interactable085(Task *t) -{ - // unused -} - -static void sub_807C744(void); - -static void sub_807C72C(Sprite_IA85 *ia85) -{ - ia85->unk49 = 0x40; - gCurTask->main = sub_807C744; -} - -static void sub_807C7A0(Sprite_IA85 *); - -static void sub_807C744(void) -{ - Sprite_IA85 *ia85 = TASK_DATA(gCurTask); - ia85->unk46 = SIN_24_8(ia85->unk49 * 4) * 16; - sub_807C3DC(ia85); - - ia85->unk49 += 8; - if ((s8)ia85->unk49 < 0) { - sub_807C7A0(ia85); - } - - sub_807C614(); - sub_807C558(ia85); -} - -static void sub_807C7A0(Sprite_IA85 *ia85) -{ - ia85->unk49 = 0x80; - gCurTask->main = sub_807C360; -} diff --git a/src/game/sa2/stage/interactables/sky_canyon_init.c b/src/game/sa2/stage/interactables/sky_canyon_level_task.c similarity index 51% rename from src/game/sa2/stage/interactables/sky_canyon_init.c rename to src/game/sa2/stage/interactables/sky_canyon_level_task.c index c5e892c54..1bac0cf9c 100644 --- a/src/game/sa2/stage/interactables/sky_canyon_init.c +++ b/src/game/sa2/stage/interactables/sky_canyon_level_task.c @@ -2,26 +2,20 @@ #include "sprite.h" #include "task.h" -#include "game/sa2/stage/interactables/sky_canyon_init.h" +#include "game/sa2/stage/interactables/sky_canyon_level_task.h" #include "constants/sa2/animations.h" -static void Task_80808DC(void); +static void Task_UpdateAnimations(void); -/* sub_80807CC is pointed to by 'gSpriteTileInits_PreStageEntry' inside collision.s - * Which itself is referenced by 'CreateStageEntitiesManager' - * It is called on stage-entry of ONLY Sky Canyon Acts 1 & 2, - * the other pointers inside 'gSpriteTileInits_PreStageEntry' are empty. - */ - -Task *sub_80807CC(void) +Task *CreateLevelTask_SkyCanyon(void) { - Task *t = TaskCreate(Task_80808DC, sizeof(Sprite_OnInit_SkyCanyon), 0x2001, 0, NULL); - Sprite_OnInit_SkyCanyon *init = TASK_DATA(t); + Task *t = TaskCreate(Task_UpdateAnimations, sizeof(SkyCanyonLevelTask), 0x2001, 0, NULL); + SkyCanyonLevelTask *init = TASK_DATA(t); Sprite *spring, *propellor; - init->unk60 = 0; - init->unk62 = 0; + init->visibleFlyingSprings = 0; + init->visiblePropellers = 0; spring = &init->spring; SPRITE_INIT_WITHOUT_ANIM_OR_VRAM(spring, 18, 2, 0); @@ -40,17 +34,17 @@ Task *sub_80807CC(void) return t; } -static void Task_80808DC(void) +static void Task_UpdateAnimations(void) { - Sprite_OnInit_SkyCanyon *init = TASK_DATA(gCurTask); + SkyCanyonLevelTask *init = TASK_DATA(gCurTask); - if (init->unk60) { + if (init->visibleFlyingSprings != 0) { UpdateSpriteAnimation(&init->spring); } - init->unk60 = 0; + init->visibleFlyingSprings = 0; - if (init->unk62 != 0) { + if (init->visiblePropellers != 0) { UpdateSpriteAnimation(&init->propellor); } - init->unk62 = 0; -} \ No newline at end of file + init->visiblePropellers = 0; +} diff --git a/src/game/shared/stage/entities_manager.c b/src/game/shared/stage/entities_manager.c index bc15f38f0..96f75edac 100644 --- a/src/game/shared/stage/entities_manager.c +++ b/src/game/shared/stage/entities_manager.c @@ -68,7 +68,7 @@ #include "game/sa2/stage/interactables/sky_canyon/fan.h" #include "game/sa2/stage/interactables/sky_canyon/small_windmill.h" #include "game/sa2/stage/interactables/sky_canyon/whirlwind.h" -#include "game/sa2/stage/interactables/sky_canyon/propeller_spring.h" +#include "game/sa2/stage/interactables/sky_canyon/flying_spring.h" #include "game/sa2/stage/interactables/techno_base/light_globe.h" #include "game/sa2/stage/interactables/techno_base/light_bridge.h" @@ -88,7 +88,7 @@ #include "game/sa2/stage/interactables/105.h" #include "game/sa2/stage/interactables/special_ring.h" #include "game/sa2/stage/interactables/collect_rings_lap_trigger.h" -#include "game/sa2/stage/interactables/sky_canyon_init.h" +#include "game/sa2/stage/interactables/sky_canyon_level_task.h" #include "game/sa2/stage/mystery_itembox.h" @@ -800,16 +800,23 @@ const MapEntityInit gSpriteInits_CollectRingsInteractables[] = { }; #ifndef COLLECT_RINGS_ROM -const StagePreInitFunc gSpriteTileInits_PreStageEntry[] = { - NULL, NULL, NULL, NULL, // Leaf Forest - NULL, NULL, NULL, NULL, // Hot Crater - NULL, NULL, NULL, NULL, // Music Plant - NULL, NULL, NULL, NULL, // Ice Paradise - sub_80807CC, sub_80807CC, NULL, NULL, // Sky Canyon - NULL, NULL, NULL, NULL, // Techno Base - NULL, NULL, NULL, NULL, // Egg Utopia - NULL, NULL, NULL, NULL, // Final Zone - NULL, NULL, +const StagePreInitFunc sLevelTaskInits[] = { + // Leaf Forest + NULL, NULL, NULL, NULL, + // Hot Crater + NULL, NULL, NULL, NULL, + // Music Plant + NULL, NULL, NULL, NULL, + // Ice Paradise + NULL, NULL, NULL, NULL, + // Sky Canyon + CreateLevelTask_SkyCanyon, CreateLevelTask_SkyCanyon, NULL, NULL, + // Techno Base + NULL, NULL, NULL, NULL, + // Egg Utopia + NULL, NULL, NULL, NULL, + // Final Zone + NULL, NULL, NULL, NULL, NULL, NULL }; #endif #endif @@ -842,10 +849,10 @@ void CreateStageEntitiesManager(void) em->enemies = decompBuf; #if (GAME == GAME_SA2) - em->preInit = NULL; + em->levelTask = NULL; - if (gSpriteTileInits_PreStageEntry[gCurrentLevel]) { - em->preInit = gSpriteTileInits_PreStageEntry[gCurrentLevel](); + if (sLevelTaskInits[gCurrentLevel]) { + em->levelTask = sLevelTaskInits[gCurrentLevel](); } #endif } else {