Jump to content

Photo

Alttp Bow Help...


  • Please log in to reply
No replies to this topic

#1 RephireZeKasual217

RephireZeKasual217

    Initiate

  • Members

Posted 16 January 2018 - 01:09 AM

I want to use the Alttp Charge bow script, but i want to have the arrow counter to show when it's selected on the subscreen.

-----------------------------------------------------------------------

// Delete these import lines if you already have them in your script file.
 
import "std.zh"
import "ffcscript.zh"
 
const int SPRITE_SPARKLE = 29; // Sparkle sprite for when charge bow is finished charging. NOT FOR ARROW SPARKLES!
const int SFX_BOW_CHARGE = 36; // Sound for when charge bow is finished charging.
const int SFX_ERROR = 61; // Error sound for when Link is out of arrows. Set to 0 for no sound.
 
int facing_dir;
bool bow_charging[2]; // [0] is true while bow is charging, [1] is true if Link gets hit while charging
 
global script BowActive
{
void run()
{
while (true)
{
Waitdraw();
BowAnimation();
Waitframe();
}
}
}
 
void BowAnimation()
{
if (bow_charging[0])
{
// Comment out if you don't want charging interrupted by getting hit!
// vvv
if (BowInterrupt())
{
bow_charging[0] = false;
bow_charging[1] = true;
return;
}
// ^^^
// Comment out if you don't want charging interrupted by getting hit!
 
Link->Dir = facing_dir;
}
bow_charging[0] = false;
}
 
// The function that determines if the bow charge should be interrupted.
bool BowInterrupt()
{
if (Link->Action > 1)
{
return true;
}
return false;
}
 
// Bow and arrow tiles cannot exceed 32768!
// Your bow and arrow tiles should be in the order up, down, left, right.
// This item script should be attached to the Action Script slot of an item that has a custom item class, not an existing bow.
// The Power of the item is how much damage it does. Most weapons do two times their "Damage" stat, but not this one!
// D0: bow tile
// D1: bow CSet
// D2: arrow sprite
// D3: arrow step speed (300 for short bow, 600 for long bow are ZC defaults)
// D4: sparkle sprite number, 0 for none
item script LttPBow
{
void run(int bow_tile, int bow_cset, int arrow_sprite, int arrow_step, int sparkle_sprite)
{
// Only triggers if the bow isn't already drawn.
int script_name[] = "LttPBowFFC";
int script_num = Game->GetFFCScript(script_name);
int bow_family = this->Family;
if (CountFFCsRunning(script_num) == 0)
{
float args[] = {bow_tile, bow_cset, arrow_sprite, this->Power, arrow_step, sparkle_sprite, bow_family};
RunFFCScript(script_num, args);
}
 
}
}
 
