Copy to Clipboard Test

Blob of Blood Code

const int BOSS_SLIME_WALL_STATE_TELEPORTING_IN = 1;
const int BOSS_SLIME_WALL_STATE_TELEPORTING_OUT = 4;
const int BOSS_SLIME_WALL_STATE_CHARGING = 2;
const int BOSS_SLIME_WALL_STATE_FIRED = 3;
const int BOSS_SLIME_WALL_STATE_NOT_IN_PLANE = 0;

const int SFX_BOSS_SLIME_WALL_NUKE = 37;//Sound to play, when SlimeWall casts nuclear flash spell.

const int BOSS_SLIME_WALL_NUKE_FLASH_COLOR = 1;//Color used for nuke flash

const int CF_CHANGEABLE_COMBO = 98;//Combo Flag to define combos that can be changed.

//Eye for Slime wall boss. A huge wall of red stuff that is really painful to touch. An eye teleports inside blob mass, firing eweapons at Link, spawning enemies. 
//When eye`s HP is low enough, the blob expands ala Demon Wall in attewmpt to fill screen completely. killing eye destroys entire Slime Wall and all summons.
//1. Compile the script. 2 FFC slots used.
//2. Set up BossSlimeWall ghosted enemy script for eye itself
////Animation - 4 sequences of frames set vertically: teleporting in, charging, firing, teleporting out.
////Attribute 1: Delay between teleporting
////Attribute 2: Enemy size, X*X square.
////Attribute 3: Attack type, add together: +1- 4 shots orthogonally, +2 - 8 shots in orthogonal and diagonal directions, +4 - summon enemies, +8 - nukes the whole screen for damage anywhere!
////Attribute 4: Eweapon sprite
////Attribute 5: Enemy count for enemy spawning attack
////Attribute 6: Berserk HP threshold
////Attribute 7: Delay between teleporting, if boss went berserk
////Attribute 8: Enemy ID for enemy spawning attack
//3. Set up 3 consecutive combos: 1 for edge of slime wall, then damaging slime innards then another slime innards combo with inherent flag #97 2nd combo must cycle into 3rd combo.
//4. Screen: place FFC with SlimeWallBody script where slime wall edge will be. And put 1 eye enemy.
//D0 - slot used by eye enemy.
//D1 - Slime wall facing direction, floor that on opposite direction must be filled with 3rd combo from step 3 (all combos above FFC, if D1 is DIR_DOWN etc.), while the rest of arena must have NO_FLYING_ENEMIES combo type to avoid eye spawning outside blob wall.
//D2 - When The Blob goes berserk once, he starts moving st that speed.
//D3 - HP threshold for blob expanding
//D4 - When HP falls below that threshold, blob expanding speed increases
//D5 - Blob expanding speed MULTIPLIER when eye HP is below D4

