Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "std.zh"
- ////////////////////////////////////////////////////////////////
- // Charge Bow
- // by grayswandir
- ////////////////////////////////////////////////////////////////
- // Description:
- //
- // This is an 8-way bow that you can charge-up, aim, and shoot. If an arrow
- // hits a flame source, it'll turn into a flamming arrow (fire-type weapon).
- ////////////////////////////////////////////////////////////////
- // Setup:
- //
- // This requires std.zh.
- //
- // Read through the following Integration section and change all the values to
- // suit your quest.
- //
- // Make sure to load the ChargeBow ffc script, and the ChargeBow_Use item
- // script.
- //
- // Set ChargeBow_Use as the item use script of the item used to fire
- // it. Change it from an arrow to a Custom Item class. (Also remember to
- // change the subscreen slot from arrow to that custom item class as well.)
- // Make the first provided argument to the script the item's id. The second
- // should be the first arrow tile, and the third the cset to use. The tiles
- // should be in order of Up, Down, Left, Right, Left-Up, Right-Up, Left-Down,
- // Right-Down.
- //
- // This makes use of global variables, so it will invalidate saves when added.
- ////////////////////////////////////////////////////////////////
- // Integration
- ////////////////
- // This section is the part that needs to be set manually for each quest. Read
- // the description for each part and set it accordingly.
- ////////////////
- ////////////////////////////////////////////////////////////////
- // Link Animation Setup
- // Each link animation is a block of tiles. Advancing to the right moves
- // through the different directions. (The order is Up, Down, Left, Right,
- // Left-Up, Right-Up, Left-Down, Right-Down). The first row is with the bow &
- // arrow, the second row is without the arrow. Each frame is a 2 by 2 tile
- // that is centered on Link.
- // Higher number costumes take precedence.
- //// Default Costume
- // The starting tile for the link animation.
- const int CHARGEBOW_LINK_C0_TILE = 1300;
- // The cset the link animation uses.
- const int CHARGEBOW_LINK_C0_CSET = 6;
- //// Costume 1
- // The item that marks using costume 1. Set to 0 to disable.
- const int CHARGEBOW_LINK_C1_ITEM = 0;
- // The starting tile for the link animation.
- const int CHARGEBOW_LINK_C1_TILE = 0;
- // The cset the link animation uses.
- const int CHARGEBOW_LINK_C1_CSET = 6;
- //// Costume 2
- // The item that marks using costume 2. Set to 0 to disable.
- const int CHARGEBOW_LINK_C2_ITEM = 0;
- // The starting tile for the link animation.
- const int CHARGEBOW_LINK_C2_TILE = 0;
- // The cset the link animation uses.
- const int CHARGEBOW_LINK_C2_CSET = 6;
- //// Costume 3
- // The item that marks using costume 3. Set to 0 to disable.
- const int CHARGEBOW_LINK_C3_ITEM = 0;
- // The starting tile for the link animation.
- const int CHARGEBOW_LINK_C3_TILE = 0;
- // The cset the link animation uses.
- const int CHARGEBOW_LINK_C3_CSET = 6;
- //// Costume 4
- // The item that marks using costume 4. Set to 0 to disable.
- const int CHARGEBOW_LINK_C4_ITEM = 0;
- // The starting tile for the link animation.
- const int CHARGEBOW_LINK_C4_TILE = 0;
- // The cset the link animation uses.
- const int CHARGEBOW_LINK_C4_CSET = 6;
- ////////////////////////////////////////////////////////////////
- // Gameplay Setup
- //// Charge Level 0
- // This is the sound played when you first use the bow. Set to 0 for no sound.
- const int CHARGEBOW_START_SOUND = 0;
- // This is the sound played when you release a level 0 shot. Set to 0 for no sound.
- const int CHARGEBOW_L0_SHOT_SOUND = 1;
- //// Charge Level 1
- // This is the item id that unlocks this charge level. Set to 0 for no item
- // needed.
- const int CHARGEBOW_L1_ITEM_ID = 0;
- // This is the cumulative frames you need to charge for this charge level.
- const int CHARGEBOW_L1_CHARGE_TIME = 45;
- // This is the sound played when you reach charge level 1. Set to 0 for no
- // sound.
- const int CHARGEBOW_L1_CHARGE_SOUND = 35;
- // This is the sound played when you release a level 1 shot. Set to 0 for no
- // sound.
- const int CHARGEBOW_L1_SHOT_SOUND = 1;
- //// Charge Level 2
- // This is the item id that unlocks this charge level. Set to 0 for no item
- // needed.
- const int CHARGEBOW_L2_ITEM_ID = 0;
- // This is the cumulative frames you need to charge for this charge level.
- const int CHARGEBOW_L2_CHARGE_TIME = 90;
- // This is the sound played when you reach charge level 2. Set to 0 for no
- // sound.
- const int CHARGEBOW_L2_CHARGE_SOUND = 36;
- // This is the sound played when you release a level 2 shot. Set to 0 for no
- // sound.
- const int CHARGEBOW_L2_SHOT_SOUND = 1;
- //// Effects
- // This is the combo flag that sets an arrow on fire. Defaults to script 1.
- const int CHARGEBOW_BURN_FLAG = 98;
- // This is the sound that's made when the arrow catches on fire. Set to 0 for
- // no sound.
- const int CHARGEBOW_BURN_SOUND = 0;
- // This is the amount of damage the arrow does.
- int ChargeBow_Damage(int item_id, int charge_level, int element) {
- itemdata data = Game->LoadItemData(item_id);
- int damage = data->Power;
- return damage;
- }
- // The amount of speed each level of charge adds to the arrow.
- const int CHARGEBOW_ARROW_CHARGE_SPEED = 1;
- // This is the speed the arrow flies at. For reference, Link's movement is
- // 1.5. Defaults to the strongest bow that Link has.
- int ChargeBow_Speed(int item_id, int charge_level, int element) {
- int bow_id = -1;
- int bow_level = -1;
- itemdata data;
- // Find the highest level bow item the player has.
- for (int i = 0; i < 256; ++i) {
- data = Game->LoadItemData(i);
- if (!Link->Item[i]) {continue;}
- if (IC_BOW != data->Family) {continue;}
- if (data->Level > bow_level) {
- bow_id = i;
- bow_level = data->Level;
- }
- }
- // Grab the speed from that bow.
- data = Game->LoadItemData(bow_id);
- int speed = data->Power;
- // Add speed for each charge level.
- speed += charge_level * CHARGEBOW_ARROW_CHARGE_SPEED;
- return speed;
- }
- ////////////////////////////////////////////////////////////////
- // Main Script
- const int CHARGEBOW_ELEMENT_NONE = 0;
- item script ChargeBow_Use {
- void run(int item_id, int tile, int cset) {
- int i; ffc f;
- // Cancel out if there's already an arrow on screen.
- if (ChargeBow.IsActive()) {return;}
- // Look for a free FFC slot.
- for (i = 1; i <= 32; ++i) {
- f = Screen->LoadFFC(i);
- if (0 == f->Data && 0 == f->Script) {break;}
- }
- // If we didn't find a free ffc, quit.
- if (33 == i) {return;}
- // Start up the ffc script.
- f->Script = ChargeBow.ScriptId();
- f->InitD[0] = item_id;
- f->InitD[1] = tile;
- f->InitD[2] = cset;
- // Play the start sound.
- if (CHARGEBOW_START_SOUND) {Game->PlaySound(CHARGEBOW_START_SOUND);}
- }
- }
- ffc script ChargeBow {
- // Get the script number for this script.
- int ScriptId() {
- int name[] = "ChargeBow";
- return Game->GetFFCScript(name);
- }
- // If the chargebow ffc is currently active.
- bool IsActive() {
- int script_id = ChargeBow.ScriptId();
- for (int i = 1; i <= 32; ++i) {
- ffc f = Screen->LoadFFC(i);
- if (script_id == f->Script) {return true;}
- }
- return false;
- }
- // Get a multiplier for the x component of a direction.
- int DirX(int dir) {
- if (DIR_LEFT == dir || DIR_LEFTUP == dir || DIR_LEFTDOWN == dir) {return -1;}
- else if (DIR_RIGHT == dir || DIR_RIGHTUP == dir || DIR_RIGHTDOWN == dir) {return 1;}
- else {return 0;}
- }
- // Get a multiplier for the y component of a direction.
- int DirY(int dir) {
- if (DIR_UP == dir || DIR_LEFTUP == dir || DIR_RIGHTUP == dir) {return -1;}
- else if (DIR_DOWN == dir || DIR_LEFTDOWN == dir || DIR_RIGHTDOWN == dir) {return 1;}
- else {return 0;}
- }
- // Get the facing based on held buttons. If nothing is held returns Link->Dir.
- int LinkInputDir() {
- if (Link->InputUp) {
- if (Link->InputLeft) {return DIR_LEFTUP;}
- else if (Link->InputRight) {return DIR_RIGHTUP;}
- else {return DIR_UP;}
- }
- else if (Link->InputDown) {
- if (Link->InputLeft) {return DIR_LEFTDOWN;}
- else if (Link->InputRight) {return DIR_RIGHTDOWN;}
- else {return DIR_DOWN;}
- }
- else if (Link->InputLeft) {return DIR_LEFT;}
- else if (Link->InputRight) {return DIR_RIGHT;}
- else {return Link->Dir;}
- }
- // If the given charge level has been unlocked.
- bool LevelUnlocked(int level) {
- if (0 == level) {return true;}
- if (1 == level) {return !CHARGEBOW_L1_ITEM_ID || Link->Item[CHARGEBOW_L1_ITEM_ID];}
- if (2 == level) {return !CHARGEBOW_L2_ITEM_ID || Link->Item[CHARGEBOW_L2_ITEM_ID];}
- return false;
- }
- // The amount of time needed to reach this charge level.
- int ChargeTime(int level) {
- if (1 == level) {return CHARGEBOW_L1_CHARGE_TIME;}
- if (2 == level) {return CHARGEBOW_L2_CHARGE_TIME;}
- return 0;
- }
- // Play the charge sound for a given level.
- int PlayChargeSound(int level) {
- int sound = 0;
- if (1 == level) {sound = CHARGEBOW_L1_CHARGE_SOUND;}
- else if (2 == level) {sound = CHARGEBOW_L2_CHARGE_SOUND;}
- if (sound) {Game->PlaySound(sound);}
- }
- // Play the shot sound for a given level.
- int PlayShotSound(int level) {
- int sound = 0;
- if (0 == level) {sound = CHARGEBOW_L0_SHOT_SOUND;}
- else if (1 == level) {sound = CHARGEBOW_L1_SHOT_SOUND;}
- else if (2 == level) {sound = CHARGEBOW_L2_SHOT_SOUND;}
- if (sound) {Game->PlaySound(sound);}
- }
- // Get the tile base for link's graphic.
- int LinkTileBase() {
- if (CHARGEBOW_LINK_C4_ITEM && Link->Item[CHARGEBOW_LINK_C4_ITEM]) {return CHARGEBOW_LINK_C4_TILE;}
- else if (CHARGEBOW_LINK_C3_ITEM && Link->Item[CHARGEBOW_LINK_C3_ITEM]) {return CHARGEBOW_LINK_C3_TILE;}
- else if (CHARGEBOW_LINK_C2_ITEM && Link->Item[CHARGEBOW_LINK_C2_ITEM]) {return CHARGEBOW_LINK_C2_TILE;}
- else if (CHARGEBOW_LINK_C1_ITEM && Link->Item[CHARGEBOW_LINK_C1_ITEM]) {return CHARGEBOW_LINK_C1_TILE;}
- else {return CHARGEBOW_LINK_C0_TILE;}
- }
- // Get the cset for link's graphic.
- int LinkCSet() {
- if (CHARGEBOW_LINK_C4_ITEM && Link->Item[CHARGEBOW_LINK_C4_ITEM]) {return CHARGEBOW_LINK_C4_CSET;}
- else if (CHARGEBOW_LINK_C3_ITEM && Link->Item[CHARGEBOW_LINK_C3_ITEM]) {return CHARGEBOW_LINK_C3_CSET;}
- else if (CHARGEBOW_LINK_C2_ITEM && Link->Item[CHARGEBOW_LINK_C2_ITEM]) {return CHARGEBOW_LINK_C2_CSET;}
- else if (CHARGEBOW_LINK_C1_ITEM && Link->Item[CHARGEBOW_LINK_C1_ITEM]) {return CHARGEBOW_LINK_C1_CSET;}
- else {return CHARGEBOW_LINK_C0_CSET;}
- }
- void run(int item_id, int arrow_tile, int arrow_cset) {
- // Hide Link.
- Link->Invisible = true;
- // Grab Link's graphic.
- int tile = ChargeBow.LinkTileBase();
- int cset = ChargeBow.LinkCSet();
- // First, find what button we're using.
- bool button_a = GetEquipmentA() == item_id;
- // Charge the shot.
- int charge_timer = 0;
- int charge_level = 0;
- while (true) {
- // If link got hurt, quit the script.
- if (LA_GOTHURTLAND == Link->Action || LA_GOTHURTWATER == Link->Action) {
- Link->Invisible = false;
- Quit();
- }
- // Exit the loop if we've let go of the button.
- if (!Cond(button_a, Link->InputA, Link->InputB)) {break;}
- // Increment the charge timer.
- ++charge_timer;
- // Check if we've passed to the next level.
- if (LevelUnlocked(charge_level + 1) && ChargeTime(charge_level + 1) == charge_timer) {
- ++charge_level;
- PlayChargeSound(charge_level);
- }
- // Set Link's direction.
- Link->Dir = ChargeBow.LinkInputDir();
- // Prevent normal commands.
- NoAction();
- // Draw Link.
- Screen->DrawTile(2, Link->X - 8, Link->Y - 8, tile + Link->Dir * 2, 2, 2,
- cset, -1, -1, 0, 0, 0, 0, true, OP_OPAQUE);
- // Wait for the next frame.
- Waitframe();
- }
- // Make Link visible again.
- Link->Invisible = false;
- // Create the arrow.
- int dir = ChargeBow.LinkInputDir();
- int dx = ChargeBow.DirX(dir);
- int dy = ChargeBow.DirY(dir);
- lweapon arrow = Screen->CreateLWeapon(LW_ARROW);
- arrow->Damage = ChargeBow_Damage(item_id, charge_level, CHARGEBOW_ELEMENT_NONE);
- arrow->Dir = dir;
- arrow->X = Link->X + dx * 16;
- arrow->Y = Link->Y + dy * 16;
- arrow->Step = ChargeBow_Speed(item_id, charge_level, CHARGEBOW_ELEMENT_NONE) * 100;
- arrow->OriginalTile = arrow_tile + dir;
- arrow->OriginalCSet = arrow_cset;
- arrow->Tile = arrow_tile + dir;
- arrow->CSet = arrow_cset;
- arrow->NumFrames = 1;
- while (arrow->isValid()) {
- Waitframe();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement