////////////////////////////////////// /// Splitting Enemies /// /// v0.5 /// /// 18th June, 2016 /// /// By: ZoriaRPG /// //////////////////////////////////////////////////////////////////////////////////////// /// D0: Source Enemy ID /// /// D1: ID of enemy to split into. /// /// D2: Number of splits. i.e. On death, enemy D0 will split into D2 number of D1. /// /// D3: A randomising factor for spawning the splits. Suggested value range: 2 to 5. /// /// /// /// Requested by Cukeman on PureZC.net /// //////////////////////////////////////////////////////////////////////////////////////// //SplitOnDeath ffc a[] const int SPLTR_Q = 0; const int SPLTR_W = 2; const int SPLTR_X = 3; const int SPLTR_Y = 3; ffc script SplitOnDeath { void run(int enem_id, int splits_into, int number_of_splits, int dist_flux ){ npc n; int a[4]; Waitframes(5); //Enemies require five frames, to spawn. // If a 'No Return' flag is set, and there are no enemies on the screen, // cleanly exit the script and make the ffc slot available. if ( ( Screen->State[ST_ENEMYNORETURN] || Screen->State[ST_TEMPNORETURN] ) && !Screen->NumNPCs() ){ this->Data = 0; this->Script = 0; Quit(); } while(true){ for ( a[SPLTR_Q] = 1; a[SPLTR_Q] <= Screen->NumNPCs(); a[SPLTR_Q]++ ) { n = Screen->LoadNPC(a[TRIB_Q]); if ( n->IsValid() ) { // If it's dying, not removed, and the correct enemy ID... if ( n->ID == enem_id && n->HP < 1 && n->X != -32768 && n->Y != -32768 ) { for ( a[SPLTR_W] = 0; a[SPLTR_W] < number_of_splits; a[SPLTR_W]++ ) { a[SPLTR_X] = n->X; //Store its position, so that we know where to spawn its splits. a[SPLTR_Y] = n->Y; n = Screen->CreateNPC(splits_into); //Reuse our pointer, instead of wasting one. n->X = a[SPLTR_X]+Rand( (dist_flux * -1), dist_flux); n->Y = a[SPLTR_Y]+Rand( (dist_flux * -1), dist_flux); n = Screen->LoadNPC(a[TRIB_Q]); //Reset the pointer for the next iteration. } } } } if ( ( Screen->State[ST_ENEMYNORETURN] || Screen->State[ST_TEMPNORETURN] ) && !Screen->NumNPCs() ) { this->Data = 0; this->Script = 0; Quit(); // Free up the slot if we're done. } Waitframe(); } } } ////////////////////////////////////// /// Splitting Enemies /// /// v0.5 /// /// 18th June, 2016 /// /// By: ZoriaRPG /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// D0: The enemy ID of the base enemy that will split when killed. /// /// D1: The enemy that the main enemy becomes, when killed. /// /// D2: The number of enemies the main enemy splits into. /// /// D4: The ID of the enemy that D1 becomes when it 'tribbles up'. Set to '0' to use the main enemy (e.g. zols). /// /// D5: The ransomised distance to spawn the split-offs into. Suggested value range: 2 to 5. /// /// D6: The timer, for the split-offs, in frames. Thus, '240' would be 5 seconds. /// /// -> When enemy D0 dies, it splits into D2 quantity of enemy D1 at a distance of D0->X and D0->Y +/- D5 pixels. /// /// -> Then, when the duration defined in D6 expires (it is set as a separate timer, on a per-enemy basis), /// /// -> D1 will transform into D4, unless D4 is not set to a positive value, in which case, it transforms into D0. /// /// /// /// Requested by: idontknow8 on PureZC.net /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Splitter FFC a[] const int TRIB_BASE = 0; const int TRIB_INTO = 1; const int TRIB_LAST = 2; const int TRIB_TIME = 3; // Splitter FFC n[] const int TRIB_Q = 0; const int TRIB_W = 1; const int TRIB_E = 2; const int TRIB_X = 4; const int TRIB_Y = 5; ffc script BasicTribble{ void run(int base_enemy, int tribbles_into, int num_tribbles, int tribbles_become, int waver, int trib_time){ int a[6]; //a vars array, for loops and stats npc n[2]; //an npc array Waitframes(5); //Wait for npcsto spawn. if ( ( Screen->State[ST_ENEMYNORETURN] || Screen->State[ST_TEMPNORETURN] ) && !Screen->NumNPCs() ) { this->Data = 0; this->Script = 0; Quit(); } while(true){ //handle making the main enemy split. for ( a[TRIB_Q] = 1; a[TRIB_Q] <= Screen->NumNPCs(); a[TRIB_Q]++ ) { n[TRIB_BASE] = Screen->LoadNPC(a[TRIB_Q]); //Parse each npc onthe screen if ( n[TRIB_BASE]->Isvalid() { if ( n[TRIB_BASE]->HP <= 0 && n[TRIB_BASE]->ID == base_enemy && n[TRIB_BASE]->X != -32768 && n[TRIB_BASE]->Y != -32768){ n[TRIB_BASE]->DrawXOffset = -200; n[TRIB_BASE]->DrawYOffset = -200; n[TRIB_BASE]->HitXOffset = -200; n[TRIB_BASE]->HitYOffset = -200; a[TRIB_X] = n[TRIB_BASE]->X; a[TRIB_Y] = n[TRIB_BASE]->Y; a[TRIB_BASE]->HP = -9999; //Waitframes(15); //A delay to make the spawning feel less insant. n[TRIB_INTO] = CreateNPCAt(tribbles_into, a[TRIB_X] + Rand( (waver * -1), waver ), a[TRIB_Y] + Rand( (waver * -1), waver )); //make the new enemies. n[TRIB_INTO]->Misc[TRIB_TIME] = trib_time; } } } //Handle making the splits of the main enemy tribble up. if ( tribbles_become <= 0 ) tribbles_become = base_enemy; //Split-off enemies will turn into the main enemy, unless D3 is set. for ( a[TRIB_Q] = 1; a[TRIB_Q] <= Screen->NumNPCs(); a[TRIB_Q]++ ) { //Count down the individual enemy timers. n[TRIB_BASE] = Screen->LoadNPC(a[TRIB_Q]; //Load the enemy. if ( n[TRIB_BASE]->IsValid()){ //Verify that it is valid... if ( n[TRIB_BASE]->Misc[TRIB_TIME] > 0 ) n[TRIB_BASE]->Misc[TRIB_TIME]--; //If the timer is positive, decrement it. if ( n[TRIB_BASE]->Misc[TRIB_TIME] <= 0 ) { //if the timer for a specific enemy has run out...transform it. n[TRIB_BASE]->DrawXOffset = -200; //Hide the main enemy. n[TRIB_BASE]->DrawYOffset = -200; n[TRIB_BASE]->HitXOffset = -200; n[TRIB_BASE]->HitYOffset = -200; a[TRIB_X] = n[TRIB_BASE]->X; a[TRIB_Y] = n[TRIB_BASE]->Y; n[TRIB_BASE]->HP = -9999; //...the spawn its replacement. n[TRIB_INTO] = CreateNPCAt(tribbles_become, a[TRIB_X], a[TRIB_Y]); } } } if ( ( Screen->State[ST_ENEMYNORETURN] || Screen->State[ST_TEMPNORETURN] ) && !Screen->NumNPCs() ) { this->Data = 0; this->Script = 0; Quit(); } Waitframe(); } } }