ffc script BossSlimeWall{
	void run(int enemyID){
		npc ghost = Ghost_InitAutoGhost(this, enemyID);
		
		int MinLinkDistance = 128 - (ghost->Homing)/2;//Minimum distance to Link when teleporting 256 - can telefrag Link.
		int WPND = ghost->WeaponDamage;//Eweapon damage
		
		int Teledelay = Ghost_GetAttribute(ghost, 0, 120);//Delay between teleporting
		int EwSize = Ghost_GetAttribute(ghost, 1, 1);//Enemy size, X*X square.
		int Wpn = Ghost_GetAttribute(ghost, 2, 15);//Attack type, add together: +1- 4 shots orthogonally, +2 - 8 shots in orthogonal and diagonal directions, +4 - summon enemies, +8 - nukes the whole screen for damage anywhere!
		int ewsprite = Ghost_GetAttribute(ghost, 3, -1);//Eweapon sprite
		int Encount = Ghost_GetAttribute(ghost, 4, 4);//Enemy count for enemy spawning attack		
		int berserkHP = Ghost_GetAttribute(ghost, 5, 4);//Berserk HP threshold
		int berserkDelay = Ghost_GetAttribute(ghost, 6, 60);//Delay between teleporting, if boss went berserk
		int EnID = Ghost_GetAttribute(ghost, 7, 167);//Enemy ID for enemy spawning attack
		int numcmbchange = Ghost_GetAttribute(ghost, 8, 5);//Unused
		int changecmb = Ghost_GetAttribute(ghost, 9, 0);//Unused
		
		int cmbs[176];
		for (int i=0;i<176;i++){
			if (ComboFI(i,CF_CHANGEABLE_COMBO))cmbs[i]=i;
			else cmbs[i]=-1;
		}
		int curcmb=0;
		int temp=0;
		
		ghost->Extend=3;
		Ghost_SetSize(this, ghost, EwSize, EwSize);
		if (EwSize>2)Ghost_SetHitOffsets(ghost, 8, 8, 8, 8);
		
		Ghost_SetFlag(GHF_NORMAL);
		Ghost_SetFlag(GHF_NO_FALL);
		Ghost_UnsetFlag(GHF_KNOCKBACK);
		Ghost_SetFlag(GHF_FLYING_ENEMY);
		
		int OrigTile = ghost->OriginalTile;
		int State = 0;
		int haltcounter = -1;
		int StateCounter =Teledelay;
		int dir = Ghost_Dir;
		int ewpn = 0;
		int combo = 0;
		bool berserk=false;
		while(true){
			if (State==BOSS_SLIME_WALL_STATE_NOT_IN_PLANE){
				ghost->DrawXOffset = 1000;
				ghost->HitXOffset = 1000;
				if (StateCounter == 0){
					ghost->DrawXOffset = 0;
					ghost->HitXOffset = 0;
					combo = FindSpawnPoint(true, false, false, false);
					if (combo>0)Ghost_X=ComboX(combo);
					if (combo>0)Ghost_Y=ComboY(combo);
					State = BOSS_SLIME_WALL_STATE_TELEPORTING_IN;
					StateCounter = 32;
					dir = SlimeWallFaceLink(ghost);
				}
			}
			if (State==BOSS_SLIME_WALL_STATE_TELEPORTING_IN){
				// if(IsOdd(StateCounter))  ghost->DrawXOffset=StateCounter/4;
				// else  ghost->DrawXOffset=-StateCounter/4;
				if (StateCounter == 0){
					State = BOSS_SLIME_WALL_STATE_CHARGING;
					StateCounter = 32;
				}
			}
			if (State==BOSS_SLIME_WALL_STATE_CHARGING){
				if (StateCounter == 0){
					State = BOSS_SLIME_WALL_STATE_FIRED;
					StateCounter = 32;
					eweapon e;
					ewpn =1<<( Rand(5));
					if ((ewpn&Wpn)==0){
						e = FireAimedEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, 0, 200, WPND, ewsprite, -1, 0);
					}
					else if (ewpn == 1){
						int dirs[4]= {DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT};
						// Game->PlaySound(ewSound);
						for (int i=0;i<SizeOfArray(dirs);i++){
							eweapon e = FireNonAngularEWeapon(ghost->Weapon,  Ghost_X, Ghost_Y, dirs[i], 300, WPND, ewsprite,-1, EWF_ROTATE);
						}
					}
					else if (ewpn == 2){
						int dirs[8] = {DIR_UP, DIR_RIGHTUP, DIR_RIGHT, DIR_RIGHTDOWN, DIR_DOWN, DIR_LEFTDOWN, DIR_LEFT, DIR_LEFTUP};
						// Game->PlaySound(ewSound);
						for (int i=0;i<SizeOfArray(dirs);i++){
							e = FireNonAngularEWeapon(ghost->Weapon, Ghost_X, Ghost_Y, dirs[i], 300, WPND, ewsprite,-1, EWF_ROTATE);
						}
					}
					else if (ewpn == 4){
						Game->PlaySound(SFX_SUMMON);
						for (int i=1; i<=Encount;i++){
							combo = SlimeWallFindSuitableSpot(ghost, MinLinkDistance,true, false, false, false);
							npc en = CreateNPCAt(EnID,ComboX(combo), ComboY(combo));
							en->Z=128;
							TraceNL();
						}
					}
					else if (ewpn == 8){
						eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, WPND, 22, SFX_BOSS_SLIME_WALL_NUKE, EWF_UNBLOCKABLE);
						e->Dir = Link->Dir;
						e->DrawYOffset = -1000;
						SetEWeaponLifespan(e, EWL_TIMER, 1);
						SetEWeaponDeathEffect(e, EWD_VANISH, 0);
						
						for (int i=1; i<=60;i++){
							if(i % 2 == 0) Screen->Rectangle(6, 0, 0, 256, 172, BOSS_SLIME_WALL_NUKE_FLASH_COLOR, 1, 0, 0, 0, true, 64);
							Ghost_Waitframe(this, ghost);
						}
					}
					else if (ewpn == 16){
						ShuffleArray(cmbs);
						curcmb = 0;
						for (int i=1; i<=numcmbchange;i++){
							while(cmbs[curcmb]<0){
								if (cmbs[curcmb]<0)curcmb++;
								if (curcmb>=175)break;
							}
							temp = cmbs[curcmb];
							Screen->ComboD[temp]=changecmb;
							curcmb++;
						}
					}
				}
			}
			if (State==BOSS_SLIME_WALL_STATE_FIRED){
				if (StateCounter == 0){
					State = BOSS_SLIME_WALL_STATE_TELEPORTING_OUT;
					StateCounter = 32;
				}
			}
			if (State==BOSS_SLIME_WALL_STATE_TELEPORTING_OUT){
				if(IsOdd(StateCounter))  ghost->DrawXOffset=1000;
				else  ghost->DrawXOffset=0;
				if (StateCounter == 0){
					ghost->DrawXOffset = 1000;
					ghost->HitXOffset = 1000;
					State = BOSS_SLIME_WALL_STATE_NOT_IN_PLANE;
					StateCounter = Cond(berserk,berserkDelay,Teledelay);
				}
			}
			StateCounter--;
			if (!berserk){
				if (Ghost_HP<=berserkHP){
					Game->PlaySound(SFX_SUMMON);
					berserk=true;
				}
			}
			SlimeWallAnimation(ghost, OrigTile, State, 1);
			if (!Ghost_Waitframe(this, ghost, false, false)){
				ghost->DrawXOffset=0;
				Ghost_DeathAnimation(this, ghost, GHD_EXPLODE);
				Quit();
			}
		}
	}
}

