PDA

View Full Version : Snakey snake



C-Dawg
01-12-2007, 08:44 PM
Experimental custom boss script ahoy.



// ====================================
// 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.)

C-Dawg
01-12-2007, 11:48 PM
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..

Saffith
01-13-2007, 12:03 AM
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:

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.

jman2050
01-13-2007, 12:30 AM
time to optimize the scripting engine!

*cries*

C-Dawg
01-13-2007, 12:38 AM
Well, switch statements and arrays would help out alot. And more intelligent coding. I'm taking a pretty "brute force" approach here.

jman2050
01-13-2007, 03:58 PM
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.