const int GLOBAL_TRIB_FFC_ const int GLOBAL_TRIB_NPC_MISC_TIMER = 3; const int GLOBAL_TRIB_NPC_MISC_FLAG = 7; const int GLOBAL_TRIB_NPC_MISC_IDS = 8; //Low value is the enemy it will split into, high is the enemy it will tribble into. int GetTribbleID(npc n){ return (n->Misc[GLOBAL_TRIB_NPC_MISC_IDS] << 0); } int GetSplitID(npc n){ return (n->Misc[GLOBAL_TRIB_NPC_MISC_IDS] - (n->Misc[GLOBAL_TRIB_NPC_MISC_IDS] >> 0)) * 10000; } bool IsTribble(npc n) { if ( n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] % 4 == 0 ) return true; } bool IsSplitOnDeath(npc n) { return (n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] == 1); } bool IsSplitOnHit(npc n) { return ( n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] == 2); } void IsSplitOnHit(npc n) { n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] = 2; } void IsSplitOnDeath(npc n) { n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] = 1; } void IsTribble(npc n) { n->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] = 4; } const int NPC_SPLIT_DEATH = 1; const int NPC_SPLIT_HIT = 2; const int NPC_TRIBBLES_INTO = 4; const int NPC_TRIBBLES_BECOME = 8; ffc script SplitAndTribble{ void run(int enemy_id, int splits_into, int number_of_splits, int tribbles_into, int tribbles_become, int split_sfx, int gleeok_override, ffc f){ npc n[256]; npc npointers[256]; int a[256]; int npcflags[256]; /// Check if any of the enemies on the screen have flags that they tribble, or split. for ( a[SPLTR_q] = 0; a[SPLTR_q] <= Screen->NumNPCs(); a[SPLTR_q]++ ) { n[0] = Screen->LoadNPC[a[SPLTR_q]]; //Load the npc if ( n[0]->isValid() ) { //if it is a valid pointer if ( n[0]->Misc[GLOBAL_TRIB_NPC_MISC_FLAG] != 0 ) { //If so, store its pointer in the npointers[] array npointers[a[SPLTR_q]] = n[0]; //If it has a flag marked, find out what kind of flag it is. if ( IsSplitOnDeath(n[0]) && !IsSplitOnHit(n[0]) && !IsTribble(n[0]) ) { //if it splits on death //Check its HP and see if we shuld split it. if ( n[0]->HP < 1 && n[0]->HP > -9999 && n[0]->X != -32768 && n[0]->Y != -32768 ) { a[SPLTR_X] = n[0]->X; //Store its position, so that we know where to spawn its splits. a[SPLTR_Y] = n[0]->Y; n[0]->HitXOffset = -200; //Hide the source enemy. n[0]->HitYOffset = -200; n[0]->DrawXOffset = -200; n[0]->DrawYOffset = -200; n[0]->HP = -9999; //Kill the original enemy. Remove(n[0]); Waitframes(1); //Replace it with the number of splits for ( a[SPLTR_W] = 0; a[SPLTR_W] < number_of_splits; a[SPLTR_W]++ ) { n[SPLTR_ENEM_REPL] = Screen->CreateNPC(splits_into); if ( gleeok_override && n[SPLTR_ENEM_REPL]->Type == NPCT_GLEEOK ) { //Force it to spawn where Gleeoks belong. n[SPLTR_ENEM_REPL]->X = GLEEOK_SPAWN_X; n[SPLTR_ENEM_REPL]->Y = GLEEOK_SPAWN_Y; } else { n[SPLTR_ENEM_REPL]->X = Clamp(a[SPLTR_X]+Rand( (dist_flux * -1), dist_flux), 0, MAX_SPAWN_NPX_X), n[SPLTR_ENEM_REPL]->Y = Clamp(a[SPLTR_Y]+Rand( (dist_flux * -1), dist_flux), 0, MAX_SPAWN_NPC_Y) ); } if ( split_sfx ) Game->PlaySound(split_sfx); //if ( Game->GuyCount[Game->GetCurScreen()] < 10 ) Game->GuyCount[Game->GetCurScreen()]++; } } //if it splits on hit... if ( !IsSplitOnDeath(n[0]) && IsSplitOnHit(n[0]) && !IsTribble(n[0]) ) { //if it splits on death //if it isn't dying, or we don't care... if ( !DYING_ENEMY_NO_SPLIT || ( DYING_ENEMY_NO_SPLIT && n[0]->HP > 0 ) ) { //See if it's been hit... //Read lweapons, check collision, and see if the weapon is blocked for ( a[SPLTR_W] = 1; a[SPLTR_W] <= Screen->NumLWeapons(); a[SPLTR_W]++ ) { //Read the lweapons on the screen, loadfing them lweapon l = Screen->LoadLWeapon(a[SPLTR_W]); if ( l->isValid() ) { //If it's valid if ( Collision(l,n[0]) && l->CollDetection ) { //Remove(l); //Kill the lweapon. l->CollDetection = false; //Stop it from colliding constantl;y. //Check for collision with that weapon and the enemy //Check if any of the defs block this weapon. if ( n[0]->Defense[ LWeaponToNPCD(l->ID) ] < 3 ) { //Can be damaged by the weapon a[SPLTR_X] = n[0]->X; //Store its position, so that we know where to spawn its splits. a[SPLTR_Y] = n[0]->Y; n[0]->HitXOffset = -200; //Hide the source enemy. n[0]->HitYOffset = -200; n[0]->DrawXOffset = -200; n[0]->DrawYOffset = -200; n[0]->HP = -9999; //Kill the original enemy. Remove(n[0]); while(n[0]->isValid()) Waitframe(); //Wait for it to die, so that we don;t spawn extra enemies... //The spawn the splits. for ( a[SPLTR_E] = 0; a[SPLTR_E] < number_of_splits; a[SPLTR_E]++ ) { n[1] = Screen->CreateNPC(splits_into); if ( gleeok_override && n[1]->Type == NPCT_GLEEOK ) { //Force it to spawn where Gleeoks belong. n[1]->X = GLEEOK_SPAWN_X; n[1]->Y = GLEEOK_SPAWN_Y; } else { n[1]->X = Clamp(a[SPLTR_X]+Rand( (dist_flux * -1), dist_flux), 0, MAX_SPAWN_NPX_X), n[1]->Y = Clamp(a[SPLTR_Y]+Rand( (dist_flux * -1), dist_flux), 0, MAX_SPAWN_NPC_Y) ); } //if ( Game->GuyCount[Game->GetCurScreen()] < 10 ) Game->GuyCount[Game->GetCurScreen()]++; if ( split_sfx ) Game->PlaySound(split_sfx); } } } } //If they do, read the enemy they will become. //Store what they are turning into. //Store their coordinates. //If splitting, split now. //If they are marked as tribbling up, read their timers. //If their timer is not zero, decrement it. //if their timer is zero, tribble them. } }