-
Snakey snake
Experimental custom boss script ahoy.
Code:
// ====================================
// snakey_snake - This FFC script codes a custom
// boss which moves in a snake pattern. The boss'
// body is made up of ten FFCs. The first FFC
// follows the player around the room. The other FFCs
// follow the previous FFC. The boss' weak point can
// occur on any segment the player wishes. As the
// boss loses hit points, it loses segments but moves
// faster. The vulnerable spot won't move until the segment
// it is on top of falls away. It will then move to the next
// segment closest to the head.
//
// DATA
// D0 - The FFC number of the head of the snake.
// D1 - The initial speed of the snake.
// D2 - The percentage by which the snake's speed increases
// after losing each segment. (10-20% is a good idea)
// D3 - The enemy id of the npc to be ghosted as hit points.
// D4 - The hit points of the ghosted enemy
// D5 - The ffc number of body segment of the snake that the ghosted enemy
// will track. (I.e. the weak point). Must be 1-10, with 1 being
// the head.
//
// FFCS
// This script expects that the next nine FFCs after the
// head FFC will be used as the snake's body segments.
// =====================================
ffc snakey_snake{
void run (int head_ffc_number, int init_speed, int percent_incr_speed,
int ghost_npc_id, int hitpoints, int vuln_segment){
ffc head_ffc = Screen->LoadFFC(head_ffc_number);
ffc seg1_ffc = Screen->LoadFFC(head_ffc_number + 1);
ffc seg2_ffc = Screen->LoadFFC(head_ffc_number + 2);
ffc seg3_ffc = Screen->LoadFFC(head_ffc_number + 3);
ffc seg4_ffc = Screen->LoadFFC(head_ffc_number + 4);
ffc seg5_ffc = Screen->LoadFFC(head_ffc_number + 5);
ffc seg6_ffc = Screen->LoadFFC(head_ffc_number + 6);
ffc seg7_ffc = Screen->LoadFFC(head_ffc_number + 7);
ffc seg8_ffc = Screen->LoadFFC(head_ffc_number + 8);
ffc seg9_ffc = Screen->LoadFFC(head_ffc_number + 9);
ffc vuln_ffc = Screen->LoadFFC(vuln_segment);
npc ghosted_enemy = Screen->CreateNPC(ghost_npc_id);
ghosted_enemy->HP = hitpoints;
int x = vuln_ffc->X;
int y = vuln_ffc->Y;
ghosted_enemy->X = x;
ghosted_enemy->Y = y;
int current_speed = init_speed;
int total_segments = 9;
while(true){
// ===============
// Check for hit point based changes in behavior
// ===============
if( ghosted_enemy->HP < ( hitpoints * (9/10)) ){
total_segments = 8;
seg9_ffc->X = 0;
seg9_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 9) {
vuln_segment = head_ffc_number + 8;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (8/10)) ){
total_segments = 7;
seg8_ffc->X = 0;
seg8_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 8) {
vuln_segment = head_ffc_number + 7;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (7/10)) ){
total_segments = 6;
seg7_ffc->X = 0;
seg7_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 7) {
vuln_segment = head_ffc_number + 6;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (6/10)) ){
total_segments = 5;
seg6_ffc->X = 0;
seg6_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 6) {
vuln_segment = head_ffc_number + 5;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (5/10)) ){
total_segments = 4;
seg5_ffc->X = 0;
seg5_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 5) {
vuln_segment = head_ffc_number + 4;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (4/10)) ){
total_segments = 3;
seg4_ffc->X = 0;
seg4_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 4) {
vuln_segment = head_ffc_number + 3;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (3/10)) ){
total_segments = 2;
seg4_ffc->X = 0;
seg4_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 3) {
vuln_segment = head_ffc_number + 2;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (3/10)) ){
total_segments = 2;
seg3_ffc->X = 0;
seg3_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 3) {
vuln_segment = head_ffc_number + 2;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (2/10)) ){
total_segments = 1;
seg2_ffc->X = 0;
seg2_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 2) {
vuln_segment = head_ffc_number + 1;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
if( ghosted_enemy->HP < ( hitpoints * (1/10)) ){
total_segments = 0;
seg1_ffc->X = 0;
seg1_ffc->Y = -16;
current_speed = current_speed + (current_speed * (percent_incr_speed / 100));
if (vuln_segment == head_ffc_number + 1) {
vuln_segment = head_ffc_number;
vuln_ffc = Screen->LoadFFC(vuln_segment);
} // end of nested if
} // end of if
// ================
// Move the FFCs
// ================
// Move the head
if ( head_ffc->X > Link->X ) { head_ffc->Vx = -current_speed; }
else { head_ffc->Vx = current_speed;}
if ( head_ffc->Y > Link->Y ) { head_ffc->Vy = -current_speed; }
else { head_ffc->Vy = current_speed;}
// Move segment 1, if its around
if ( total_segments >= 1){
if ( seg1_ffc->X > head_ffc->X ) { seg1_ffc->Vx = -current_speed; }
else { seg1_ffc->Vx = current_speed;}
if ( seg1_ffc->Y > head_ffc->Y ) { seg1_ffc->Vy = -current_speed; }
else { seg1_ffc->Vy = current_speed;}
} // end of moving segment 1
// Move segment 2, if its around
if ( total_segments >= 2){
if ( seg2_ffc->X > seg1_ffc->X ) { seg2_ffc->Vx = -current_speed; }
else { seg2_ffc->Vx = current_speed;}
if ( seg2_ffc->Y > seg1_ffc->Y ) { seg2_ffc->Vy = -current_speed; }
else { seg2_ffc->Vy = current_speed;}
} // end of moving segment 2
// Move segment 3, if its around
if ( total_segments >= 3){
if ( seg3_ffc->X > seg2_ffc->X ) { seg3_ffc->Vx = -current_speed; }
else { seg3_ffc->Vx = current_speed;}
if ( seg3_ffc->Y > seg2_ffc->Y ) { seg3_ffc->Vy = -current_speed; }
else { seg3_ffc->Vy = current_speed;}
} // end of moving segment 3
// Move segment 4, if its around
if ( total_segments >= 4){
if ( seg4_ffc->X > seg3_ffc->X ) { seg4_ffc->Vx = -current_speed; }
else { seg4_ffc->Vx = current_speed;}
if ( seg4_ffc->Y > seg3_ffc->Y ) { seg4_ffc->Vy = -current_speed; }
else { seg4_ffc->Vy = current_speed;}
} // end of moving segment 4
// Move segment 5, if its around
if ( total_segments >= 5){
if ( seg5_ffc->X > seg4_ffc->X ) { seg5_ffc->Vx = -current_speed; }
else { seg5_ffc->Vx = current_speed;}
if ( seg5_ffc->Y > seg4_ffc->Y ) { seg5_ffc->Vy = -current_speed; }
else { seg5_ffc->Vy = current_speed;}
} // end of moving segment 5
// Move segment 6, if its around
if ( total_segments >= 6){
if ( seg6_ffc->X > seg5_ffc->X ) { seg6_ffc->Vx = -current_speed; }
else { seg6_ffc->Vx = current_speed;}
if ( seg6_ffc->Y > seg5_ffc->Y ) { seg6_ffc->Vy = -current_speed; }
else { seg6_ffc->Vy = current_speed;}
} // end of moving segment 6
// Move segment 7, if its around
if ( total_segments >= 7){
if ( seg7_ffc->X > seg6_ffc->X ) { seg7_ffc->Vx = -current_speed; }
else { seg7_ffc->Vx = current_speed;}
if ( seg7_ffc->Y > seg6_ffc->Y ) { seg7_ffc->Vy = -current_speed; }
else { seg7_ffc->Vy = current_speed;}
} // end of moving segment 7
// Move segment 8, if its around
if ( total_segments >= 8){
if ( seg8_ffc->X > seg7_ffc->X ) { seg8_ffc->Vx = -current_speed; }
else { seg8_ffc->Vx = current_speed;}
if ( seg8_ffc->Y > seg7_ffc->Y ) { seg8_ffc->Vy = -current_speed; }
else { seg8_ffc->Vy = current_speed;}
} // end of moving segment 8
// Move segment 9, if its around
if ( total_segments >= 9){
if ( seg9_ffc->X > seg8_ffc->X ) { seg9_ffc->Vx = -current_speed; }
else { seg9_ffc->Vx = current_speed;}
if ( seg9_ffc->Y > seg8_ffc->Y ) { seg9_ffc->Vy = -current_speed; }
else { seg9_ffc->Vy = current_speed;}
} // end of moving segment 9
// =======================
// Move the ghosted enemy to the vulnerable spot
// =======================
if ( Screen->numNPC() < 0 ){
x = vuln_ffc->X;
y = vuln_ffc->Y;
ghosted_enemy->X = x;
ghosted_enemy->Y = y;
} // end of if
Waitframe();
} // end of while loop
} // end of void run
} // end of snakey_snake
Once i get this working, it should be pretty simple to make the snake's head change directions depending on which way it's going. (Just stick "head_ffc->Data = original_combo + 1;" type things in the code where the snake decides to go east, west, north, or south.)
-
Re: Snakey snake
Whoooaaa shit. I've been debugging this code, and it turns out that this script, running alone, slows ZQuest down to a crawl. Looks like I wont be using snakey snake any time soon.
Now, if we had arrays, this code would be much simplier..
-
Re: Snakey snake
If you split up the HP checks differently, you could drastically reduce the number of comparisons it makes each frame, which should speed it up significantly. Something like this:
Code:
if(HP<50%)
{
if(HP<30%)
{
if(HP<10%)
then...
else if(HP<20%)
then...
else
then...
}
else if(HP<40%)
then...
else
then...
}
else
// even more...
That's probably not the best way to divide them up, but you see what I mean. Dropping from ten such tests per frame to three or four makes a bigger difference than you might expect.
Also, using HP*0.9 instead of HP*9/10 might help. The compiler doesn't do much optimization, I don't think.
-
Re: Snakey snake
time to optimize the scripting engine!
*cries*
-
Re: Snakey snake
Well, switch statements and arrays would help out alot. And more intelligent coding. I'm taking a pretty "brute force" approach here.
-
Re: Snakey snake
I've found the bottleneck in the scripting engine and am in the process of patching it up. Expect MUCH better performace from scipts in beta 16c.