ffc script LttPBowFFC
{
void run(int bow_tile, int bow_cset, int arrow_sprite, int arrow_damage, int arrow_step, int sparkle_sprite, int bow_family)
{
itemdata A_item;
itemdata B_item;
bool using_B = false;
 
B_item = Game->LoadItemData(GetEquipmentB());
if (B_item->Family == bow_family)
{
using_B = true;
}
 
// Comment this out to give Link's bowmanship a lot less oomph.
Link->Action = LA_ATTACKING;
 
// Loop to draw the bow for 15 frames before firing. Similar for loops for additional frames of animation, such as taking out the bow
// à la Link to the Past, can be placed here.
for (int i = 0; i < 15; i++)
{
A_item = Game->LoadItemData(GetEquipmentA());
B_item = Game->LoadItemData(GetEquipmentB());
 
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
if (A_item->Family != bow_family)
{
Link->InputA = false;
// Quits if you switch item.
if (!using_B)
{
Quit();
}
}
if (B_item->Family != bow_family)
{
Link->InputB = false;
// Quits if you switch item.
if (using_B)
{
Quit();
}
}
// Disable other button inputs here if you want.
 
// Quits if Link gets hit. Comment this out if you don't want arrow firing to be interrupted.
if (Link->Action == LA_GOTHURTLAND)
{
Quit();
}
 
Screen->FastTile(4, Link->X + InFrontX(Link->Dir, 7), Link->Y + InFrontY(Link->Dir, 7), bow_tile + Link->Dir, bow_cset, OP_OPAQUE);
 
Waitframe();
}
 
// Checks to see that you have arrows and that no previously fired arrows are on screen.
if ((Game->Counter[CR_ARROWS] > 0 || Link->Item[I_QUIVER4]) && NumLWeaponsOf(LW_ARROW) == 0)
{
if (!Link->Item[I_QUIVER4])
{
Game->Counter[CR_ARROWS]--;
}
Game->PlaySound(SFX_ARROW);
lweapon arrow = NextToLink(LW_ARROW, 0);
arrow->UseSprite(arrow_sprite);
arrow->Damage = arrow_damage;
arrow->Step = arrow_step;
arrow->Dir = Link->Dir;
LWeaponFlip(arrow, arrow->Dir);
 
//Arrow hitbox shenanigans. Modeled after ZC arrow defaults.
if (arrow->Dir == DIR_UP || arrow->Dir == DIR_DOWN)
{
arrow->HitWidth = 15;
arrow->HitHeight = 12;
arrow->HitXOffset = 0;
arrow->HitYOffset = 2;
arrow->DrawXOffset = 0;
arrow->DrawYOffset = -2;
}
else
{
arrow->HitWidth = 12;
arrow->HitHeight = 14;
arrow->HitXOffset = 2;
arrow->HitYOffset = 2;
arrow->DrawXOffset = 0;
arrow->DrawYOffset = 1;
}
// Creates sparkles around arrow while it's onscreen, if sprite for them is set.
for (int i = 0; NumLWeaponsOf(LW_ARROW) > 0 && sparkle_sprite; i = (i + 1) % 4)
{
if (i == 0)
{
arrow = LoadLWeaponOf(LW_ARROW);
SetSparkle(arrow, sparkle_sprite);
}
 
Waitframe();
}
}
else
{
if (Game->Counter[CR_ARROWS] == 0 && !Link->Item[I_QUIVER4] && SFX_ERROR)
{
Game->PlaySound(SFX_ERROR); // Plays the error sound, if there is one, when Link is out of arrows.
}
Quit();
}
}
}
 
// Bow and arrow tiles cannot exceed 32768!
// Your bow and arrow tiles should be in the order up, down, left, right.
// This item script should be attached to the Action Script slot of an item that has a custom item class, not an existing bow.
// The Power of the item is how much damage it does. Most weapons do two times their "Damage" stat, but not this one!
// D0: bow tile
// D1: bow CSet
// D2: arrow sprite
// D3: arrow step speed (300 for short bow, 600 for long bow are ZC defaults)
// D4: sparkle sprite number, 0 for none
// D5: charge time
item script LttPChargeBow
{
void run(int bow_tile, int bow_cset, int arrow_sprite, int arrow_step, int sparkle_sprite, int charge_time)
{
// Only triggers if the bow isn't already drawn.
int script_name[] = "LttPChargeBowFFC";
int script_num = Game->GetFFCScript(script_name);
int bow_family = this->Family;
if (CountFFCsRunning(script_num) == 0)
{
float args[] = {bow_tile, bow_cset, arrow_sprite, this->Power, arrow_step, sparkle_sprite, charge_time, bow_family};
RunFFCScript(script_num, args);
}
 
}
}
 