void SlimeWallAnimation(npc ghost, int origtile, int state, int numframes){
	int offset = state-1;
	if (offset<0)offset=0;
	ghost->OriginalTile = origtile + 20*offset*ghost->TileHeight;
}

int SlimeWallFaceLink(npc ghost){
	int cmb = ComboAt (CenterLinkX(), CenterLinkY());
	int ghostcmb = ComboAt (Ghost_X+8, Ghost_Y+8);
	if (ComboY(cmb)<ComboY(ghostcmb)) return DIR_UP;
	else if (ComboY(cmb)>ComboY(ghostcmb)) return DIR_DOWN;
	else if (ComboX(cmb)<ComboX(ghostcmb))  return DIR_LEFT;
	else  return DIR_RIGHT;	
}

int  SlimeWallFindSuitableSpot(npc ghost, int MinLinkDistance, bool landOK, bool wallsOK, bool waterOK, bool pitsOK){
	int tileRatings[176];
    int checkCombo;
    int checkX;
    int checkY;
    int bestRating;
    int bestCount;
    int counter;
    int choice;
    int tries;
    npc otherNPC;    
    // First, rate each tile for suitability. Lower is better,
    // but negative means it's strictly off-limits.      
    for(int i=Screen->NumNPCs(); i>0; i--){// Tiles too close to other enemies are undesirable
        otherNPC=Screen->LoadNPC(i);
        checkCombo=ComboAt(otherNPC->X, otherNPC->Y);
        tileRatings[checkCombo]+=100;        
        if(checkCombo>15)tileRatings[checkCombo-16]+=1;		
        if(checkCombo<160)tileRatings[checkCombo+16]+=1;		
        if(checkCombo%16>0)tileRatings[checkCombo-1]+=1;		
        if(checkCombo%16<15)tileRatings[checkCombo+1]+=1;		
	}    
    // Mark prohibited tiles
    for(int i=0; i<176; i++){       
        if((Screen->Flags[SF_ROOMTYPE]&010b)!=0 && (i<32 || i>143 || i%16<2 || i%16>13))	tileRatings[i]=-1;   // Screen edges in NES dungeon      
        else if(IsWater(i)){// Water
            if(!waterOK)tileRatings[i]=-1;			
		}        
        else if(__IsPit(i)){// Pits
            if(!pitsOK)tileRatings[i]=-1;			
		}       
        else if(Screen->ComboF[i]==CF_NOENEMY || Screen->ComboI[i]==CF_NOENEMY || Screen->ComboT[i]==CT_NOENEMY || Screen->ComboT[i]==CT_NOJUMPZONE)tileRatings[i]=-1; // "No enemy" flag and combos      
        else if(Abs(ComboX(i)-Link->X)<32 && Abs(ComboY(i)-Link->Y)<32) tileRatings[i]+=150;// Too close to Link      
        else{  // All other combos		
			if(landOK && !wallsOK){// If land is okay, but not walls (i.e. walkable only)             
				if (Screen->ComboS[i]>0) tileRatings[i]=-1;				
			}			
			else if(!landOK && wallsOK){   // If walls are okay, but not land (i.e. unwalkable only)            
				if(Screen->ComboS[i]<15) tileRatings[i]=-1;
			}		
			else if(!landOK && !wallsOK)tileRatings[i]=-1;	// Neither land nor walls are okay		
		}
		if (tileRatings[i]>=0){
			tileRatings[i]+=20;
			if (DamageComboPower(i)>0)	tileRatings[i]+=1200;
			int cmb = ComboAt (CenterLinkX(), CenterLinkY());
			if (Distance(ComboX(i), ComboY(i), ComboX(cmb), ComboY(cmb))<MinLinkDistance)tileRatings[i]+=12;
		}
	}
	
	bestRating=10000;// Find the best rating and count the number of tiles with that rating
	bestCount=0;
	for(int i=0; i<176; i++){
		if(tileRatings[i]<0)	continue;		
		if(tileRatings[i]==bestRating)	bestCount++;
		else if(tileRatings[i]<bestRating){
			bestRating=tileRatings[i];
			bestCount=1;
		}
	}	
	
	if(bestCount==0)return 0;	// The loop below might hang if every tile is unusable	
	counter=Rand(bestCount)+1;// Pick at random from the best rated tiles
	
	for(choice=0; counter>0; choice++){
		if(tileRatings[choice]==bestRating)counter--;	
	}	
	return choice-1;// Subtract 1 because the for loop overshot
}

