Code:
// =================================================
// Tentaplus - This script codes the Pieces Master, Tentaplus. Has
// three attack patterns: (1) loop-de-looping around the middle of the
// screen; (2) chasing player and trying to grab her in his tentacles (if
// succeeds, Tentaplus holds player stationary and drains her health to
// its own); (3) swooping over the top or bottom of screen spraying
// bubbles.
// Throughout combat, tentaplus babies will swarm around it, making the
// tentaplus impossible to hit. Periodically, squid torpedoes
// will emerge from the walls. Coordinate one to hit Tentaplus, and the
// babies will fall away, making Tentaplus temporarily vulnerable.
// INPUT:
// D0 = The number of the FFC centered on the body.
// D1 = hit points of this FFC
// D2 = number of the first of 6 FFC making up the body
// of the ship: 1 2 3
// 4 5 6
// 16x64 and makes up the final right collumn of the boss.
// D3 = number of first of 12 FFCs making up bubbles sprayed by Tentaplus.
// D4 = number of first of 3 FFCs making up torpedoes
// ==================================================
ffc script Tentaplus_CE{
void run (int this_ffc_number, int hit_points, int body_ffc_number, int bubble_ffc_number, int torpedo_ffc_number){
// ---------------------------
// GENERAL ENEMY SETUP (same for all)
// ---------------------------
ffc this_ffc = Screen->LoadFFC(this_ffc_number);
int head_location_X;
int head_location_Y;
boss_flag = true;
npc ghosted_enemy = Screen->CreateNPC(85);
ghosted_enemy->HP = hit_points;
npc ghosted_damage_enemy = Screen->CreateNPC(200);
ffc body1 = Screen->LoadFFC(body_ffc_number);
ffc body2 = Screen->LoadFFC(body_ffc_number+1);
ffc body3 = Screen->LoadFFC(body_ffc_number+2);
ffc bubble1 = Screen->LoadFFC(bubble_ffc_number); bubble1->X = -16; bubble1->Y = -16;
ffc bubble2 = Screen->LoadFFC(bubble_ffc_number+1); bubble2->X = -16; bubble2->Y = -16;
ffc bubble3 = Screen->LoadFFC(bubble_ffc_number+2); bubble3->X = -16; bubble3->Y = -16;
ffc bubble4 = Screen->LoadFFC(bubble_ffc_number+3); bubble4->X = -16; bubble4->Y = -16;
ffc bubble5 = Screen->LoadFFC(bubble_ffc_number+4); bubble5->X = -16; bubble5->Y = -16;
ffc bubble6 = Screen->LoadFFC(bubble_ffc_number+5); bubble6->X = -16; bubble6->Y = -16;
ffc bubble7 = Screen->LoadFFC(bubble_ffc_number+6); bubble7->X = -16; bubble7->Y = -16;
ffc bubble8 = Screen->LoadFFC(bubble_ffc_number+7); bubble8->X = -16; bubble8->Y = -16;
ffc bubble9 = Screen->LoadFFC(bubble_ffc_number+8); bubble9->X = -16; bubble9->Y = -16;
ffc bubble10 = Screen->LoadFFC(bubble_ffc_number+9); bubble10->X = -16; bubble10->Y = -16;
ffc bubble11 = Screen->LoadFFC(bubble_ffc_number+10); bubble11->X = -16; bubble11->Y = -16;
ffc bubble12 = Screen->LoadFFC(bubble_ffc_number+11); bubble12->X = -16; bubble12->Y = -16;
ffc torpedo1 = Screen->LoadFFC(torpedo_ffc_number); torpedo1->X = -16; torpedo1->Y = -16;
ffc torpedo2 = Screen->LoadFFC(torpedo_ffc_number+1); torpedo2->X = -16; torpedo2->Y = -16;
ffc torpedo3 = Screen->LoadFFC(torpedo_ffc_number+2); torpedo3->X = -16; torpedo3->Y = -16;
int torpedo_counter = 250; // countdown till torpedo fires
int torpedo_explosion1_counter = 0; // Keeps track of explosion timing.
int torpedo_explosion2_counter = 0;
int torpedo_explosion3_counter = 0;
int original_CSet = body1->CSet;
int prev_health = ghosted_enemy->HP; // The health of the ghosted enemy last frame
int invuln_counter = 0; // Enemy is invulnerable briefly after being damaged.
int state = 0; // State 0 = normal movement
// State 1 = reacting to damage
// State 2 = enemy is dead
int state_counter = 0;
int shot_counter = 0;
int attack_state = 0; // Start in wait mode
int wobble = 0;
int target_X;
int target_Y;
item end_boss;
// --------------------------
// Enemy Projectile Setup
// --------------------------
// We don't have arrays. We only have 32 FFCs. So to make 25+ projectiles,
// we make a bunch of enemies!
int first_projectile_enemy_number = Screen->NumNPCs() + 1;
int i;
npc current_enemy;
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->CreateNPC(190);
current_enemy->X = -16; // Hide ze enemy off the screen
current_enemy->Y = -16;
current_enemy->WeaponDamage = 0; // Used as Vx
current_enemy->BossPal = 0; // Used as Vy
current_enemy->HP = 99999;
}
// So now there are 25 baddies off the screen waiting patiently.
while(true){
// --------------------------
// DRAW ENEMY LIFE BAR
// --------------------------
Screen->Rectangle(4,11,9,18,70,108,1,0,0,0,true,128);
if(ghosted_enemy->HP>=100){
Screen->Rectangle(4,11,(71-((62*(ghosted_enemy->HP-100)) / (hit_points-100))),17,70,101,1,0,0,0,true,128);
}
Screen->DrawTile(3,8,71,15118,1,1,6,1,0,0, 0,0,true,128);
// --------------------------
// ENEMY DAMAGE CONTROL
// --------------------------
if (invuln_counter <= 0){
ghosted_enemy->X = this_ffc->X;
ghosted_enemy->Y = this_ffc->Y;
body1->CSet = original_CSet;
body2->CSet = original_CSet;
body3->CSet = original_CSet;
}
else{
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
invuln_counter--;
body1->CSet++;
}
// check to see if enemy has been damaged
if (prev_health > ghosted_enemy->HP){
invuln_counter = 20;
}
// if hit points are exhausted, enemy explodes
if ((ghosted_enemy->HP < 100)&&(ghosted_enemy->HP > 0)){
boss_flag = false;
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
ghosted_enemy->HP--;
wobble++;
Screen->Circle(3,this_ffc->X,this_ffc->Y,2*wobble,109,1,0,0,0,true,128);
Screen->Circle(3,this_ffc->X,this_ffc->Y,(64*Cos(wobble)),109,1,0,0,0,true,128);
Screen->Circle(3,this_ffc->X + Rand(48) - 24,this_ffc->Y + Rand(48) - 24,
8 + Rand(8),109,1,0,0,0,true,128);
if(ghosted_enemy->HP == 50) {Game->PlaySound(84);;}
if(!((this_ffc->Data >= 3756) && (this_ffc->Data <= 3765))){
Game->PlaySound(88);
this_ffc->Data = 3756;
body1->Data = 3756;
body2->Data = 3756;
body3->Data = 3756;
}
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 72; i++){
current_enemy = Screen->LoadNPC(i);
current_enemy->HP = 0;
}
if(ghosted_enemy->HP<=2){
end_boss = Screen->CreateItem(62);
end_boss->X = Link->X;
end_boss->Y = Link->Y;
}
}
if (ghosted_enemy->HP>100){
// --------------------------
// ENEMY MOVEMENT (varies per enemy!)
// --------------------------
// Attack State 0
// ----------------------------
// Loop-de-looping in middle of screen.
// Babies swarming, invincible.
// ----------------------------
if ( attack_state == 0){
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
target_X = 120 + 72*Sin(wobble);
target_Y = 72 + 64*Cos(wobble);
wobble++;
body1->Data = 3856;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 3863;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 3867;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(this_ffc->X < target_X){this_ffc->Vx = this_ffc->Vx+0.2;}
else{this_ffc->Vx = this_ffc->Vx-0.2;}
if(this_ffc->Y < target_Y){this_ffc->Vy = this_ffc->Vy+0.2;}
else{this_ffc->Vy = this_ffc->Vy-0.2;}
if(this_ffc->Vx>1){this_ffc->Vx=1;}
if(this_ffc->Vx<-1){this_ffc->Vx=-1;}
if(this_ffc->Vy>1){this_ffc->Vy=1;}
if(this_ffc->Vy<-1){this_ffc->Vy=-1;}
if(state_counter >= 400){
state_counter = 0;
wobble = 0;
attack_state = 1;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
// Move babies a swarm around Tentaplus
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->LoadNPC(i);
if(current_enemy->X<this_ffc->X-32){
current_enemy->WeaponDamage = 1 + Rand(2);
}
if(current_enemy->X>this_ffc->X+32){
current_enemy->WeaponDamage = 1 + Rand(2) +10;
}
if(current_enemy->Y<this_ffc->Y-32){
current_enemy->BossPal = 1 + Rand(2);
}
if(current_enemy->Y>this_ffc->Y+32){
current_enemy->BossPal = 1 + Rand(2) +10;
}
}
}
// Attack State 1
// ----------------------------
// Chasing player in attempt to trap
// her in its tentacles.
// ----------------------------
if ( attack_state == 1){
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
target_X = Link->X;
target_Y = Link->Y - 32;
wobble++;
body1->Data = 3892;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 0;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 0;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(this_ffc->X < target_X){this_ffc->Vx = this_ffc->Vx+0.2;}
else{this_ffc->Vx = this_ffc->Vx-0.2;}
if(this_ffc->Y < target_Y){this_ffc->Vy = this_ffc->Vy+0.2;}
else{this_ffc->Vy = this_ffc->Vy-0.2;}
if(this_ffc->Vx>1){this_ffc->Vx=1;}
if(this_ffc->Vx<-1){this_ffc->Vx=-1;}
if(this_ffc->Vy>1){this_ffc->Vy=1;}
if(this_ffc->Vy<-1){this_ffc->Vy=-1;}
if((Abs(this_ffc->X-Link->X)<8)&&(this_ffc->Y<Link->Y)&&(Abs(this_ffc->Y-Link->Y)<32)){
attack_state = 2;
state_counter = 0;
wobble = 0;
}
if(state_counter >= 100){
state_counter = 0;
wobble = 0;
attack_state = 3;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
// Move babies a swarm around Tentaplus
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->LoadNPC(i);
if(current_enemy->X<this_ffc->X-32){
current_enemy->WeaponDamage = 1 + Rand(2);
}
if(current_enemy->X>this_ffc->X+32){
current_enemy->WeaponDamage = 1 + Rand(2) +10;
}
if(current_enemy->Y<this_ffc->Y-32){
current_enemy->BossPal = 1 + Rand(2);
}
if(current_enemy->Y>this_ffc->Y+32){
current_enemy->BossPal = 1 + Rand(2) +10;
}
}
}
// Attack State 2
// ----------------------------
// Successful! Player held, her health
// decreases while Tentaplus's increases.
// ----------------------------
if ( attack_state == 2){
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
ghosted_enemy->HP++;
if(wobble>=5){
wobble = 0;
Link->HP--;
}else{
wobble++;
}
Link->X = this_ffc->X;
Link->Y = this_ffc->Y+32;
body1->Data = 3904;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 3875;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 3879;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(state_counter >= 100){
state_counter = 0;
wobble = 0;
attack_state = 0;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
// Move babies a swarm around Tentaplus
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->LoadNPC(i);
if(current_enemy->X<this_ffc->X-32){
current_enemy->WeaponDamage = 1 + Rand(2);
}
if(current_enemy->X>this_ffc->X+32){
current_enemy->WeaponDamage = 1 + Rand(2) +10;
}
if(current_enemy->Y<this_ffc->Y-32){
current_enemy->BossPal = 1 + Rand(2);
}
if(current_enemy->Y>this_ffc->Y+32){
current_enemy->BossPal = 1 + Rand(2) +10;
}
}
}
// Attack State 3
// ----------------------------
// Swoops top or bottom of screen
// spraying bubbles.
// ----------------------------
if ( attack_state == 3){
ghosted_enemy->X = -16;
ghosted_enemy->Y = -16;
target_X = 120 + 60*Sin(3*wobble);
target_Y = 16;
wobble++;
body1->Data = 3856;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 3863;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 3867;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(this_ffc->X < target_X){this_ffc->Vx = this_ffc->Vx+0.2;}
else{this_ffc->Vx = this_ffc->Vx-0.2;}
if(this_ffc->Y < target_Y){this_ffc->Vy = this_ffc->Vy+0.2;}
else{this_ffc->Vy = this_ffc->Vy-0.2;}
if(this_ffc->Vx>2){this_ffc->Vx=2;}
if(this_ffc->Vx<-2){this_ffc->Vx=-2;}
if(this_ffc->Vy>2){this_ffc->Vy=2;}
if(this_ffc->Vy<-2){this_ffc->Vy=-2;}
if((Abs(this_ffc->X-Link->X)<8)&&(this_ffc->Y<Link->Y)&&(Abs(this_ffc->Y-Link->Y)<32)){
attack_state = 2;
state_counter = 0;
wobble = 0;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}
if((state_counter==25)||(state_counter==85)){
bubble1->Data = 3883;
bubble1->CSet = original_CSet;
bubble1->X = this_ffc->X;
bubble1->Y = this_ffc->Y;
bubble1->Vx = -0.5;
bubble1->Vy = -2;
bubble7->Data = 3883;
bubble7->CSet = original_CSet;
bubble7->X = this_ffc->X;
bubble7->Y = this_ffc->Y;
bubble7->Vx = 0.5;
bubble7->Vy = -2;
Game->PlaySound(89);
}
if((state_counter==35)||(state_counter==95)){
bubble2->Data = 3883;
bubble2->CSet = original_CSet;
bubble2->X = this_ffc->X;
bubble2->Y = this_ffc->Y;
bubble2->Vx = 0.5;
bubble2->Vy = -2;
bubble8->Data = 3883;
bubble8->CSet = original_CSet;
bubble8->X = this_ffc->X;
bubble8->Y = this_ffc->Y;
bubble8->Vx = -0.5;
bubble8->Vy = -2;
Game->PlaySound(89);
}
if((state_counter==45)||(state_counter==105)){
bubble3->Data = 3883;
bubble3->CSet = original_CSet;
bubble3->X = this_ffc->X;
bubble3->Y = this_ffc->Y;
bubble3->Vx = -0.5;
bubble3->Vy = -2;
bubble9->Data = 3883;
bubble9->CSet = original_CSet;
bubble9->X = this_ffc->X;
bubble9->Y = this_ffc->Y;
bubble9->Vx = 0.5;
bubble9->Vy = -2;
Game->PlaySound(89);
}
if((state_counter==55)||(state_counter==115)){
bubble4->Data = 3883;
bubble4->CSet = original_CSet;
bubble4->X = this_ffc->X;
bubble4->Y = this_ffc->Y;
bubble4->Vx = 0.5;
bubble4->Vy = -2;
bubble10->Data = 3883;
bubble10->CSet = original_CSet;
bubble10->X = this_ffc->X;
bubble10->Y = this_ffc->Y;
bubble10->Vx = -0.5;
bubble10->Vy = -2;
Game->PlaySound(89);
}
if((state_counter==65)||(state_counter==125)){
bubble5->Data = 3883;
bubble5->CSet = original_CSet;
bubble5->X = this_ffc->X;
bubble5->Y = this_ffc->Y;
bubble5->Vx = -0.5;
bubble5->Vy = -2;
bubble11->Data = 3883;
bubble11->CSet = original_CSet;
bubble11->X = this_ffc->X;
bubble11->Y = this_ffc->Y;
bubble11->Vx = 0.5;
bubble11->Vy = -2;
Game->PlaySound(89);
}
if((state_counter==75)||(state_counter==135)){
bubble6->Data = 3883;
bubble6->CSet = original_CSet;
bubble6->X = this_ffc->X;
bubble6->Y = this_ffc->Y;
bubble6->Vx = 0.5;
bubble6->Vy = -2;
bubble12->Data = 3883;
bubble12->CSet = original_CSet;
bubble12->X = this_ffc->X;
bubble12->Y = this_ffc->Y;
bubble12->Vx = -0.5;
bubble12->Vy = -2;
Game->PlaySound(89);
}
if(state_counter >= 150){
state_counter = 0;
wobble = 0;
attack_state = 0;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
// Move babies a swarm around Tentaplus
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->LoadNPC(i);
if(current_enemy->X<this_ffc->X-32){
current_enemy->WeaponDamage = 1 + Rand(2);
}
if(current_enemy->X>this_ffc->X+32){
current_enemy->WeaponDamage = 1 + Rand(2) +10;
}
if(current_enemy->Y<this_ffc->Y-32){
current_enemy->BossPal = 1 + Rand(2);
}
if(current_enemy->Y>this_ffc->Y+32){
current_enemy->BossPal = 1 + Rand(2) +10;
}
}
}
// Attack State 4
// ----------------------------
// Hit by torpedo! Babies scatter
// and Tentaplus is vulnerable.
// ----------------------------
if ( attack_state == 4){
ghosted_enemy->X = this_ffc->X;
ghosted_enemy->Y = this_ffc->Y;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
body1->Data = 3868;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 0;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 0;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(state_counter >= 200){
state_counter = 0;
wobble = 0;
attack_state = 5;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
}
// Attack State 5
// ----------------------------
// Recovering from torpedo hit;
// babies returning.
// ----------------------------
if ( attack_state == 5){
ghosted_enemy->X = this_ffc->X;
ghosted_enemy->Y = this_ffc->Y;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
body1->Data = 3868;
body1->X = this_ffc->X-16;
body1->Y = this_ffc->Y-16;
body2->Data = 0;
body2->X = this_ffc->X;
body2->Y = this_ffc->Y+16;
body3->Data = 0;
body3->X = this_ffc->X;
body3->Y = this_ffc->Y+32;
if(state_counter >= 100){
state_counter = 0;
wobble = 0;
attack_state = 0;
this_ffc->Vx = 0;
this_ffc->Vy = 0;
}else{
state_counter++;
}
for(i = first_projectile_enemy_number; i < first_projectile_enemy_number + 25; i++){
current_enemy = Screen->LoadNPC(i);
if(current_enemy->X<this_ffc->X-32){
current_enemy->WeaponDamage = 1 + Rand(2);
}
if(current_enemy->X>this_ffc->X+32){
current_enemy->WeaponDamage = 1 + Rand(2) +10;
}
if(current_enemy->Y<this_ffc->Y-32){
current_enemy->BossPal = 1 + Rand(2);
}
if(current_enemy->Y>this_ffc->Y+32){
current_enemy->BossPal = 1 + Rand(2) +10;
}
}
}
CONT'D BELOW