Copy to Clipboard Test

FF Gleeok Code

const int FFGLEEOK_FIRE_RATE = 4;//Fire Gleeok`s fire rate
const int NPC_MISC_GLEEOK_HEAD_OFFSET_X = 13;
const int NPC_MISC_GLEEOK_HEAD_OFFSET_Y = 14;

//Extended variant of Z1 Gleeok. Can have more customizability, like killable loose heads, different eweapons for intact and loose heads, unhardcoded position. Moving Gleeok also works.
//Uses 3 enemies. 
//Each head is separate NPC. Slice all heads off body to kill Gleeok, as usual.

ffc script FFGleeokBody{
	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 numheads = Ghost_GetAttribute(ghost, 0, 2);//Number of heads. Max 16
		int HeadNPC = Ghost_GetAttribute(ghost, 1, enemyID+1);//ID of head enemy.
		int necksegmentcount = Ghost_GetAttribute(ghost, 2, 4); //Number of neck segments per head
		int NeckSegmentCmb = Ghost_GetAttribute(ghost, 3, 1);//Combo used to render neck segment
		int looseheadnpc = Ghost_GetAttribute(ghost, 4, enemyID+2);//ID of loose head NPC to remove, when Gleeok is killed, -1 to disable
		int headinitXOffset = Ghost_GetAttribute(ghost, 5, 8);//Spawning X offset for heads.
		int headinitYOffset = Ghost_GetAttribute(ghost, 6, 40);//Spawning Y offset for heads.
		int neckoffsetX = Ghost_GetAttribute(ghost, 7, 0);//X position of connection between necks and body.
		int neckoffsetY = Ghost_GetAttribute(ghost, 8, 0);//Y position of connection between necks and body.
		int ewsize = Ghost_GetAttribute(ghost, 9, 2);//Body size (square)
		
		ghost->Extend=3;
		Ghost_SetSize(this, ghost, ewsize, ewsize);
		if (ewsize>2)Ghost_SetHitOffsets(ghost, 8, 8, 8, 8);
		
		if (ghost->Damage==0) ghost->CollDetection=false;
		
		Ghost_SetFlag(GHF_NORMAL);
		Ghost_UnsetFlag(GHF_KNOCKBACK);
		
		int curheads = 0;
		int State = 0;
		int neckposX=0;
		int neckposY=0;
		npc curhead;
		npc heads[16];
		for (int i=0;i<numheads;i++){
			heads[i] = CreateNPCAt(HeadNPC, Ghost_X+headinitXOffset,Ghost_Y+headinitYOffset);
		}
		int haltcounter=-1;
		
		Ghost_SpawnAnimationPuff(this, ghost);
		
		while(true){
			if (State==0){
				if (SPD>0)haltcounter = Ghost_ConstantWalk4(haltcounter, SPD, RR, HF, HNG);
				curheads=0;
				for (int i=0; i<numheads; i++){
					if (!(heads[i]->isValid())) continue;
					curhead = heads[i];
					for (int i=0; i< necksegmentcount; i++){
						neckposX = Lerp(Ghost_X+neckoffsetX, GetEnemyProperty(curhead, ENPROP_X), (1/(necksegmentcount))*i);
						neckposY = Lerp(Ghost_Y+neckoffsetY, GetEnemyProperty(curhead, ENPROP_Y), (1/(necksegmentcount)*i));
						Screen->FastCombo(3, neckposX, neckposY, NeckSegmentCmb, Ghost_CSet, OP_OPAQUE);
					}
					curhead->Misc[NPC_MISC_GLEEOK_HEAD_OFFSET_X] = Ghost_X + headinitXOffset;
					curhead->Misc[NPC_MISC_GLEEOK_HEAD_OFFSET_Y] = Ghost_Y + headinitYOffset;
					curheads++;
				}
			}
			if (!Ghost_Waitframe(this, ghost, false, false)||curheads==0){
				ghost->CollDetection=false;
				for (int i=1; i<=Screen->NumNPCs();i++){
					if (looseheadnpc<0)continue;
					curhead = Screen->LoadNPC(i);
					if (curhead->ID!=looseheadnpc) continue;
					SetEnemyProperty(curhead, ENPROP_HP, 0);
				}
				for (int i=0; i<16; i++){
					if (!heads[i]->isValid()) continue;
					curhead = heads[i];
					SetEnemyProperty(curhead, ENPROP_HP, 0);
				}
				if (ewsize>1)Ghost_DeathAnimation(this, ghost, GHD_EXPLODE);
				ghost->HP=0;
				Quit();
			}
		}
	}	
}