ffc script LttPChargeBowFFC
{
void run(int bow_tile, int bow_cset, int arrow_sprite, int arrow_damage, int arrow_step, int sparkle_sprite, int charge_time, int bow_family)
{
itemdata A_item;
itemdata B_item;
bool using_B = false;
bool fully_charged;
int bow_charge;
lweapon sparkle;
bow_charging[1] = false;
facing_dir = Link->Dir;
 
B_item = Game->LoadItemData(GetEquipmentB());
if (B_item->Family == bow_family)
{
using_B = true;
}
 
// Comment this out to give Link's bowmanship a lot less oomph.
//Link->Action = LA_ATTACKING;
 
// Loop to draw the bow for 15 frames before firing. Similar for loops for additional frames of animation, such as taking out the bow
// à la Link to the Past, can be placed here.
for (int i = 0; true; i++)
{
A_item = Game->LoadItemData(GetEquipmentA());
B_item = Game->LoadItemData(GetEquipmentB());
 
if (i % 2 == 0)
{
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
}
if (A_item->Family != bow_family)
{
Link->InputA = false;
// Quits if you switch item.
if (!using_B)
{
Quit();
}
}
if (B_item->Family != bow_family)
{
Link->InputB = false;
// Quits if you switch item.
if (using_B)
{
Quit();
}
}
if (using_B && !Link->InputB)
{
if (bow_charge >= charge_time)
{
fully_charged = true;
}
break;
}
else if (!using_B && !Link->InputA)
{
if (bow_charge >= charge_time)
{
fully_charged = true;
}
break;
}
else
{
bow_charge++;
}
// Disable other button inputs here if you want.
 
// Quits if Link gets hit. Comment this out if you don't want arrow firing to be interrupted.
if (Link->Action == LA_GOTHURTLAND || bow_charging[1])
{
bow_charging[1] = false;
Quit();
}
 
bow_charging[0] = true;
 
// Charge up sparkle animation.
if (i == charge_time)
{
Game->PlaySound(SFX_BOW_CHARGE);
sparkle = Screen->CreateLWeapon(LW_SPARKLE);
sparkle->X = Link->X;
sparkle->Y = Link->Y;
sparkle->UseSprite(SPRITE_SPARKLE);
sparkle->CollDetection = false;
sparkle->Misc[0] = 15;
}
for (int j = 1; j <= Screen->NumLWeapons(); j++)
{
sparkle = Screen->LoadLWeapon(j);
if (sparkle->ID == LW_SPARKLE && sparkle->Misc[0] == 15)
{
DrawToLayer(sparkle, 4, OP_OPAQUE);
sparkle->X = Link->X;
sparkle->Y = Link->Y;
}
}
 
Screen->FastTile(4, Link->X + InFrontX(Link->Dir, 7), Link->Y + InFrontY(Link->Dir, 7), bow_tile + Link->Dir, bow_cset, OP_OPAQUE);
 
Waitframe();
}
 
Link->Action = LA_ATTACKING;
 
for (int i = 0; i < 10; i++)
{
A_item = Game->LoadItemData(GetEquipmentA());
B_item = Game->LoadItemData(GetEquipmentB());
 
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
 
if (A_item->Family != bow_family)
{
Link->InputA = false;
// Quits if you switch item.
if (!using_B)
{
Quit();
}
}
if (B_item->Family != bow_family)
{
Link->InputB = false;
// Quits if you switch item.
if (using_B)
{
Quit();
}
}
 
// Quits if Link gets hit. Comment this out if you don't want arrow firing to be interrupted.
if (Link->Action == LA_GOTHURTLAND)
{
Quit();
}
 
Screen->FastTile(4, Link->X + InFrontX(Link->Dir, 7), Link->Y + InFrontY(Link->Dir, 7), bow_tile + Link->Dir, bow_cset, OP_OPAQUE);
 
Waitframe();
}
 
// Checks to see that you have arrows and that no previously fired arrows are on screen.
if ((Game->Counter[CR_ARROWS] > 0 || Link->Item[I_QUIVER4]) && NumLWeaponsOf(LW_ARROW) == 0)
{
if (!Link->Item[I_QUIVER4])
{
Game->Counter[CR_ARROWS]--;
}
Game->PlaySound(SFX_ARROW);
lweapon arrow = NextToLink(LW_ARROW, 0);
arrow->UseSprite(arrow_sprite);
arrow->Damage = arrow_damage;
arrow->Step = arrow_step;
// Multiply damage by 2 and step by 2 if bow was fully charged before releasing.
if (fully_charged)
{
arrow->Damage *= 2;
arrow->Step *= 2;
}
arrow->Dir = Link->Dir;
LWeaponFlip(arrow, arrow->Dir);
 
//Arrow hitbox shenanigans. Modeled after ZC arrow defaults.
if (arrow->Dir == DIR_UP || arrow->Dir == DIR_DOWN)
{
arrow->HitWidth = 15;
arrow->HitHeight = 12;
arrow->HitXOffset = 0;
arrow->HitYOffset = 2;
arrow->DrawXOffset = 0;
arrow->DrawYOffset = -2;
}
else
{
arrow->HitWidth = 12;
arrow->HitHeight = 14;
arrow->HitXOffset = 2;
arrow->HitYOffset = 2;
arrow->DrawXOffset = 0;
arrow->DrawYOffset = 1;
}
// Creates sparkles around arrow while it's onscreen, if sprite for them is set.
for (int i = 0; NumLWeaponsOf(LW_ARROW) > 0 && sparkle_sprite; i = (i + 1) % 4)
{
if (i == 0)
{
arrow = LoadLWeaponOf(LW_ARROW);
SetSparkle(arrow, sparkle_sprite);
}
 
Waitframe();
}
}
else
{
if (Game->Counter[CR_ARROWS] == 0 && !Link->Item[I_QUIVER4] && SFX_ERROR)
{
Game->PlaySound(SFX_ERROR); // Plays the error sound, if there is one, when Link is out of arrows.
}
Quit();
}
}
}
 
