2020-12-06 12:38:41 +00:00
|
|
|
/// Makai Stage 15 Boss - Elis
|
|
|
|
/// --------------------------
|
|
|
|
|
2021-10-30 13:49:25 +00:00
|
|
|
#include <stddef.h>
|
2020-12-06 12:38:41 +00:00
|
|
|
#include "platform.h"
|
2021-10-22 08:56:07 +00:00
|
|
|
#include "pc98.h"
|
|
|
|
#include "planar.h"
|
2021-10-30 19:29:55 +00:00
|
|
|
#include "master.hpp"
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/v_colors.hpp"
|
2021-10-30 13:49:25 +00:00
|
|
|
#include "th01/math/area.hpp"
|
2022-05-11 14:37:53 +00:00
|
|
|
#include "th01/math/dir.hpp"
|
2022-05-12 14:59:50 +00:00
|
|
|
#include "th01/math/polar.hpp"
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/math/subpixel.hpp"
|
2022-05-11 14:37:53 +00:00
|
|
|
extern "C" {
|
2022-05-12 11:34:18 +00:00
|
|
|
#include "th01/math/vector.hpp"
|
2021-10-30 19:29:55 +00:00
|
|
|
#include "th01/hardware/egc.h"
|
|
|
|
#include "th01/hardware/graph.h"
|
2021-10-30 13:49:25 +00:00
|
|
|
#include "th01/formats/pf.hpp"
|
2021-10-30 19:44:58 +00:00
|
|
|
#include "th01/formats/grc.hpp"
|
2021-10-22 08:56:07 +00:00
|
|
|
#include "th01/formats/ptn.hpp"
|
2022-05-23 21:50:17 +00:00
|
|
|
#include "th01/main/entity.hpp"
|
2022-05-11 14:37:53 +00:00
|
|
|
#include "th01/snd/mdrv2.h"
|
2021-10-30 19:29:55 +00:00
|
|
|
#include "th01/main/playfld.hpp"
|
2021-10-30 13:49:25 +00:00
|
|
|
#include "th01/main/vars.hpp"
|
|
|
|
#include "th01/main/boss/entity_a.hpp"
|
2020-12-06 12:38:41 +00:00
|
|
|
}
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/shiftjis/fns.hpp"
|
|
|
|
#include "th01/sprites/pellet.h"
|
2021-10-30 19:29:55 +00:00
|
|
|
#include "th01/main/shape.hpp"
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/main/particle.hpp"
|
2021-10-30 13:49:25 +00:00
|
|
|
#include "th01/main/boss/boss.hpp"
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/main/boss/palette.hpp"
|
2022-05-11 14:37:53 +00:00
|
|
|
#include "th01/main/bullet/laser_s.hpp"
|
2021-10-30 20:45:31 +00:00
|
|
|
#include "th01/main/bullet/missile.hpp"
|
|
|
|
#include "th01/main/bullet/pellet.hpp"
|
2021-10-30 20:26:08 +00:00
|
|
|
#include "th01/main/hud/hp.hpp"
|
2020-12-06 12:38:41 +00:00
|
|
|
|
2021-10-30 19:29:55 +00:00
|
|
|
// Coordinates
|
|
|
|
// -----------
|
|
|
|
|
|
|
|
static const pixel_t GIRL_W = 128;
|
|
|
|
static const pixel_t GIRL_H = 96;
|
2021-10-30 20:26:08 +00:00
|
|
|
static const pixel_t BAT_W = 48;
|
|
|
|
static const pixel_t BAT_H = 32;
|
2021-10-30 19:29:55 +00:00
|
|
|
|
|
|
|
static const pixel_t BASE_LEFT = (PLAYFIELD_CENTER_X - (GIRL_W / 2));
|
|
|
|
static const pixel_t BASE_TOP = (
|
|
|
|
PLAYFIELD_TOP + ((PLAYFIELD_H / 21) * 5) - (GIRL_H / 2)
|
|
|
|
);
|
|
|
|
// -----------
|
|
|
|
|
2022-05-11 14:37:53 +00:00
|
|
|
enum elis_colors_t {
|
|
|
|
COL_FX = 4,
|
|
|
|
};
|
|
|
|
|
|
|
|
// State
|
|
|
|
// -----
|
|
|
|
|
2022-05-06 17:04:35 +00:00
|
|
|
#define pattern_state elis_pattern_state
|
2021-10-30 19:29:55 +00:00
|
|
|
#define stars elis_stars
|
2020-12-17 20:28:17 +00:00
|
|
|
#define flash_colors elis_flash_colors
|
|
|
|
#define invincibility_frame elis_invincibility_frame
|
|
|
|
#define invincible elis_invincible
|
2021-10-30 19:29:55 +00:00
|
|
|
#define wave_teleport_done elis_wave_teleport_done
|
2020-12-09 20:42:10 +00:00
|
|
|
#define initial_hp_rendered elis_initial_hp_rendered
|
2020-12-17 20:28:17 +00:00
|
|
|
extern int invincibility_frame;
|
|
|
|
extern bool16 invincible;
|
2021-10-30 19:29:55 +00:00
|
|
|
extern bool16 wave_teleport_done;
|
2020-12-09 20:42:10 +00:00
|
|
|
extern bool initial_hp_rendered;
|
2022-05-11 14:37:53 +00:00
|
|
|
// -----
|
|
|
|
|
|
|
|
// Patterns
|
|
|
|
// --------
|
|
|
|
static const int CHOOSE_NEW = 0;
|
2020-12-09 20:42:10 +00:00
|
|
|
|
2022-05-12 18:05:16 +00:00
|
|
|
enum elis_starpattern_ret_t {
|
|
|
|
SP_STAR_OF_DAVID = false,
|
|
|
|
SP_PATTERN = true,
|
|
|
|
|
|
|
|
_elis_starpattern_ret_t_FORCE_INT16 = 0x7FFF,
|
|
|
|
};
|
|
|
|
|
2022-05-06 17:04:35 +00:00
|
|
|
extern union {
|
2022-05-12 11:34:18 +00:00
|
|
|
int angle_range; // ACTUAL TYPE: unsigned char
|
2022-05-12 14:59:50 +00:00
|
|
|
pellet_group_t group;
|
2022-05-11 14:37:53 +00:00
|
|
|
int speed_multiplied_by_8;
|
2022-05-06 17:04:35 +00:00
|
|
|
} pattern_state;
|
2022-05-11 14:37:53 +00:00
|
|
|
// --------
|
2022-05-06 17:04:35 +00:00
|
|
|
|
2021-10-22 08:56:07 +00:00
|
|
|
// Entities
|
|
|
|
// --------
|
|
|
|
|
2022-05-11 14:37:53 +00:00
|
|
|
enum elis_form_t {
|
|
|
|
F_GIRL = 0,
|
|
|
|
F_BAT = 1,
|
|
|
|
|
|
|
|
_elis_form_t_FORCE_INT16 = 0x7FFF,
|
|
|
|
};
|
|
|
|
|
2022-05-09 13:09:04 +00:00
|
|
|
enum elis_entity_t {
|
|
|
|
// "Girl" sprites
|
|
|
|
ENT_STILL_OR_WAVE = 0,
|
|
|
|
ENT_ATTACK = 1,
|
|
|
|
|
|
|
|
ENT_BAT = 2,
|
|
|
|
};
|
|
|
|
|
2022-05-11 14:37:53 +00:00
|
|
|
enum elis_entity_cel_t {
|
|
|
|
// ENT_STILL_OR_WAVE
|
2021-10-30 19:29:55 +00:00
|
|
|
C_STILL = 0,
|
2022-05-11 14:37:53 +00:00
|
|
|
C_HAND = 1,
|
2021-10-30 19:29:55 +00:00
|
|
|
C_WAVE_1 = 2,
|
|
|
|
C_WAVE_2 = 3,
|
|
|
|
C_WAVE_3 = 4,
|
|
|
|
C_WAVE_4 = 5,
|
2022-05-12 18:05:16 +00:00
|
|
|
|
|
|
|
// ENT_ATTACK
|
|
|
|
C_PREPARE = 0,
|
2021-10-30 19:29:55 +00:00
|
|
|
};
|
|
|
|
|
2022-05-09 13:09:04 +00:00
|
|
|
#define ent_still_or_wave boss_entities[ENT_STILL_OR_WAVE]
|
|
|
|
#define ent_attack boss_entities[ENT_ATTACK]
|
|
|
|
#define ent_bat boss_entities[ENT_BAT]
|
2021-10-30 19:29:55 +00:00
|
|
|
|
2022-01-29 23:30:33 +00:00
|
|
|
inline void elis_ent_load(void) {
|
2022-05-07 14:30:24 +00:00
|
|
|
ent_still_or_wave.load("boss5.bos", 0);
|
|
|
|
ent_attack.load("boss5_2.bos", 1);
|
|
|
|
ent_bat.load("boss5_3.bos", 2);
|
2021-10-30 19:29:55 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 23:30:33 +00:00
|
|
|
inline void elis_ent_free(void) {
|
2021-10-30 19:44:58 +00:00
|
|
|
bos_entity_free(0);
|
|
|
|
bos_entity_free(1);
|
|
|
|
bos_entity_free(2);
|
|
|
|
}
|
2022-01-29 23:30:33 +00:00
|
|
|
|
2022-05-09 13:09:04 +00:00
|
|
|
inline void ent_sync(elis_entity_t dst, elis_entity_t src) {
|
|
|
|
boss_entities[dst].pos_cur_set(
|
|
|
|
boss_entities[src].cur_left, boss_entities[src].cur_top
|
2022-01-29 23:30:33 +00:00
|
|
|
);
|
|
|
|
}
|
2022-05-11 14:37:53 +00:00
|
|
|
|
2022-05-12 14:59:50 +00:00
|
|
|
// [unput_0] should theoretically always be `true`. Making sure that both VRAM
|
|
|
|
// pages are identical avoids visual glitches from blitting cels with different
|
|
|
|
// transparent areas on top of each other (see: Mima's third arm)… but you can
|
|
|
|
// always just *assume* rather than ensure, right? :zunpet:
|
|
|
|
inline void ent_unput_and_put_both(
|
|
|
|
elis_entity_t ent, elis_entity_cel_t cel, bool unput_0 = true
|
|
|
|
) {
|
2022-05-11 14:37:53 +00:00
|
|
|
void girl_bg_put(int unncessary_parameter_that_still_needs_to_be_1_or_2);
|
|
|
|
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
girl_bg_put(ent + 1);
|
|
|
|
boss_entities[ent].move_lock_and_put_image_8(cel);
|
|
|
|
graph_accesspage_func(0);
|
2022-05-12 14:59:50 +00:00
|
|
|
if(unput_0) {
|
|
|
|
girl_bg_put(ent + 1);
|
|
|
|
}
|
|
|
|
boss_entities[ent].move_lock_and_put_image_8(cel);
|
2022-05-11 14:37:53 +00:00
|
|
|
}
|
2021-10-22 08:56:07 +00:00
|
|
|
// --------
|
|
|
|
|
2022-05-11 14:37:53 +00:00
|
|
|
// Form-relative coordinates
|
|
|
|
// -------------------------
|
|
|
|
|
|
|
|
inline screen_x_t form_center_x(elis_form_t form) {
|
|
|
|
return (ent_still_or_wave.cur_left + (GIRL_W / 2));
|
|
|
|
}
|
|
|
|
|
2022-05-12 14:59:50 +00:00
|
|
|
inline screen_y_t form_center_y(elis_form_t form) {
|
|
|
|
return (ent_still_or_wave.cur_top + (GIRL_H / 2));
|
|
|
|
}
|
|
|
|
|
2022-05-11 14:37:53 +00:00
|
|
|
inline screen_x_t girl_lefteye_x(void) {
|
|
|
|
return (ent_still_or_wave.cur_left + 60);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline screen_y_t girl_lefteye_y(void) {
|
|
|
|
return (ent_still_or_wave.cur_top + 28);
|
|
|
|
}
|
|
|
|
// -------------------------
|
|
|
|
|
2022-05-10 11:53:47 +00:00
|
|
|
// Surround area
|
|
|
|
// -------------
|
|
|
|
// Common bullet spawn area around Elis.
|
|
|
|
|
|
|
|
static const pixel_t SURROUND_AREA_W = ((PLAYFIELD_W * 3) / 10);
|
|
|
|
static const pixel_t SURROUND_AREA_H = ((PLAYFIELD_H * 8) / 21);
|
|
|
|
|
|
|
|
inline screen_x_t surround_random_left(elis_entity_t relative_to) {
|
|
|
|
return (
|
|
|
|
(boss_entities[relative_to].cur_left + (rand() % SURROUND_AREA_W)) -
|
|
|
|
((SURROUND_AREA_W - GIRL_W) / 2)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline screen_y_t surround_random_top(elis_entity_t relative_to) {
|
|
|
|
return (
|
|
|
|
(boss_entities[relative_to].cur_top + (rand() % SURROUND_AREA_H)) -
|
|
|
|
(SURROUND_AREA_H - GIRL_H)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// -------------
|
|
|
|
|
2022-05-12 11:34:18 +00:00
|
|
|
// .GRC entities
|
|
|
|
// -------------
|
|
|
|
|
|
|
|
enum elis_grc_cel_t {
|
|
|
|
RIFT_CELS = 2,
|
|
|
|
|
|
|
|
C_RIFT = 4,
|
|
|
|
C_RIFT_last = (C_RIFT + RIFT_CELS - 1),
|
|
|
|
};
|
|
|
|
|
|
|
|
#define elis_grc_sloppy_unput(entities, i) { \
|
|
|
|
grc_sloppy_unput(entities.left[i], entities.top[i]); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define elis_grc_put(entities, i, cel, col) { \
|
|
|
|
grc_put_8(entities.left[i], entities.top[i], GRC_SLOT_BOSS_1, cel, col); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define rifts_update_and_render(rifts, start_frame, end_frame, tmp_cel) { \
|
|
|
|
if( \
|
|
|
|
(boss_phase_frame >= start_frame) && \
|
|
|
|
(boss_phase_frame <= end_frame) && \
|
|
|
|
((boss_phase_frame % 4) == 0) \
|
|
|
|
) { \
|
|
|
|
for(int i = 0; i < rifts.count(); i++) { \
|
|
|
|
/* Unblit */ \
|
|
|
|
if(boss_phase_frame > start_frame) { \
|
|
|
|
elis_grc_sloppy_unput(rifts, i); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
/* Initialize */ \
|
|
|
|
if( \
|
|
|
|
((boss_phase_frame % 16) == ((i * 4) % 16)) || \
|
|
|
|
(boss_phase_frame == start_frame) \
|
|
|
|
) { \
|
|
|
|
rifts.left[i] = surround_random_left(ENT_STILL_OR_WAVE); \
|
|
|
|
rifts.top[i] = surround_random_top(ENT_STILL_OR_WAVE); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
/* Render */ \
|
|
|
|
if(boss_phase_frame < end_frame) { \
|
|
|
|
tmp_cel = (rand() % RIFT_CELS); \
|
|
|
|
elis_grc_put(rifts, i, (C_RIFT + cel), COL_FX); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
mdrv2_se_play(7); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
// -------------
|
|
|
|
|
2022-05-12 14:59:50 +00:00
|
|
|
// Shared big circle
|
|
|
|
// -----------------
|
|
|
|
// Concrete circle structures must look like this: {
|
|
|
|
// unsigned char angle;
|
|
|
|
// int frame;
|
|
|
|
//
|
|
|
|
// screen_x_t center_x(void) { return …; };
|
|
|
|
// screen_y_t center_y(void) { return …; };
|
|
|
|
// };
|
|
|
|
|
|
|
|
static const pixel_t BIGCIRCLE_RADIUS = ((GIRL_W * 2) / 2);
|
|
|
|
|
|
|
|
#define bigcircle_sloppy_unput(bigcircle) { \
|
|
|
|
shape_circle_sloppy_unput( \
|
|
|
|
bigcircle.center_x(), bigcircle.center_y(), BIGCIRCLE_RADIUS, 0x01 \
|
|
|
|
); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bigcircle_put_arc(bigcircle, angle_start, angle_end, col) { \
|
|
|
|
shape_ellipse_arc_put( \
|
|
|
|
bigcircle.center_x(), \
|
|
|
|
bigcircle.center_y(), \
|
|
|
|
BIGCIRCLE_RADIUS, \
|
|
|
|
BIGCIRCLE_RADIUS, \
|
|
|
|
col, \
|
|
|
|
0x01, \
|
|
|
|
angle_start, \
|
|
|
|
angle_end \
|
|
|
|
); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bigcircle_put(bigcircle, col) { \
|
|
|
|
bigcircle_put_arc(bigcircle, 0x00, 0xFF, col); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bigcircle_put_dot(bigcircle, offset_start, offset_end, col) { \
|
|
|
|
bigcircle_put_arc( \
|
|
|
|
bigcircle, \
|
|
|
|
(bigcircle.angle + offset_start), \
|
|
|
|
(bigcircle.angle + offset_end), \
|
|
|
|
col \
|
|
|
|
); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bigcircle_is_summon_frame(start_frame) ( \
|
|
|
|
(boss_phase_frame >= start_frame) && ((boss_phase_frame % 2) == 0) \
|
|
|
|
)
|
|
|
|
|
|
|
|
#define bigcircle_summon_done(bigcircle) \
|
|
|
|
(bigcircle.angle >= (0x100 / 4))
|
|
|
|
|
|
|
|
#define bigcircle_summon_update_and_render(bigcircle, q4_offset_end) { \
|
|
|
|
bigcircle_put_dot(bigcircle, 0x00, q4_offset_end, V_WHITE); \
|
|
|
|
bigcircle_put_dot(bigcircle, 0x40, 0x42, V_WHITE); \
|
|
|
|
bigcircle_put_dot(bigcircle, 0x80, 0x82, V_WHITE); \
|
|
|
|
bigcircle_put_dot(bigcircle, 0xC0, 0xC2, V_WHITE); \
|
|
|
|
\
|
|
|
|
bigcircle.angle += 0x02; \
|
|
|
|
}
|
|
|
|
|
|
|
|
// All of the summon animation macros below are forced to be used inside an
|
|
|
|
// `if` statement, returning a non-zero value when the flash animation is done.
|
|
|
|
// MODDERS: Just turn them into regular functions.
|
|
|
|
|
|
|
|
// Renders a frame of the summon animation.
|
|
|
|
#define bigcircle_summon(bigcircle, start_frame, q4_offset_end) \
|
|
|
|
boss_phase_frame == start_frame) { \
|
|
|
|
mdrv2_se_play(8); \
|
|
|
|
} \
|
|
|
|
bigcircle_summon_update_and_render(bigcircle, q4_offset_end); \
|
|
|
|
if(bigcircle_summon_done(bigcircle) /* return value */
|
|
|
|
|
|
|
|
// Renders a frame of the summon and flash animation.
|
|
|
|
#define bigcircle_summon_and_flash(bigcircle, start_frame, q4_offset_end) \
|
|
|
|
bigcircle_is_summon_frame(start_frame) && (bigcircle.frames == 0)) { \
|
|
|
|
if(bigcircle_summon(bigcircle, start_frame, q4_offset_end)) { \
|
|
|
|
bigcircle_sloppy_unput(bigcircle); /* (redundant) */ \
|
|
|
|
\
|
|
|
|
/* Also looks redundant, but we might have unblitted parts of */ \
|
|
|
|
/* the circle during the summon animation… */ \
|
|
|
|
bigcircle_put(bigcircle, V_WHITE); \
|
|
|
|
\
|
|
|
|
bigcircle.frames = 1; \
|
|
|
|
ent_unput_and_put_both(ENT_STILL_OR_WAVE, C_STILL); \
|
|
|
|
} \
|
|
|
|
} else if((bigcircle.frames != 0) && (bigcircle.frames < 40)) { \
|
|
|
|
bigcircle.frames++; \
|
|
|
|
if((bigcircle.frames % 8) == 0) { \
|
|
|
|
bigcircle_sloppy_unput(bigcircle); /* (redundant) */ \
|
|
|
|
bigcircle_put(bigcircle, COL_FX); \
|
|
|
|
} else if((bigcircle.frames % 8) == 4) { \
|
|
|
|
bigcircle_sloppy_unput(bigcircle); /* (redundant) */ \
|
|
|
|
bigcircle_put(bigcircle, V_WHITE); \
|
|
|
|
} \
|
|
|
|
} else if(bigcircle.frames != 0 /* return value */
|
|
|
|
|
|
|
|
// Circle around the Star of David
|
|
|
|
struct starcircle_t {
|
|
|
|
unsigned char angle;
|
|
|
|
int frames;
|
|
|
|
|
|
|
|
screen_x_t center_x(void) { return form_center_x(F_GIRL); }
|
|
|
|
screen_y_t center_y(void) { return form_center_y(F_GIRL); }
|
|
|
|
};
|
|
|
|
// -----------------
|
|
|
|
|
2022-01-29 23:23:27 +00:00
|
|
|
// .PTN
|
|
|
|
// ----
|
|
|
|
|
|
|
|
static const main_ptn_slot_t PTN_SLOT_BG_ENT = PTN_SLOT_BOSS_1;
|
|
|
|
static const main_ptn_slot_t PTN_SLOT_MISSILE = PTN_SLOT_BOSS_2;
|
|
|
|
// ----
|
|
|
|
|
2021-10-30 21:35:56 +00:00
|
|
|
#define bg_func_init(left, top, entity_src) { \
|
2022-05-09 13:09:04 +00:00
|
|
|
ent_sync(ENT_ATTACK, ENT_STILL_OR_WAVE); \
|
|
|
|
if(entity_src == (ENT_STILL_OR_WAVE + 1)) { \
|
2021-10-30 21:35:56 +00:00
|
|
|
left = ent_still_or_wave.cur_left; \
|
|
|
|
top = ent_still_or_wave.cur_top; \
|
2022-05-09 13:09:04 +00:00
|
|
|
} else if(entity_src == (ENT_ATTACK + 1)) { \
|
2021-10-30 21:35:56 +00:00
|
|
|
left = ent_attack.cur_left; \
|
|
|
|
top = ent_attack.cur_top; \
|
|
|
|
} \
|
2021-10-30 19:29:55 +00:00
|
|
|
}
|
|
|
|
|
2021-10-30 13:49:25 +00:00
|
|
|
void girl_bg_snap(int unncessary_parameter_that_still_needs_to_be_1_or_2)
|
2021-10-30 21:35:56 +00:00
|
|
|
{
|
|
|
|
int ptn_x;
|
|
|
|
int ptn_y;
|
|
|
|
screen_x_t left;
|
|
|
|
screen_y_t top;
|
|
|
|
int image;
|
|
|
|
|
|
|
|
bg_func_init(left, top, unncessary_parameter_that_still_needs_to_be_1_or_2);
|
|
|
|
|
|
|
|
image = 0;
|
|
|
|
ptn_snap_rect_from_1_8(
|
|
|
|
left, top, GIRL_W, GIRL_H, PTN_SLOT_BG_ENT, image, ptn_x, ptn_y
|
|
|
|
);
|
|
|
|
}
|
2021-10-30 13:49:25 +00:00
|
|
|
|
|
|
|
void girl_bg_put(int unncessary_parameter_that_still_needs_to_be_1_or_2)
|
2021-10-30 21:35:56 +00:00
|
|
|
{
|
|
|
|
int ptn_x;
|
|
|
|
int ptn_y;
|
|
|
|
screen_x_t left;
|
|
|
|
screen_y_t top;
|
|
|
|
int image = 0;
|
|
|
|
|
|
|
|
bg_func_init(left, top, unncessary_parameter_that_still_needs_to_be_1_or_2);
|
|
|
|
ptn_put_rect_noalpha_8(
|
|
|
|
left, top, GIRL_W, GIRL_H, PTN_SLOT_BG_ENT, image, ptn_x, ptn_y
|
|
|
|
);
|
|
|
|
}
|
2021-10-30 19:29:55 +00:00
|
|
|
|
2021-10-30 20:45:31 +00:00
|
|
|
void elis_load(void)
|
|
|
|
{
|
|
|
|
pellet_interlace = true;
|
|
|
|
Pellets.unknown_seven = 7;
|
2022-01-29 23:30:33 +00:00
|
|
|
elis_ent_load();
|
2022-05-07 14:30:24 +00:00
|
|
|
grc_load(GRC_SLOT_BOSS_1, "boss5_gr.grc");
|
2021-10-30 20:45:31 +00:00
|
|
|
ptn_new(PTN_SLOT_BG_ENT, ((GIRL_W / PTN_W) * (GIRL_H / PTN_H)));
|
|
|
|
Missiles.load(PTN_SLOT_MISSILE);
|
|
|
|
boss_palette_snap();
|
|
|
|
void elis_setup(void);
|
|
|
|
elis_setup();
|
|
|
|
particles_unput_update_render(PO_INITIALIZE, V_WHITE);
|
|
|
|
}
|
|
|
|
|
2021-10-30 20:26:08 +00:00
|
|
|
void elis_setup(void)
|
|
|
|
{
|
|
|
|
int col;
|
|
|
|
int comp;
|
|
|
|
|
|
|
|
ent_still_or_wave.pos_set(
|
|
|
|
BASE_LEFT, BASE_TOP, 48,
|
|
|
|
PLAYFIELD_LEFT, (PLAYFIELD_RIGHT + ((GIRL_W / 4) * 3)),
|
|
|
|
PLAYFIELD_TOP, (PLAYFIELD_BOTTOM - GIRL_H)
|
|
|
|
);
|
|
|
|
ent_attack.pos_set(
|
|
|
|
BASE_LEFT, BASE_TOP, 48,
|
|
|
|
PLAYFIELD_LEFT, (PLAYFIELD_RIGHT + ((GIRL_W / 4) * 3)),
|
|
|
|
PLAYFIELD_TOP, (PLAYFIELD_BOTTOM - GIRL_H)
|
|
|
|
);
|
|
|
|
ent_bat.pos_set(
|
|
|
|
BASE_LEFT, BASE_TOP, 48,
|
|
|
|
PLAYFIELD_LEFT, (PLAYFIELD_RIGHT + (BAT_W * 2)),
|
|
|
|
PLAYFIELD_TOP, (PLAYFIELD_BOTTOM - (BAT_H * 3))
|
|
|
|
);
|
|
|
|
ent_still_or_wave.hitbox_set(
|
|
|
|
((GIRL_W / 4) * 1), ((GIRL_H / 8) * 1),
|
|
|
|
((GIRL_W / 4) * 3), ((GIRL_H / 3) * 2)
|
|
|
|
);
|
|
|
|
// Note that [ent_attack] doesn't receive a hitbox!
|
|
|
|
ent_bat.hitbox_set(
|
|
|
|
((BAT_W / 6) * 1), ((BAT_H / 4) * 1),
|
|
|
|
((BAT_W / 6) * 5), ((BAT_H / 4) * 3)
|
|
|
|
);
|
|
|
|
|
|
|
|
boss_phase = 0;
|
|
|
|
boss_phase_frame = 0;
|
|
|
|
boss_hp = 14;
|
|
|
|
hud_hp_first_white = 10;
|
|
|
|
hud_hp_first_redwhite = 6;
|
|
|
|
random_seed = frame_rand;
|
|
|
|
palette_set_grayscale(boss_post_defeat_palette, 0x0, col, comp);
|
|
|
|
}
|
|
|
|
|
2021-10-30 19:44:58 +00:00
|
|
|
void elis_free(void)
|
|
|
|
{
|
2022-01-29 23:30:33 +00:00
|
|
|
elis_ent_free();
|
2022-01-29 23:23:27 +00:00
|
|
|
grc_free(GRC_SLOT_BOSS_1);
|
|
|
|
ptn_free(PTN_SLOT_BG_ENT);
|
|
|
|
ptn_free(PTN_SLOT_MISSILE);
|
2021-10-30 19:44:58 +00:00
|
|
|
}
|
|
|
|
|
2021-10-30 19:29:55 +00:00
|
|
|
bool16 wave_teleport(screen_x_t target_left, screen_y_t target_top)
|
|
|
|
{
|
2022-05-09 13:09:04 +00:00
|
|
|
ent_sync(ENT_ATTACK, ENT_STILL_OR_WAVE);
|
2021-10-30 19:29:55 +00:00
|
|
|
|
|
|
|
// Wave sprite
|
|
|
|
if(boss_phase_frame == 20) {
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
girl_bg_put(1);
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_1);
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
} else if(boss_phase_frame == 28) {
|
|
|
|
girl_bg_put(1);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_2);
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
} else if(boss_phase_frame == 36) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
2021-10-30 21:35:56 +00:00
|
|
|
girl_bg_put(1);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_3);
|
2021-10-30 19:29:55 +00:00
|
|
|
} else if(boss_phase_frame == 44) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
egc_copy_rect_1_to_0_16(
|
|
|
|
ent_still_or_wave.cur_left,
|
|
|
|
ent_still_or_wave.cur_top,
|
|
|
|
GIRL_W,
|
|
|
|
GIRL_H
|
|
|
|
);
|
|
|
|
} else if(boss_phase_frame == 52) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
ent_still_or_wave.pos_cur_set(target_left, target_top);
|
|
|
|
girl_bg_snap(1);
|
|
|
|
girl_bg_put(1); // unnecessary
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_3);
|
|
|
|
} else if(boss_phase_frame == 60) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
girl_bg_put(1);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_2);
|
|
|
|
} else if(boss_phase_frame == 68) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = true;
|
|
|
|
girl_bg_put(1);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_WAVE_1);
|
|
|
|
} else if(boss_phase_frame == 76) {
|
|
|
|
ent_still_or_wave.hitbox_orb_inactive = false;
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_STILL);
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
ent_still_or_wave.move_lock_and_put_image_8(C_STILL);
|
|
|
|
} else if(boss_phase_frame > 80) {
|
|
|
|
boss_phase_frame = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stars
|
|
|
|
if((boss_phase_frame % 4) != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-05-10 11:53:47 +00:00
|
|
|
extern CEntities<5> stars;
|
2021-10-30 19:29:55 +00:00
|
|
|
|
2022-05-23 21:50:17 +00:00
|
|
|
for(int i = 0; i < stars.count(); i++) {
|
2021-10-30 19:29:55 +00:00
|
|
|
if(boss_phase_frame > 4) {
|
|
|
|
egc_copy_rect_1_to_0_16_word_w(stars.left[i], stars.top[i], 8, 8);
|
|
|
|
}
|
|
|
|
if((boss_phase_frame < 40) || (boss_phase_frame > 52)) {
|
2022-05-10 11:53:47 +00:00
|
|
|
stars.left[i] = surround_random_left(ENT_STILL_OR_WAVE);
|
|
|
|
stars.top[i] = surround_random_top(ENT_STILL_OR_WAVE);
|
2021-10-30 19:29:55 +00:00
|
|
|
} else {
|
|
|
|
stars.left[i] = (stars.left[i] + (
|
2022-05-10 11:53:47 +00:00
|
|
|
(surround_random_left(ENT_STILL_OR_WAVE) - stars.left[i]) / 3
|
2021-10-30 19:29:55 +00:00
|
|
|
));
|
|
|
|
stars.top[i] = (stars.top[i] + (
|
2022-05-10 11:53:47 +00:00
|
|
|
(surround_random_top(ENT_STILL_OR_WAVE) - stars.top[i]) / 3
|
2021-10-30 19:29:55 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
if(boss_phase_frame < 68) {
|
|
|
|
shape8x8_star_put(stars.left[i], stars.top[i], 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2021-10-30 13:49:25 +00:00
|
|
|
|
2020-12-06 12:38:41 +00:00
|
|
|
#define select_for_rank elis_select_for_rank
|
|
|
|
#include "th01/main/select_r.cpp"
|
2022-05-11 14:37:53 +00:00
|
|
|
|
|
|
|
int pattern_11_lasers_across(void)
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
INTERVAL = 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define circle_center_x form_center_x(F_GIRL)
|
|
|
|
#define circle_center_y (ent_still_or_wave.cur_top + (GIRL_H / 3))
|
|
|
|
|
|
|
|
#define circle_radius pattern0_circle_radius
|
|
|
|
#define direction pattern0_direction
|
|
|
|
|
|
|
|
extern pixel_t circle_radius;
|
|
|
|
extern bool16 direction; // ACTUAL TYPE: x_direction_t
|
|
|
|
double target_left;
|
|
|
|
double target_y;
|
|
|
|
|
|
|
|
if(boss_phase_frame == 50) {
|
|
|
|
direction = (rand() % 2);
|
2022-05-12 14:59:50 +00:00
|
|
|
ent_unput_and_put_both(ENT_STILL_OR_WAVE, C_HAND, false);
|
2022-05-11 14:37:53 +00:00
|
|
|
select_for_rank(pattern_state.speed_multiplied_by_8,
|
|
|
|
(to_sp(6.25f) / 2),
|
|
|
|
(to_sp(6.875f) / 2),
|
|
|
|
(to_sp(7.5f) / 2),
|
|
|
|
(to_sp(8.125f) / 2)
|
|
|
|
);
|
|
|
|
} else if(boss_phase_frame == 60) {
|
|
|
|
shape_circle_put(
|
|
|
|
circle_center_x, circle_center_y, (GIRL_W / 4), COL_FX, 0x02
|
|
|
|
);
|
|
|
|
circle_radius = (GIRL_W / 4);
|
|
|
|
} else if(
|
|
|
|
(boss_phase_frame < 120) &&
|
|
|
|
(boss_phase_frame > 60) &&
|
|
|
|
((boss_phase_frame % 2) == 0)
|
|
|
|
) {
|
|
|
|
shape_circle_sloppy_unput(
|
|
|
|
circle_center_x, circle_center_y, circle_radius, 0x02
|
|
|
|
);
|
|
|
|
circle_radius += 8;
|
|
|
|
shape_circle_put(
|
|
|
|
circle_center_x, circle_center_y, circle_radius, COL_FX, (
|
|
|
|
(boss_phase_frame < 100) ? 0x02 :
|
|
|
|
(boss_phase_frame < 110) ? 0x08 :
|
|
|
|
0x20
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else if(boss_phase_frame == 120) {
|
|
|
|
shape_circle_sloppy_unput(
|
|
|
|
circle_center_x, circle_center_y, circle_radius, 0x20
|
|
|
|
);
|
|
|
|
} else if(boss_phase_frame == 150) {
|
2022-05-12 14:59:50 +00:00
|
|
|
ent_unput_and_put_both(ENT_STILL_OR_WAVE, C_STILL, false);
|
2022-05-11 14:37:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if((boss_phase_frame >= 70) && ((boss_phase_frame % INTERVAL) == 0)) {
|
|
|
|
if(direction == X_RIGHT) {
|
|
|
|
target_left = (PLAYFIELD_LEFT +
|
|
|
|
(((boss_phase_frame - 70) / INTERVAL) * (PLAYFIELD_W / 10))
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
target_left = (PLAYFIELD_RIGHT -
|
|
|
|
(((boss_phase_frame - 70) / INTERVAL) * (PLAYFIELD_W / 10))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
target_y = RES_Y;
|
|
|
|
shootout_laser_safe(boss_phase_frame / INTERVAL).spawn(
|
|
|
|
girl_lefteye_x(),
|
|
|
|
girl_lefteye_y(),
|
|
|
|
target_left,
|
|
|
|
target_y,
|
|
|
|
pattern_state.speed_multiplied_by_8,
|
|
|
|
V_WHITE,
|
|
|
|
25,
|
|
|
|
4
|
|
|
|
);
|
|
|
|
mdrv2_se_play(6);
|
|
|
|
|
|
|
|
// <= instead of < is why this pattern actually fires 11 lasers rather
|
|
|
|
// than the 10 you might guess from looking at the target calculation
|
|
|
|
// above.
|
|
|
|
if(
|
|
|
|
((direction == X_RIGHT) && (target_left >= PLAYFIELD_RIGHT)) ||
|
|
|
|
((direction == X_LEFT) && (target_left <= PLAYFIELD_LEFT))
|
2022-05-12 14:59:50 +00:00
|
|
|
) {
|
2022-05-11 14:37:53 +00:00
|
|
|
boss_phase_frame = 0;
|
|
|
|
return CHOOSE_NEW;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
#undef direction
|
|
|
|
#undef circle_radius
|
|
|
|
#undef circle_center_y
|
|
|
|
#undef circle_center_x
|
|
|
|
}
|
2022-05-12 11:34:18 +00:00
|
|
|
|
|
|
|
int pattern_random_downwards_missiles(void)
|
|
|
|
{
|
|
|
|
#define rifts pattern1_rifts
|
|
|
|
|
|
|
|
extern CEntities<5> rifts;
|
|
|
|
int cel; // ACTUAL TYPE: elis_grc_cel_t
|
|
|
|
pixel_t velocity_x;
|
|
|
|
pixel_t velocity_y;
|
|
|
|
unsigned char angle;
|
|
|
|
|
|
|
|
if(boss_phase_frame == 50) {
|
2022-05-12 14:59:50 +00:00
|
|
|
ent_unput_and_put_both(ENT_STILL_OR_WAVE, C_HAND, false);
|
2022-05-12 11:34:18 +00:00
|
|
|
select_for_rank(pattern_state.angle_range, 0x0F, 0x15, 0x19, 0x1D);
|
|
|
|
}
|
|
|
|
|
|
|
|
// That's quite the brave placement for this branch...
|
|
|
|
if((boss_phase_frame > 60) && ((boss_phase_frame % 3) == 0)) {
|
|
|
|
int i = (rand() % rifts.count());
|
|
|
|
angle = (
|
|
|
|
(rand() % pattern_state.angle_range) -
|
|
|
|
((pattern_state.angle_range - 0x01) / 2) +
|
|
|
|
0x40
|
|
|
|
);
|
|
|
|
vector2(velocity_x, velocity_y, 7, angle);
|
|
|
|
Missiles.add(rifts.left[i], rifts.top[i], velocity_x, velocity_y);
|
|
|
|
}
|
|
|
|
|
|
|
|
rifts_update_and_render(rifts, 60, 160, cel);
|
|
|
|
|
|
|
|
if(boss_phase_frame > 170) {
|
|
|
|
boss_phase_frame = 0;
|
|
|
|
return CHOOSE_NEW;
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
#undef rifts
|
|
|
|
}
|
2022-05-12 14:59:50 +00:00
|
|
|
|
|
|
|
int pattern_pellets_along_circle(void)
|
|
|
|
{
|
|
|
|
#define circle pattern2_circle
|
|
|
|
|
|
|
|
extern starcircle_t circle;
|
|
|
|
screen_x_t left;
|
|
|
|
screen_y_t top;
|
|
|
|
|
|
|
|
if(boss_phase_frame < 10) {
|
|
|
|
circle.frames = 0;
|
|
|
|
}
|
|
|
|
if(boss_phase_frame == 50) {
|
|
|
|
ent_unput_and_put_both(ENT_STILL_OR_WAVE, C_HAND, false);
|
|
|
|
circle.angle = 0x00;
|
|
|
|
select_for_rank(reinterpret_cast<int &>(pattern_state.group),
|
|
|
|
PG_1_AIMED,
|
|
|
|
PG_1_RANDOM_NARROW_AIMED,
|
|
|
|
PG_3_SPREAD_WIDE_AIMED,
|
|
|
|
// This will spawn (32 * 5) = 160 pellets, which is 60 more than
|
|
|
|
// the original PELLET_COUNT. As a result, Elis will only ever fire
|
|
|
|
// up to 20 of these spreads on Lunatic, rather than the coded 32.
|
|
|
|
PG_5_SPREAD_NARROW_AIMED
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adding a `double` value < 1.0 to an integer is still a NOP. That leads
|
|
|
|
// to the start and end angle for quadrant IV being identical, and nothing
|
|
|
|
// being drawn there as a result. Hard to call it a ZUN bug though, since
|
|
|
|
// this is the only function where this happens. But if it this was
|
|
|
|
// intended after all, why not just remove the call for quadrant IV?!
|
|
|
|
if(bigcircle_summon_and_flash(circle, 60, 0.05)) {
|
|
|
|
bigcircle_sloppy_unput(circle);
|
|
|
|
circle.angle = 0x00;
|
|
|
|
for(int i = 0; i < 32; i++) {
|
|
|
|
// lefteye?!
|
|
|
|
left = polar_x(girl_lefteye_x(), BIGCIRCLE_RADIUS, circle.angle);
|
|
|
|
|
|
|
|
top = polar_y(
|
|
|
|
form_center_y(F_GIRL), BIGCIRCLE_RADIUS, circle.angle
|
|
|
|
);
|
|
|
|
Pellets.add_group(left, top, pattern_state.group, to_sp(0.25f));
|
|
|
|
circle.angle += (0x100 / 32);
|
|
|
|
}
|
|
|
|
boss_phase_frame = 0;
|
|
|
|
circle.frames = 0;
|
|
|
|
return CHOOSE_NEW;
|
|
|
|
}
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
#undef circle
|
|
|
|
}
|
2022-05-12 16:09:36 +00:00
|
|
|
|
|
|
|
// Draws a line from [angle_1] to [angle_2] on the star circle around Elis.
|
|
|
|
void pascal near starcircle_line_put(
|
|
|
|
unsigned char angle_1, unsigned char angle_2, int col
|
|
|
|
)
|
|
|
|
{
|
|
|
|
screen_x_t p1_x = polar_x(form_center_x(F_GIRL), BIGCIRCLE_RADIUS, angle_1);
|
|
|
|
screen_y_t p1_y = polar_y(form_center_y(F_GIRL), BIGCIRCLE_RADIUS, angle_1);
|
|
|
|
screen_x_t p2_x = polar_x(form_center_x(F_GIRL), BIGCIRCLE_RADIUS, angle_2);
|
|
|
|
screen_y_t p2_y = polar_y(form_center_y(F_GIRL), BIGCIRCLE_RADIUS, angle_2);
|
|
|
|
graph_r_line(p1_x, p1_y, p2_x, p2_y, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
void pascal near starcircle_line_unput(
|
|
|
|
unsigned char angle_1, unsigned char angle_2
|
|
|
|
)
|
|
|
|
{
|
|
|
|
screen_x_t p1_x = polar_x(form_center_x(F_GIRL), BIGCIRCLE_RADIUS, angle_1);
|
|
|
|
screen_y_t p1_y = polar_y(form_center_y(F_GIRL), BIGCIRCLE_RADIUS, angle_1);
|
|
|
|
screen_x_t p2_x = polar_x(form_center_x(F_GIRL), BIGCIRCLE_RADIUS, angle_2);
|
|
|
|
screen_y_t p2_y = polar_y(form_center_y(F_GIRL), BIGCIRCLE_RADIUS, angle_2);
|
|
|
|
graph_r_line_unput(p1_x, p1_y, p2_x, p2_y);
|
|
|
|
}
|
2022-05-12 16:45:46 +00:00
|
|
|
|
|
|
|
int phase_1(int id)
|
|
|
|
{
|
|
|
|
switch(id) {
|
|
|
|
case CHOOSE_NEW:
|
|
|
|
return (rand() % 4);
|
|
|
|
case 1: return pattern_11_lasers_across();
|
|
|
|
case 2: return pattern_random_downwards_missiles();
|
|
|
|
case 3: return pattern_pellets_along_circle();
|
|
|
|
}
|
|
|
|
return CHOOSE_NEW;
|
|
|
|
}
|
2022-05-12 18:05:16 +00:00
|
|
|
|
|
|
|
void pascal near star_of_david_put(int col)
|
|
|
|
{
|
|
|
|
starcircle_line_put(-0x40, +0x16, col);
|
|
|
|
starcircle_line_put(-0x40, +0x6A, col);
|
|
|
|
starcircle_line_put(+0x16, +0x6A, col);
|
|
|
|
starcircle_line_put(+0x40, -0x6A, col);
|
|
|
|
starcircle_line_put(+0x40, -0x16, col);
|
|
|
|
starcircle_line_put(-0x6A, -0x16, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void star_of_david_unput(void) {
|
|
|
|
starcircle_line_unput(-0x40, +0x16);
|
|
|
|
starcircle_line_unput(-0x40, +0x6A);
|
|
|
|
starcircle_line_unput(+0x16, +0x6A);
|
|
|
|
starcircle_line_unput(+0x40, -0x6A);
|
|
|
|
starcircle_line_unput(+0x40, -0x16);
|
|
|
|
starcircle_line_unput(-0x6A, -0x16);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Renders a frame of the Star of David summon/flash animation in front of a
|
|
|
|
// danmaku pattern.
|
|
|
|
elis_starpattern_ret_t near star_of_david(void)
|
|
|
|
{
|
|
|
|
#define circle star_of_david_circle
|
|
|
|
|
|
|
|
extern starcircle_t circle;
|
|
|
|
|
|
|
|
if(boss_phase_frame < 5) {
|
|
|
|
circle.frames = 0;
|
|
|
|
circle.angle = 0x00;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(boss_phase_frame < 10) {
|
|
|
|
return SP_STAR_OF_DAVID;
|
|
|
|
}
|
|
|
|
if(boss_phase_frame == 10) {
|
|
|
|
ent_unput_and_put_both(ENT_ATTACK, C_PREPARE);
|
|
|
|
circle.angle = 0x00;
|
|
|
|
circle.frames = 0;
|
|
|
|
}
|
|
|
|
if(bigcircle_is_summon_frame(10) && (circle.frames == 0)) {
|
|
|
|
if(bigcircle_summon(circle, 10, 0x02)) {
|
|
|
|
circle.frames = 1;
|
|
|
|
bigcircle_sloppy_unput(circle); // (redundant, position unchanged)
|
|
|
|
bigcircle_put(circle, V_WHITE);
|
|
|
|
}
|
|
|
|
} else if(bigcircle_summon_done(circle)) {
|
|
|
|
circle.frames++;
|
|
|
|
if(circle.frames == 10) {
|
|
|
|
star_of_david_put(V_WHITE);
|
|
|
|
}
|
|
|
|
if((circle.frames > 20) && ((circle.frames % 4) == 0)) {
|
|
|
|
star_of_david_put(COL_FX);
|
|
|
|
bigcircle_put(circle, COL_FX);
|
|
|
|
} else if((circle.frames > 20) && ((circle.frames % 4) == 2)) {
|
|
|
|
star_of_david_put(V_WHITE);
|
|
|
|
bigcircle_put(circle, V_WHITE);
|
|
|
|
}
|
|
|
|
if(circle.frames > 60) {
|
|
|
|
star_of_david_unput();
|
|
|
|
bigcircle_sloppy_unput(circle);
|
|
|
|
boss_phase_frame = 0;
|
|
|
|
circle.angle = 0x00;
|
|
|
|
circle.frames = 0;
|
|
|
|
return SP_PATTERN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return SP_STAR_OF_DAVID;
|
|
|
|
|
|
|
|
#undef circle
|
|
|
|
}
|