ffc script FFGleeokHead{
	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 rangex = Ghost_GetAttribute(ghost, 0, 24);//Maximum range at X coordinate
		int rangey = Ghost_GetAttribute(ghost, 1, 16);//Maximum range at Y coordinate
		int speedx = Ghost_GetAttribute(ghost, 2, 1);//Angular speed for X coordinate, in 1/100th of degree per frame.
		int speedy = Ghost_GetAttribute(ghost, 3, 2);//Angular speed for Y coordinate, in 1/100th of degree per frame.
		int initanglex = Ghost_GetAttribute(ghost, 4, 0);//Starting angle for X coordinate
		int initangley = Ghost_GetAttribute(ghost, 5, 0);//Starting angle for Y coordinate
		int looseheadnpc = Ghost_GetAttribute(ghost, 6, enemyID+1);//NPC to spawn on death, -1 - no loose head spawning
		int firenum = Ghost_GetAttribute(ghost, 7, 1);//Number of eweapons to fire per burst
		int shotspeed = Ghost_GetAttribute(ghost, 8, 60);//delay between shots, in frames. Enemy won`t fire , if Weapon Damage is 0.
		int ewsprite = Ghost_GetAttribute(ghost, 9, -1);//Eweapon sprite 
		
		
		
		Ghost_SetFlag(GHF_NORMAL);
		Ghost_SetFlag(GHF_IGNORE_WATER);
		Ghost_SetFlag(GHF_IGNORE_PITS);
		Ghost_SetFlag(GHF_FLYING_ENEMY);
		Ghost_SetFlag(GHF_NO_FALL);
		Ghost_SetFlag(GHF_MOVE_OFFSCREEN);
		Ghost_UnsetFlag(GHF_KNOCKBACK);
		
		if (speedx >=1000) speedx= -320+Rand(640);
		if (speedy >=1000) speedy= -320+Rand(640);
		if (initanglex>360) initanglex =Rand(359);
		if (initangley>360) initangley =Rand(359);
		
		int State = 0;
		int origx = Ghost_X;
		int origy = Ghost_Y;
		int anglex = initanglex;
		int angley = initangley;
		int shotcounter=shotspeed;
		int shoottimer =0;		
		
		int defs[18];
		Ghost_StoreDefenses(ghost,defs);
		Ghost_SpawnAnimationPuff(this, ghost);
		while(true){
			if (State==0){
				origx = ghost->Misc[NPC_MISC_GLEEOK_HEAD_OFFSET_X];
				origy = ghost->Misc[NPC_MISC_GLEEOK_HEAD_OFFSET_Y];
				anglex+=speedx/100;
				angley+=speedy/100;
				if (anglex>=360) anglex-=360;
				if (angley>=360) angley-=360;
				if (anglex<0)anglex+=360;
				if (angley<0)angley+=360;
				Ghost_X = origx + rangex*Cos(anglex);
				Ghost_Y = origy + rangey*Sin(angley);
				shotcounter--;
				if (shotcounter==0 && WPND>0){
					shoottimer = FFGLEEOK_FIRE_RATE*firenum;
					shotcounter=shotspeed;
				}
				if (shoottimer>0){
					if ((shoottimer%FFGLEEOK_FIRE_RATE)==0){
						eweapon e = FireAimedEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, 0, 200, WPND, ewsprite, -1, 0);
					}
					shoottimer--;
				}
			}
			// Screen->FastTile(3, Ghost_X, Ghost_Y, ghost->Tile, Ghost_CSet, OP_OPAQUE);
			if (!Ghost_Waitframe(this, ghost, false, false)){
				for (int i=1;i<=Screen->NumNPCs();i++){
					if (looseheadnpc<0)continue;
					npc n=Screen->LoadNPC(i);
					if (n->ID!=enemyID) continue;
					if (n->HP==0)continue;
					npc e = CreateNPCAt(looseheadnpc, Ghost_X,Ghost_Y);
					break;
				}
				Quit();
			}
		}
	}	
}		

ffc script FFGleeokLooseHead{
	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 firenum = Ghost_GetAttribute(ghost, 0, 1);//Number of eweapons to fire per burst
		int shotspeed = Ghost_GetAttribute(ghost, 1, 60);//delay between shots, in frames. Enemy won`t fire , if Weapon Damage is 0.
		int ewsprite = Ghost_GetAttribute(ghost, 2, -1);//Eweapon sprite
		
		
		
		Ghost_SetFlag(GHF_NORMAL);
		Ghost_SetFlag(GHF_IGNORE_WATER);
		Ghost_SetFlag(GHF_IGNORE_PITS);
		Ghost_SetFlag(GHF_NO_FALL);
		Ghost_SetFlag(GHF_8WAY);
		Ghost_UnsetFlag(GHF_KNOCKBACK);
		Ghost_SetFlag(GHF_FLYING_ENEMY);
		
		int State = 0;
		int shotcounter=shotspeed;
		int shoottimer =0;
		int haltcounter = -1;
		
		int defs[18];
		Ghost_StoreDefenses(ghost,defs);
		
		while(true){
			if (State==0){
				haltcounter = Ghost_ConstantWalk8(haltcounter, SPD, RR, HF, HNG);
				shotcounter--;
				if (shotcounter==0 && WPND>0){
					shoottimer = FFGLEEOK_FIRE_RATE*firenum;
					shotcounter=shotspeed;
				}
				if (shoottimer>0){
					if ((shoottimer%FFGLEEOK_FIRE_RATE)==0){
						eweapon e = FireAimedEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, 0, 200, WPND, ewsprite, -1, 0);
					}
					shoottimer--;
				}
			}
			if (!Ghost_Waitframe(this, ghost, false, false)){
				Quit();
			}
		}
	}	
}