// This function flips the arrow sprite in the proper way based on direction.
void LWeaponFlip(lweapon lwpn, int dir)
{
int flip;
 
if (dir == DIR_UP)
{
flip = 0;
}
else if (dir == DIR_DOWN)
{
flip = 3;
}
else if (dir == DIR_LEFT)
{
flip = 7;
}
else if (dir == DIR_RIGHT)
{
flip = 4;
}
else if (dir == DIR_LEFTUP)
{
flip = 0;
}
else if (dir == DIR_RIGHTUP)
{
flip = 0;
}
else if (dir == DIR_LEFTDOWN)
{
flip = 3;
}
else if (dir == DIR_RIGHTDOWN)
{
flip = 3;
}
 
lwpn->Flip = flip;
}
 
// This function generates sparkles for flying arrows.
//
// UP
// Sparkles oscillate between 0 to 3 pixels greater than arrow X. 4 to 7 pixels greater than arrow Y. OffsetY is -2.
//
// DOWN
// Sparkles oscillate between 0 to 3 pixels greater than arrow X. 1 to 4 pixels less than arrow Y. OffsetY is -2.
//
// LEFT
// Sparkles oscillate between 4 to 7 pixels greater than arrow X. 0 to 3 pixels greater than arrow Y. OffsetY is -2.
//
// RIGHT
// Sparkles oscillate between 1 to 4 pixels less than arrow X. 0 to 3 pixels greater than arrow Y. OffsetY is -2.
//
void SetSparkle(lweapon arrow, int sparkle_sprite)
{
lweapon sparkle = CreateLWeaponAt(LW_SPARKLE, arrow->X, arrow->Y);
sparkle->UseSprite(sparkle_sprite);
if (arrow->Dir == DIR_UP)
{
sparkle->X = arrow->X + Rand(0, 3);
sparkle->Y = arrow->Y + Rand(4, 7);
}
if (arrow->Dir == DIR_DOWN)
{
sparkle->X = arrow->X + Rand(0, 3);
sparkle->Y = arrow->Y - Rand(1, 4);
}
if (arrow->Dir == DIR_LEFT)
{
sparkle->X = arrow->X + Rand(4, 7);
sparkle->Y = arrow->Y + Rand(0, 3);
}
if (arrow->Dir == DIR_RIGHT)
{
sparkle->X = arrow->X - Rand(1, 4);
sparkle->Y = arrow->Y + Rand(0, 3);
}
sparkle->DrawYOffset = -2;
sparkle->CollDetection = false;
}
--------------------------------------------------------------------------------------

Edited by RephireZeKasual217, 16 January 2018 - 10:48 PM.



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users