DEFINE LW_TENNIS_HITBOX = LW_SCRIPT10; // Weapon type used for the LWeapon hitbox on a reflected volley
CONFIG SFX_TENNIS_REFLECT_LINK = SFX_CLINK; // Sound when Link hits the weapon
CONFIG SFX_TENNIS_REFLECT_ENEMY = SFX_CLINK; // Sound when the enemy hits the weapon
CONFIG TENNIS_HIT_STOP = 8; // How many frames the weapon holds in place before reflecting
@InitD0("Bounces"),
@InitDHelp0("How many extra times the weapon must be hit before its enemy hitbox goes active. If >0 the enemy can bounce the weapon back at Link."),
@InitD1("Homing"),
@InitDHelp1("Whether or not the weapon homes in on the parent enemy. Useful if the enemy is fast moving and you don't want the volleys to miss.")
eweapon script Tennis
{
void run(int bounces, bool homing)
{
lweapon hitbox = FireLWeaponDegAngle(LW_TENNIS_HITBOX, this->X, this->Y, 0, 0, this->Damage, 0, 0);
hitbox->NoCollisionTimer = -1;
hitbox->DrawXOffset = -10000;
hitbox->HitXOffset = this->HitXOffset;
hitbox->HitYOffset = this->HitYOffset;
hitbox->HitWidth = this->HitWidth;
hitbox->HitHeight = this->HitHeight;
bool reflected;
int step = this->Step;
while(true)
{
this->Dir = AngleDir4(WrapDegrees(this->DegAngle));
if(hitbox->isValid())
{
hitbox->X = this->X;
hitbox->Y = this->Y;
hitbox->Dir = this->Dir;
}
if(!reflected)
{
bool hit;
for(int i=Screen->NumLWeapons; i>0; --i)
{
lweapon l = Screen->LoadLWeapon(i);
if(l->ID==LW_SWORD||l->Weapon==LW_SWORD)
{
if(Collided(this, l))
{
hit = true;
break;
}
}
}
if(hit)
{
Audio->PlaySound(SFX_TENNIS_REFLECT_LINK);
this->Step = 0;
this->NoCollisionTimer = TENNIS_HIT_STOP;
Waitframes(TENNIS_HIT_STOP);
this->Step = step;
this->DegAngle = Angle(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this));
reflected = true;
}
}
else
{
this->NoCollisionTimer = 2;
if(homing)
{
if(this->Parent->isValid())
{
this->DegAngle = Angle(CenterX(this), CenterY(this), CenterX(this->Parent), CenterY(this->Parent));
}
}
if(bounces<=0)
{
if(hitbox->isValid())
hitbox->NoCollisionTimer = 0;
else
this->Remove();
}
else
{
if(Collided(this, this->Parent))
{
Audio->PlaySound(SFX_TENNIS_REFLECT_ENEMY);
this->Step = 0;
this->NoCollisionTimer = TENNIS_HIT_STOP;
Waitframes(TENNIS_HIT_STOP);
this->Step = step;
this->DegAngle = Angle(CenterX(this), CenterY(this), CenterLinkX(), CenterLinkY());
--bounces;
reflected = false;
}
}
}
Waitframe();
}
}
bool Collided(eweapon this, sprite s)
{
int x1 = s->X+s->HitXOffset;
int y1 = s->Y+s->HitYOffset;
int x2 = this->X+this->HitXOffset+4;
int y2 = this->Y+this->HitYOffset+4;
return RectCollision(x1, y1, x1+s->HitWidth-1, y1+s->HitHeight-1, x2, y2, x2+this->HitWidth-9, y2+this->HitHeight-9) && (this->Z + this->HitZHeight >= s->Z) && (this->Z <= s->Z + s->HitZHeight);
}
}