Copy to Clipboard Test

Geldarm + Z2 Geldarm Code

const int GELDARM_FLASH_CSET = 5;//Flash CSet on damage. 0 - flicker.

//Geldarm - worm -like creature that lurks in one place in attempt to bite Link when he gets close enough.
ffc script FFGeldarm{
	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 dir = Ghost_GetAttribute(ghost, 0, 0);//Direction facing. -1 - following Link. Use right facing head for enemy tile.
		int proximity = Ghost_GetAttribute(ghost, 1, 32);//Proximity radius and monter length, in pixels.
		int speedon = Ghost_GetAttribute(ghost, 2, 3);//Attack speed, in 100th pixels per frame
		int speedoff = Ghost_GetAttribute(ghost, 3, 1);//Retraction speed, in 100th pixels per frame
		int segmenttile = Ghost_GetAttribute(ghost, 4, 0);//Combo used for rendering segments of mpnster.
		int roottile = Ghost_GetAttribute(ghost, 5, 0);//Combo used for rendering root of mpnster.
		int looseheadnpc = Ghost_GetAttribute(ghost, 6, -1);//NPC to spawn on death, -1 - no loose head spawning
		int numsegments = Ghost_GetAttribute(ghost, 7, 4);//Number of segments to render, including root tile
		int delay = Ghost_GetAttribute(ghost, 8, 60);//Delay between noticing Link and attacking, in frames
		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);
		
		int angle= 0;
		if (dir>=0)angle=DirAngle(dir);
		else angle = 0;
		int LinkYOffset = Cond(IsSideview(),0,8);
		int State = 0;
		int origx = Ghost_X;
		int origy = Ghost_Y;
		int shoottimer =0;	
		int shotangle = 0;
		int length=0;
		int neckposX=0;
		int neckposY=0;
		int flickercnt=0;
		Ghost_SpawnAnimationPuff(this, ghost);
		ghost->DrawXOffset=1000;
		int drawcset =Ghost_CSet;
		
		int defs[18];
		Ghost_StoreDefenses(ghost,defs);
		
		while(true){
			if (GELDARM_FLASH_CSET>0 &&(flickercnt%4)>1)drawcset = GELDARM_FLASH_CSET;
			else drawcset = Ghost_CSet;
			if (State==0){
				if (shoottimer==0){
					if (dir<0)angle = Angle(origx, origy, Link->X, Link->Y);
					if (Distance(CenterX(ghost), CenterY(ghost), CenterLinkX(),CenterLinkY())<=proximity){
						shoottimer=delay;
					}
				}
				else {
					shoottimer--;
					if (shoottimer==0){
						//if (dir<0)angle = Angle(origx, origy, Link->X, Link->Y);
						State=1;
					}
				}
			}
			else if (State==1){
				length+=speedon/100;
				Ghost_X=origx+length*Cos(angle);
				Ghost_Y=origy+length*Sin(angle);
				
				if (length>=proximity){
					if (dir<0)shotangle = RadianAngle(Ghost_X, Ghost_Y, Link->X, Link->Y);
					else shotangle = DirRad(dir);
					eweapon e = FireEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, shotangle, 200, WPND, ewsprite, -1, 0);
					shoottimer=delay;
					State=2;
				}
			}
			else if (State==2){
				if (shoottimer>0){
					shoottimer--;
				}
				else {
					length-=speedoff/100;
					Ghost_X=origx+length*Cos(angle);
					Ghost_Y=origy+length*Sin(angle);
					
					if (length<=0){
						Ghost_X = origx;
						Ghost_Y = origy;
						shoottimer=0;
						State=0;
					}
				}
			}
			if (State!=0){
				for (int i=0; i< numsegments; i++){
					neckposX = Lerp(origx, Ghost_X, (1/(numsegments))*i);
					neckposY = Lerp(origy, Ghost_Y, (1/(numsegments)*i));
					if (IsEven(flickercnt)||GELDARM_FLASH_CSET>0)Screen->DrawCombo(3, neckposX, neckposY, Cond(i==0, roottile, segmenttile), 1, 1,drawcset, -1, -1, neckposX, neckposY, angle, 0, 0,true, OP_OPAQUE);
					if (RectCollision(Link->X, Link->Y+LinkYOffset, Link->X+15, Link->Y+Cond(IsSideview(),16,8), neckposX+4, neckposY+4, neckposX+12, neckposY+12)){
						eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, ghost->Damage, -1, -1, EWF_UNBLOCKABLE);
						e->Dir = Link->Dir;
						e->DrawYOffset = -1000;
						SetEWeaponLifespan(e, EWL_TIMER, 1);
						SetEWeaponDeathEffect(e, EWD_VANISH, 0);
					}
				}
			}
			if ( Ghost_GotHit())flickercnt=45;
			if (flickercnt>0)flickercnt--;			
			// debugValue(1,angle);
			// debugValue(2,dir);
			if (IsEven(flickercnt)||GELDARM_FLASH_CSET>0)Screen->DrawTile(3, Ghost_X, Ghost_Y, ghost->Tile, 1, 1,drawcset, -1, -1,Ghost_X, Ghost_Y, angle, 0, true, OP_OPAQUE);
			if (!Ghost_Waitframe(this, ghost, false, false)){
				ghost->DrawXOffset=0;
				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();
			}
		}
	}	
}

const int Z2GELDARM_FLASH_CSET = 5;//Flash CSet on damage. 0 - flicker.

