Copy to Clipboard Test

Manhandla EX Code

//FFManhandla
//Extended variant of Z1 Manhandla with more customizability. Moves and fires like a normal 4, or 8 headed boss.
//Uses 2 enemy slots, 1 for core, 1 or head. If core is killed first, all heads are gone instantly and vice versa.
ffc script FFManhandla{
	void run(int enemyID){
		npc ghost = Ghost_InitAutoGhost(this, enemyID);
		int HF = ghost->Homing;
		int HR = ghost->Haltrate;
		int RR = ghost->Rate;
		int HNG = ghost->Hunger;
		int SPD = ghost->Step;
		int WPND = ghost->WeaponDamage;		
		int weaponID = ghost->Weapon;
		
		// Initialize
		ghost->Extend=3;
		Ghost_SetFlag(GHF_NO_FALL);
		Ghost_SetFlag(GHF_NORMAL);
		Ghost_SetFlag(GHF_8WAY);
		Ghost_UnsetFlag(GHF_KNOCKBACK);
		
		int firerate = Ghost_GetAttribute(ghost, 0, 60);//Delay batween firing EWeapons, in frames.
		int size = Ghost_GetAttribute(ghost, 1, 1);//Enemy size and number of heads, 1 - 1x1(4 heads), 2- 2x2(8 heads), 3 -3x3(12 heads), 4 - 4x4(16 heads)
		int speedinc = Ghost_GetAttribute(ghost, 2, 8);//Speed increase modifier with each head killed, stacked additively
		int headID = Ghost_GetAttribute(ghost, 3, enemyID+1);//Enemy ID for heads, uses next ID in list by default, must use "Other" enemy type
		int WPNS = Ghost_GetAttribute(ghost, 4, -1);//Sprite used by fired EWeapons.
		
		ghost->Extend=3;
		Ghost_SetSize(this, ghost, size, size);
		
		Ghost_SpawnAnimationPuff(this, ghost);
		int OrigTile = ghost->OriginalTile;
		int state = 0;
		int statecounter=firerate;
		if (size>4)size=4;
		int haltcounter=0;
		int speedmod = 0;
		
		//Spawn heads
		int numheads = size*4;
		npc heads[16];
		int offsetX[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		int offsetY[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		int dirs[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		int offsetX1[16] = {0, -16,16,0,0,0,0,0,0,0,0,0,0,0,0,0};
		int	offsetY1[16] = {-16, 0,0,16,0,0,0,0,0,0,0,0,0,0,0,0};
		int dirs1[16] = {0,2,3,1,0,0,0,0,0,0,0,0,0,0,0,0};
		int dirs2[16] = {0,0,2,3,2,3,1,1,0,0,0,0,0,0,0,0};
		int offsetX2[16] = {0, 16,-16,32,-16,32,0,16,0,0,0,0,0,0,0,0};
		int offsetY2[16] = {-16, -16,0,0,16,16,32,32,0,0,0,0,0,0,0,0};
		int dirs3[16] = {0,0,0,2,3,2,3,2,3,1,1,1,0,0,0,0};
		int offsetX3[16] = {0, 16,32,-16,48,-16,48,-16,48,0,16,32,0,0,0,0};
		int offsetY3[16] = {-16, -16,-16,0,0,16,16,32,32,48,48,48,0,0,0,0};
		int dirs4[16] = {0,0,0,0,2,3,2,3,2,3,2,3,1,1,1,1};
		int offsetX4[16] = {0, 16,32,48,-16,64,-16,64,-16,64,-16,64,0,16,32,48};
		int offsetY4[16] = {-16, -16,-16,-16,0,0,16,16,32,32,48,48,64,64,64,64};
		for (int i=0; i<numheads; i++){
			heads[i]=SpawnNPC(headID);
			if (size==4){
				offsetX[i]=offsetX4[i];
				offsetY[i]=offsetY4[i];
				dirs[i]=dirs4[i];
			}
			else if (size==3){
				offsetX[i]=offsetX3[i];
				offsetY[i]=offsetY3[i];
				dirs[i]=dirs3[i];
			}
			else if (size==2){
				offsetX[i]=offsetX2[i];
				offsetY[i]=offsetY2[i];
				dirs[i]=dirs2[i];
			}
			else{
				offsetX[i]=offsetX1[i];
				offsetY[i]=offsetY1[i];
				dirs[i]=dirs1[i];
			}
			SetEnemyProperty(heads[i], ENPROP_X, Ghost_X+offsetX[i]);
			SetEnemyProperty(heads[i], ENPROP_Y, Ghost_Y+offsetY[i]);
			SetEnemyProperty(heads[i], ENPROP_DIR, dirs[i]);
			SetEnemyProperty(heads[i], ENPROP_CSET, Ghost_CSet);
		}
		Ghost_Waitframe(this, ghost);
		Ghost_Waitframe(this, ghost);
		Ghost_Waitframe(this, ghost);
		Ghost_Waitframe(this, ghost);
		while(true)	{
			speedmod=0;
			for (int i=0; i<numheads; i++){
				if (heads[i]->isValid()){
					SetEnemyProperty(heads[i], ENPROP_X, Ghost_X+offsetX[i]);
					SetEnemyProperty(heads[i], ENPROP_Y, Ghost_Y+offsetY[i]);
					SetEnemyProperty(heads[i], ENPROP_DIR, dirs[i]);
				}
				else speedmod+=speedinc;
				if (speedmod==(numheads*speedinc)) Ghost_HP=0;
			}
			haltcounter = Ghost_VariableWalk8(haltcounter, SPD+speedmod, RR, HF, HNG, 15);
			statecounter--;
			if (statecounter==0){
				eweapon e;
				for (int i=0; i<numheads; i++){
					if (!heads[i]->isValid()) continue;
					if (WPND==0)continue;
					if (weaponID==EW_FIREBALL) e = FireAimedEWeapon(weaponID,heads[i]->X , heads[i]->Y, 0, 150, WPND, WPNS, -1, EWF_ROTATE);
					else e = FireNonAngularEWeapon (weaponID, heads[i]->X , heads[i]->Y, dirs[i], 200, WPND, WPNS, -1, EWF_ROTATE);
				}
				statecounter=firerate;
			}
			if (!Ghost_Waitframe(this, ghost, false, false)){
				for (int i=0; i<numheads; i++){
					if (heads[i]->isValid())SetEnemyProperty(heads[i], ENPROP_HP, 0);
				}
				Ghost_DeathAnimation(this, ghost, GHD_EXPLODE);
				Quit();
			}		
		}
	}
}