//FF_Tektite
//Jumps around bouncing off inaccessible terrain, firing eweapons at Link at the apex of the jump.
//Uses 2 rows of tiles, normal ,then jumping directly below
ffc script Tektite{
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 sizex = Ghost_GetAttribute(ghost, 0, 4);//Tile Width
int sizey = Ghost_GetAttribute(ghost, 1, 4);//Tile Height
int jumpdelay = Ghost_GetAttribute(ghost, 2, 42);//minimum delay between jumps, in frames.
int maxjumpdelay = Ghost_GetAttribute(ghost, 3, 60);//Maximum delay between jumps, in frames.
int jumppower = Ghost_GetAttribute(ghost, 4, 320);//jumping height
int moveangle = Ghost_GetAttribute(ghost, 5, 0);//0 - use diagonal dumps only, 1 - 8-way jumping, 2+ = fine jumping angle
int terrain = Ghost_GetAttribute(ghost, 6, 0);//Allowed terrain to land onto. Add together: 1 - solid combos, 2 - water, 4 - pits.
int WPNS = Ghost_GetAttribute(ghost, 7, -1);//Eweapon sprite
ghost->Extend=3;
Ghost_SetSize(this, ghost, sizex, sizey);
if (sizex>2)Ghost_SetHitOffsets(ghost, 4, 4, 8, 8);
int State = 0;
int haltcounter = -1;
int statecounter = jumpdelay+Rand(maxjumpdelay-jumpdelay);
eweapon e;
int angle=0;
int origtile = ghost->OriginalTile;
int offset = 0;
float xStep=0;
float yStep=0;
int angle4[4]={45,135,-45,-135};
int angle8[8]={0,45,90,135,180,-135,-90,-45};
bool fired=false;
Ghost_SetFlag(GHF_NORMAL);
Ghost_UnsetFlag(GHF_KNOCKBACK);
if ((terrain&1)>0)Ghost_SetFlag(GHF_IGNORE_SOLIDITY);
if ((terrain&2)>0)Ghost_SetFlag(GHF_IGNORE_WATER);
if ((terrain&4)>0)Ghost_SetFlag(GHF_IGNORE_PITS);
while(true){
if (State==0){
statecounter--;
if (statecounter==0){
angle = Angle(CenterX(ghost),CenterY(ghost),CenterLinkX(),CenterLinkY());
if (Rand(256)>=HF) angle = Rand(360);
if (moveangle==0) angle = GetClosestFromArray(angle4, angle);
if (moveangle==1) angle = GetClosestFromArray(angle8, angle);
xStep = SPD/100*Cos(angle);
yStep = SPD/100*Sin(angle);
Ghost_Jump=jumppower/100;
offset = 20*Ghost_TileHeight;
State=1;
}
}
else if (State==1){
if(xStep<0)// Bounce
{
if(!Ghost_CanMove(DIR_LEFT, -xStep, 3))
xStep*=-1;
}
else
{
if(!Ghost_CanMove(DIR_RIGHT, xStep, 3))
xStep*=-1;
}
if(yStep<0)
{
if(!Ghost_CanMove(DIR_UP, -yStep, 3))
yStep*=-1;
}
else
{
if(!Ghost_CanMove(DIR_DOWN, yStep, 3))
yStep*=-1;
}
Ghost_MoveXY(xStep, yStep, 3);
if (!fired&&Ghost_Jump<=0&&WPND>0){
e=FireAimedEWeapon(ghost->Weapon, CenterX(ghost)-8, CenterY(ghost)-8-Ghost_Z, 0, 100, WPND, WPNS, -1, EWF_ROTATE);
fired=true;
}
if (Ghost_Z<=0&&Ghost_Jump<=0){
statecounter = jumpdelay+Rand(maxjumpdelay-jumpdelay);
offset = 0;
Ghost_Z=0;
xStep=0;
yStep=0;
fired=false;
State=0;
}
}
ghost->OriginalTile = origtile+offset;
// debugValue(1, angle);
//debugValue(2, Ghost_Z);
Ghost_Waitframe(this, ghost);
}
}
}
int GetClosestFromArray(int arr, int target){
int diff = 99999;
int newdiff;
int ret = 0;
for (int i=0;i<SizeOfArray(arr);i++){
newdiff = Abs(arr[i]- target);
if (newdiff>=diff) continue;
diff=newdiff;
ret = i;
if (newdiff==0)return target;
}
return arr[ret];
}