//Z2Geldarm - worm -like creature that lurks in one place in attempt to bite Link when he gets close enough. Attack root point when he is extended to damage it.
ffc script Z2Geldarm{
	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 dir = Ghost_GetAttribute(ghost, 0, 0);//Direction facing. -1 - following Link. Use right facing head for enemy tile.
		int proximity = Ghost_GetAttribute(ghost, 1, 32);//Proximity radius and monter length, in pixels.
		int speedon = Ghost_GetAttribute(ghost, 2, 3);//Attack speed, in 100th pixels per frame
		int speedoff = Ghost_GetAttribute(ghost, 3, 1);//Retraction speed, in 100th pixels per frame
		int segmenttile = Ghost_GetAttribute(ghost, 4, 0);//Combo used for rendering segments of mpnster.
		int roottile = Ghost_GetAttribute(ghost, 5, 0);//Combo used for rendering root of mpnster.
		int looseheadnpc = Ghost_GetAttribute(ghost, 6, -1);//NPC to spawn on death, -1 - no loose head spawning
		int numsegments = Ghost_GetAttribute(ghost, 7, 4);//Number of segments to render, including root tile
		int delay = Ghost_GetAttribute(ghost, 8, 60);//delay between noticing Link and attacking, in frames
		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);
		
		int angle= 0;
		if (dir>=0)angle=DirAngle(dir);
		else angle = 0;
		int LinkYOffset = Cond(IsSideview(),0,8);
		int State = 0;
		int origx = Ghost_X;
		int origy = Ghost_Y;
		int shoottimer =0;	
		int shotangle = 0;
		int length=0;
		int neckposX=0;
		int neckposY=0;
		Ghost_SpawnAnimationPuff(this, ghost);
		ghost->DrawXOffset=1000;
		int xpos = Ghost_X;
		int ypos = Ghost_Y;
		int flickercnt=0;
		int drawcset =Ghost_CSet;
		
		int defs[18];
		Ghost_StoreDefenses(ghost,defs);
		
		while(true){
			if (Z2GELDARM_FLASH_CSET>0 &&(flickercnt%4)>1)drawcset = GELDARM_FLASH_CSET;
			else drawcset = Ghost_CSet;
			if (State==0){
				if (shoottimer==0){
					if (dir<0)angle = Angle(origx, origy, Link->X, Link->Y);
					if (Distance(CenterX(ghost), CenterY(ghost), CenterLinkX(),CenterLinkY())<=proximity){
						shoottimer=delay;
					}
				}
				else {
					shoottimer--;
					if (shoottimer==0){
						//if (dir<0)angle = Angle(origx, origy, Link->X, Link->Y);
						State=1;
					}
				}
			}
			else if (State==1){
				length+=speedon/100;
				xpos=origx+length*Cos(angle);
				ypos=origy+length*Sin(angle);
				
				if (length>=proximity){
					if (dir<0)shotangle = RadianAngle(xpos, ypos, Link->X, Link->Y);
					else shotangle = DirRad(dir);
					eweapon e = FireEWeapon(ghost->Weapon, xpos, ypos, shotangle, 200, WPND, ewsprite, -1, 0);
					shoottimer=delay;
					State=2;
				}
			}
			else if (State==2){
				if (shoottimer>0){
					shoottimer--;
				}
				else {
					length-=speedoff/100;
					xpos=origx+length*Cos(angle);
					ypos=origy+length*Sin(angle);
					
					if (length<=0){
						xpos = origx;
						ypos = origy;
						shoottimer=0;
						State=0;
					}
				}
			}
			if (State!=0){
				for (int i=0; i< numsegments; i++){
					neckposX = Lerp(origx, xpos, (1/(numsegments))*i);
					neckposY = Lerp(origy, ypos, (1/(numsegments)*i));
					if (IsEven(flickercnt)||Z2GELDARM_FLASH_CSET>0)Screen->DrawCombo(3, neckposX, neckposY, Cond(i==0, roottile, segmenttile), 1, 1, drawcset, -1, -1, neckposX, neckposY, angle, 0, 0,true, OP_OPAQUE);
					if (RectCollision(Link->X, Link->Y+LinkYOffset, Link->X+15, Link->Y+Cond(IsSideview(),16,8), neckposX+4, neckposY+4, neckposX+12, neckposY+12)){
						eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, ghost->Damage, -1, -1, EWF_UNBLOCKABLE);
						e->Dir = Link->Dir;
						e->DrawYOffset = -1000;
						SetEWeaponLifespan(e, EWL_TIMER, 1);
						SetEWeaponDeathEffect(e, EWD_VANISH, 0);
					}
				}
			}
			// debugValue(1,angle);
			// debugValue(2,dir);
			if ( Ghost_GotHit())flickercnt=45;
			if (flickercnt>0)flickercnt--;			
			if (IsEven(flickercnt)||Z2GELDARM_FLASH_CSET>0)Screen->DrawTile(3, xpos, ypos, ghost->Tile, 1, 1,drawcset, -1, -1,xpos, ypos, angle, 0, true, OP_OPAQUE);
			if (RectCollision(Link->X, Link->Y+LinkYOffset, Link->X+15, Link->Y+Cond(IsSideview(),16,8), xpos+1, ypos+1, xpos+13, ypos+13)){
						eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, ghost->Damage, -1, -1, EWF_UNBLOCKABLE);
						e->Dir = Link->Dir;
						e->DrawYOffset = -1000;
						SetEWeaponLifespan(e, EWL_TIMER, 1);
						SetEWeaponDeathEffect(e, EWD_VANISH, 0);
					}
			if (!Ghost_Waitframe(this, ghost, false, false)){
				ghost->DrawXOffset=0;
				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();
			}
		}
	}	
}