//Swaps two elements in the given array
void SwapArray(int arr, int pos1, int pos2){
	int r = arr[pos1];
	arr[pos1]=arr[pos2];
	arr[pos2]=r;
}

//Shuffles the given array like deck of playing cards
void ShuffleArray(int arr){
	int size = SizeOfArray(arr)-1;
	for (int i=0; i<=size*size; i++){
		int r1 = Rand(size);
		int r2 = Rand(size);
		SwapArray(arr, r1, r2);
	}
}

const int SFX_SLIMEWALL_DEATH = 3;
const int SPR_SLIMEWALL_DEATH = 92;

ffc script SlimeWallBody{
	void run(int npcslot, int dir, int speed, int threshold1, int threshold2, int speed2){
		for(int i=0;i<4;i++){
			Screen->FastCombo(0, this->X, this->Y, this->Data, this->CSet, OP_OPAQUE);
			if (dir==DIR_UP){Screen->FastCombo(0, this->X, this->Y+16, this->Data+2, this->CSet, OP_OPAQUE);}
			if (dir==DIR_DOWN){Screen->FastCombo(0, this->X, this->Y-16, this->Data+2, this->CSet, OP_OPAQUE);}
			if (dir==DIR_LEFT){Screen->FastCombo(0, this->X-16, this->Y, this->Data+2, this->CSet, OP_OPAQUE);}
			if (dir==DIR_RIGHT){Screen->FastCombo(0, this->X+16, this->Y, this->Data+2, this->CSet, OP_OPAQUE);}
			if (dir>1){
				for (int i=1; i<16; i++){					
					if (!Screen->isSolid(this->X, this->Y-16*i))Screen->FastCombo(0, this->X, this->Y-16*i, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y+16*i))Screen->FastCombo(0, this->X, this->Y+16*i, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y-16*i))Screen->FastCombo(0, this->X+Cond(dir==DIR_LEFT,16,-16), this->Y-16*i, this->Data+2, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y+16*i))Screen->FastCombo(0, this->X+Cond(dir==DIR_LEFT,16,-16), this->Y+16*i, this->Data+2, this->CSet, OP_OPAQUE);
				}
			}
			else{
				for (int i=1; i<16; i++){
					if (!Screen->isSolid(this->X-16*i, this->Y))Screen->FastCombo(0, this->X-16*i, this->Y, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X+16*i, this->Y))Screen->FastCombo(0, this->X+16*i, this->Y, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X-16*i, this->Y))Screen->FastCombo(0, this->X-16*i, this->Y+Cond(dir==DIR_UP,16,-16), this->Data+2, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X+16*i, this->Y))Screen->FastCombo(0, this->X+16*i, this->Y+Cond(dir==DIR_UP,16,-16), this->Data+2, this->CSet, OP_OPAQUE);
				}
			}
			Waitframe();
		}
		npc en = Screen->LoadNPC(npcslot);
		int drawx = 0;
		int drawy = 0;
		if (!en->isValid()){
			Game->PlaySound(SFX_GANON);
			Quit();
		}
		int moving = 0;
		lweapon explosion;
		while(true){
			if (en->HP<=0){
				this->Vx=0;
				this->Vy=0;
				for (int i=0;i<176;i++){
					if (Screen->ComboD[i]!=this->Data+1 && Screen->ComboD[i]!=this->Data+2)continue;
					Screen->ComboD[i]=Screen->UnderCombo;
					Screen->ComboC[i]=Screen->UnderCSet;
					explosion=Screen->CreateLWeapon(LW_SPARKLE);
					explosion->X=ComboX(i);
					explosion->Y=ComboY(i);
					explosion->UseSprite(SPR_SLIMEWALL_DEATH);
					explosion->CollDetection=false;
				}
				Game->PlaySound(SFX_SLIMEWALL_DEATH);
				this->Data=0;
				Quit();
			}
			if (moving==0){
				if (en->HP<=threshold1){
					if (dir==DIR_UP){
						this->Vy = -speed;
					}
					if (dir==DIR_DOWN){
						this->Vy = speed;
					}
					if (dir==DIR_LEFT){
						this->Vx = -speed;
					}
					if (dir==DIR_RIGHT){
						this->Vy = -speed;
					}
					moving=1;
				}
			}
			else if (moving==1){
				if (en->HP<=threshold2){
					if (dir==DIR_UP){
						this->Vy *= speed2;
					}
					if (dir==DIR_DOWN){
						this->Vy *= speed2;
					}
					if (dir==DIR_LEFT){
						this->Vx *= -speed2;
					}
					if (dir==DIR_RIGHT){
						this->Vy *= -speed2;
					}
					for (int i=1;i<=32;i++){
						ffc f =Screen->LoadFFC(i);
						if (!f->Flags[FFCF_CHANGER])continue;
						if (f->Data!=this->Data)continue;
						f->Vx*=speed2;
						f->Vy*=speed2;
					}
					moving=2;
				}
			}
			for (int i=0;i<176;i++){
				if (Screen->ComboS[i]>0) continue;
				// if (Screen->ComboD[i]==this->Data+1 || Screen->ComboD[i]==this->Data+2) continue;
				if (dir==DIR_UP){
					if (ComboY(i)>=this->Y+16){
						if (Screen->ComboD[i]!=this->Data+1 && Screen->ComboD[i]!=this->Data+2){
							Screen->ComboD[i]=(this->Data)+1;
							Screen->ComboC[i]=this->CSet;
						}
					}
					else{
						if (Screen->ComboD[i]==this->Data+1 || Screen->ComboD[i]==this->Data+2){
							Screen->ComboD[i]=Screen->UnderCombo;
							Screen->ComboC[i]=Screen->UnderCSet;
						}
					}
				}
				if (dir==DIR_DOWN){
					if (ComboY(i)<=this->Y-16){
						if (Screen->ComboD[i]!=this->Data+1 && Screen->ComboD[i]!=this->Data+2){
							Screen->ComboD[i]=(this->Data)+1;
							Screen->ComboC[i]=this->CSet;
						}
					}
					else{
						if (Screen->ComboD[i]==this->Data+1 || Screen->ComboD[i]==this->Data+2){
							Screen->ComboD[i]=Screen->UnderCombo;
							Screen->ComboC[i]=Screen->UnderCSet;
						}
					}
				}
				if (dir==DIR_LEFT){
					if (ComboX(i)>=this->X+16){
						if (Screen->ComboD[i]!=this->Data+1 && Screen->ComboD[i]!=this->Data+2){
							Screen->ComboD[i]=(this->Data)+1;
							Screen->ComboC[i]=this->CSet;
						}
					}
					else{
						if (Screen->ComboD[i]==this->Data+1 || Screen->ComboD[i]==this->Data+2){
							Screen->ComboD[i]=Screen->UnderCombo;
							Screen->ComboC[i]=Screen->UnderCSet;
						}
					}
				}
				if (dir==DIR_RIGHT){
					if (ComboX(i)<=this->X-16){
						if (Screen->ComboD[i]!=this->Data+1 && Screen->ComboD[i]!=this->Data+2){
							Screen->ComboD[i]=(this->Data)+1;
							Screen->ComboC[i]=this->CSet;
						}
					}
					else{
						if (Screen->ComboD[i]==this->Data+1 || Screen->ComboD[i]==this->Data+2){
							Screen->ComboD[i]=Screen->UnderCombo;
							Screen->ComboC[i]=Screen->UnderCSet;
						}
					}
				}
			}
			Screen->FastCombo(0, this->X, this->Y, this->Data, this->CSet, OP_OPAQUE);
			if (dir==DIR_UP){Screen->FastCombo(0, this->X, this->Y+16, this->Data+2, this->CSet, OP_OPAQUE);
			}
			if (dir==DIR_DOWN){Screen->FastCombo(0, this->X, this->Y-16, this->Data+2, this->CSet, OP_OPAQUE);
			}
			if (dir==DIR_LEFT){Screen->FastCombo(0, this->X-16, this->Y, this->Data+2, this->CSet, OP_OPAQUE);
			}
			if (dir==DIR_RIGHT){Screen->FastCombo(0, this->X+16, this->Y, this->Data+2, this->CSet, OP_OPAQUE);
			}
			if (dir>1){
				for (int i=1; i<16; i++){					
					if (!Screen->isSolid(this->X, this->Y-16*i))Screen->FastCombo(0, this->X, this->Y-16*i, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y+16*i))Screen->FastCombo(0, this->X, this->Y+16*i, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y-16*i))Screen->FastCombo(0, this->X+Cond(dir==DIR_LEFT,16,-16), this->Y-16*i, this->Data+2, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X, this->Y+16*i))Screen->FastCombo(0, this->X+Cond(dir==DIR_LEFT,16,-16), this->Y+16*i, this->Data+2, this->CSet, OP_OPAQUE);
				}
			}
			else{
				for (int i=1; i<16; i++){
					if (!Screen->isSolid(this->X-16*i, this->Y))Screen->FastCombo(0, this->X-16*i, this->Y, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X+16*i, this->Y))Screen->FastCombo(0, this->X+16*i, this->Y, this->Data, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X-16*i, this->Y))Screen->FastCombo(0, this->X-16*i, this->Y+Cond(dir==DIR_UP,16,-16), this->Data+2, this->CSet, OP_OPAQUE);
					if (!Screen->isSolid(this->X+16*i, this->Y))Screen->FastCombo(0, this->X+16*i, this->Y+Cond(dir==DIR_UP,16,-16), this->Data+2, this->CSet, OP_OPAQUE);
				}
			}
			// debugValue(1, this->Data+1);
			Waitframe();
		}
	}
}

//Returns power of damage combo at given coordinates, or 0, it`s not a damage combo.
int DamageComboPower(int cmb){
	if (Screen->ComboT[cmb] == CT_DAMAGE1) return 2;
	else if (Screen->ComboT[cmb] == CT_DAMAGE2) return 4;
	else if (Screen->ComboT[cmb] == CT_DAMAGE3) return 8;
	else if (Screen->ComboT[cmb] == CT_DAMAGE4) return 16;
	else if (Screen->ComboT[cmb] == CT_DAMAGE5) return 32;
	else if (Screen->ComboT[cmb] == CT_DAMAGE6) return 64;
	else if (Screen->ComboT[cmb] == CT_DAMAGE7) return 128;
	else	return 0;
}