Jump to content

Photo
- - - - -

Example Scripts


  • Please log in to reply
1 reply to this topic

#1 idontknow8

idontknow8

    Senior

  • Members

Posted 08 August 2016 - 07:51 PM

So I thought it might be useful/helpful to compile a list of all the example scripts shown in the script tutorials, including those in the quiz. Is possible to keep this pinned???

 

1. Item Script that refills health and magic (like a potion)

// Using an item with this script will refill Link's HP and MP.
item script Recharge
{
   void run()
    {
        Link->HP = Link->MaxHP;
        Link->MP = Link->MaxMP;
    }
}
2. Item that enables level 4 cheat
// This script will enable level 4 cheats. This won't work correctly if
// cheats are disabled in the quest.

item script CheatLevel4
{
    void run()
    {
        Game->Cheat = 4;
    }
}
​3. Item Script: Screen shakes & Link jumps
// This script will cause the screen to shake for one second and make Link jump into the air.
// It will also disable the sword and items for as long as the screen shakes.

ffc script Earthquake
{
    void run()
    {
        // There are 60 frames in a second, so...
        Screen->Quake = 60;
        Link->Jump = 3;
        Link->SwordJinx = 60;
        Link->ItemJinx = 60;
    }
}
4. FFC Script: Moves the FFC to Link's position (once)
ffc script PutLinkHere
{
    void run()
    {
        Link->X = this->X;
        Link->Y = this->Y;
    }
}
​5. Item Script: Sets Link's HP to 3 Hearts & MP to 3 Magic Containers
item script ThreeHCAndMC
{
    void run()
    {
        Link->HP = 48;
        Link->MP = 96;
    }
}
6. ​FFC SCript: FFC Moves to the left & accelerates to the right
ffc script LeftToRight
{
    void run()
    {
        // These numbers are arbitrary.
        this->Vx = -5;
        this->Ax = 0.075;
    }
7. ​Reduce Link's HP & MP by 25%
// This script reduces Link's current HP and MP by 25%.
ffc script SeventyFive
{
    void run()
    {
        Link->HP *= 0.75;
        Link->MP *= 0.75;
    }
}
8. Aims FFC at Link but accelerate in the opposite direcition:
// This script will make the FFC aim at Link, but accelerate in the opposite direction.
ffc script VeerAway
{
    void run()
    {
        // Dividing by 60 means it will take one second to reach Link's position -
        // or it would, if it weren't accelerating away
        this->Vx = (Link->X - this->X) / 60;
        this->Vy = (Link->Y - this->Y) / 60;

        // Acceleration can be unintutive; you may want to try this one out.
        // The acceleration is based on the negative of the velocity, so if it
        // starts out moving up and left, it'll accelerate down and right.
        this->Ax = -this->Vx / 150;
        this->Ay = -this->Vy / 150;
    }
}
9.​ Disable sword & items based on HP & MP (respectively)
// This script disables Link's sword for one second for every full heart and
// disables items for one second for every full magic container.
ffc script ProportionateDisability
{
    void run()
    {
        // 16 HP in a heart, 60 frames in a second
        Link->SwordJinx = (Link->HP / 16) * 60;

        // And 32 MP in a magic container
        Link->ItemJinx = (Link->MP / 32) * 60;
    }
}
10.​ Moves Link down & to the right
ffc script MoveDownRight
{
    void run()
    {
        Link->X += 16;
        Link->Y += 16;
    }
}
11. Lose 1/4 Magic container but gain HP
item script QuarterMPHeal
{
    void run()
    {
        // The HP gain is equal to 1/8 of Link's MP when the item is used.
        Link->HP += Link->MP / 8;
        Link->MP -= Link->MP * 0.25;
    }
}
12. FFC that plays the secret sound effect (once)
// This script will play sound effect #27 (the secret sound, by default).

ffc script SecretSound
{
    void run()
    {
        Game->PlaySound(27);
    }
}
13. ​Draws a shrinking circle around Link
// This script will draw a quickly shrinking circle around Link on layer 5.
// You'll learn better ways to do this sort of thing later on.

ffc script CircleLink
{
    void run()
    {
        // Don't be overwhelmed by all the arguments. Just figure out what they do one by one.
        Screen->Circle(5, Link->X+8, Link->Y+8, 16, 3, 1, 0, 0, 0, false, 128);
        Waitframe();
        Screen->Circle(5, Link->X+8, Link->Y+8, 12, 3, 1, 0, 0, 0, false, 128);
        Waitframe();
        Screen->Circle(5, Link->X+8, Link->Y+8, 8, 3, 1, 0, 0, 0, false, 128);
        Waitframe();
        Screen->Circle(5, Link->X+8, Link->Y+8, 4, 3, 1, 0, 0, 0, false, 128);
    }
}
14. Moves FFC towards Link, one pixel at atime
// This script uses trigonometric functions to make the FFC aim at Link, moving at one pixel per frame.

import "std.zh"

ffc script MoveTowardLink
{
    void run()
    {
        // Using functions from std.zh:
        this->Vx = VectorX(1, Angle(this->X, this->Y, Link->X, Link->Y);
        this->Vy = VectorY(1, Angle(this->X, this->Y, Link->X, Link->Y);
        
        // Here's another way to do it...
        // For angular movement at a given speed, X velocity is speed * Cos(angle),
        // and Y velocity is speed * Sin(angle).
        //this->Vx = 1 * RadianCos(ArcTan(Link->X - this->X, Link->Y - this->Y));
        //this->Vy = 1 * RadianSin(ArcTan(Link->X - this->X, Link->Y - this->Y));
    }
}
15. FFC Script: Waits 10 seconds & then play a sound
ffc script SoundAfterTenSeconds
{
    void run()
    {
        Waitframes(600);
        Game->PlaySound(28); // #28 is the sound played when Link dies
    }
}
16. Global script that adds a cheat every ten time Link has died
global script HelpMe
{
    void run()
    {
        // Use the Min() function to ensure the level doesn't go above 4
        Game->Cheat = Min(4, Link->NumDeaths / 10);
    }
17. Waits five seconds, then the screen flashes
ffc script Flash
{
    void run()
    {
        Waitframes(300);
        Screen->Rectangle(6, 0, 0, 255, 175, 2, 1, 0, 0, 0, true, 128);
    }
}
18. Earthquake script (screen shakes & makes a sound)
// This script will play a sound and make the screen shake.
// It will also disable the sword and items for as long as the screen shakes.

// Change the constants to control how long the quake lasts and what sound is played.
const int EQ_QUAKE_TIME = 60;
const int EQ_QUAKE_SOUND = 13;

ffc script Earthquake
{
    void run()
    {
        Game->PlaySound(EQ_QUAKE_SOUND);
        Screen->Quake = EQ_QUAKE_TIME;
        Link->SwordJinx = EQ_QUAKE_TIME;
        Link->ItemJinx = EQ_QUAKE_TIME;
    }
}
19. Warping FFC Script
// This warps Link to DMap 10, screen 1F.
const int WARP_DEST_DMAP = 10;
const int WARP_DEST_SCREEN = 0x1F;

ffc script WarpLink
{
    void run()
    {
        Link->PitWarp(WARP_DEST_DMAP, WARP_DEST_SCREEN);
    }
}
20. Takes away all of Link's swords
ffc script Disarm
{
    void run()
    {
        Link->Item[I_SWORD1]=false;
        Link->Item[I_SWORD2]=false;
        Link->Item[I_SWORD3]=false;
        Link->Item[I_SWORD4]=false;
    }
}
21. Refills Link's bombs & increases his max by 4 (like a More Bombs special room type)
// This script refills Link's bombs and increases the maximum by 4.

import "std.zh"

ffc script MoreBombs
{
    void run()
    {
        Game->MCounter[CR_BOMBS] += 4;
        Game->Counter[CR_BOMBS] = Game->MCounter[CR_BOMBS];
    }
}
22. Changes color of combo Link is standing on
// When this item is used, it will randomly change the CSet of the combo Link is standing on.

import "std.zh"

item script ColorChange
{
    void run()
    {
        // ZQuest only lets you select a CSet up to 11, but CSets 0-15 all work
        Screen->ComboC[ComboAt(Link->X, Link->Y)] = Rand(16);
    }
}
23. Gives Link a key in exchange for losing one heart container
item script HCtoKey
{
    void run()
    {
        Link->MaxHP = Max(Link->HP - HP_PER_HEART, HP_PER_HEART);
        Link->HP = Min(Link->HP, Link->MaxHP); // Because Link->HP might be greater than Link->MaxHP now
        Game->Counter[CR_KEY] += 1;
    }
}
24 Gives ink an extra bomb for every heart he's missing from his max HP.
ffc script PainToBombs
{
    void run()
    {
        Game->Counter[CR_BOMBS] += (Link->MaxHP - Link->HP) / HP_PER_HEART;
    }
}
25. Draws a line between Link & this FFC
// This script will draw a line connecting Link and the FFC.

ffc script ConnectingLine
{
    void run()
    {
        while(true)
        {
            // The line will flash because a random color is selected each frame
            Screen->Line(0, this->X + 8, this->Y + 8, Link->X + 8, Link->Y + 8, Rand(16), 1, 0, 0, 0, 128);
            Waitframe();
        }
    }
}

​26. Moves a FFC toward Link, readjusting its aim every two seconds
ffc script ReaimRepeatedly
{
    void run()
    {
        while(true) // This will repeat indefinitely
        {
            // Aim toward Link
            this->Vx = (Link->X - this->X) / Distance(Link->X, Link->Y, this->X, this->Y);
            this->Vy = (Link->Y - this->Y) / Distance(Link->X, Link->Y, this->X, this->Y);
            
            // Wait two seconds, then the loop will repeat
            Waitframes(120);
        }
    }
}
27. Drains Link's MP while button B is held
// This script will drain Link's MP as long as B is held.
// (Again, nested loops aren't normally the way this would be done.)

ffc script MPDrainOnB
{
    void run()
    {
        while(true)
        {
            while(Link->InputB)
            {
                Link->MP -=1;
                Waitframe();
            }
            
            Waitframe();
            
            // Why are two Waitframes needed? If the inner loop didn't have a Waitframe call,
            // it would be a hanging infinite loop when B was pressed. If the outer loop didn't
            // have one, it would hang when B was not pressed.
        }
    }
}
28. Keps the FFC's position opposite Link's. If Link is, say, one tile down from the top-left corner, the FFC will be one tile up from the bottom-right. This only takes a few lines; just figure out the mathematical relationship between the two's positions.
ffc script MirrorLink
{
    void run()
    {
        while(true)
        {
            this->X = 240 - Link->X;
            this->Y = 160 - Link->Y;
            Waitframe();
        }
    }
}
29. Draws a circle around Link & follows him as he moves

ffc script CircleLink
{
    void run()
    {
        while(true)
        {
            Screen->Circle(6, Link->X + 8, Link->Y + 8, 16, 1, 1, 0, 0, 0, false, 128);
            Waitframe();
        }
    }
}

30. Heals Link while the B button is held
// This script will heal Link while the B button is held.
ffc script BButtonHeal
{
    void run()
    {
        while(true)
        {
            if(Link->InputB)
            {
                Link->HP +=1;
            }
            Waitframe();
        }
    }
}
(Please don't reply yet, will add more later)

 

31. Reverse left & right buttons

// This script will reverse the left and right buttons.
ffc script SwitchLeftAndRight
{
    void run()
    {
	    while(true)
	    {
		    // If you don't see why it's done this way, try writing it differently
		    // and work out what happens when both left and right are pressed
		    if(Link->InputLeft)
		    {
			    // If both buttons are pressed, nothing changes
			    if(Link->InputRight)
			    {
				    // Do nothing
			    }
			    // If only left is pressed, unpress it and press right instead
			    else
			    {
				    Link->InputRight = true;
				    Link->InputLeft = false;
			    }
		    }
		    // If only right is pressed, unpress it and press left instead
		    else if(Link->InputRight)
		    {
			    Link->InputLeft = true;
			    Link->InputRight = false;
		    }
		   
		    Waitframe();
	    }
    }
}
32. Makes FFC move left if right is pressed & right if left is pressed.
ffc script OtherWay
{
    void run()
    {
	    while(true)
	    {
		    if(Link->InputLeft)
		    {
			    this->X += 2;
		    }
		    if(Link->InputRight)
		    {
			    this->X -= 2;
		    }
		   
		    // What would be different if the second "if" were "else if" instead?
		   
		    Waitframe();
	    }
    }
}
33. Refills Link's MP while both L & R are held.
global script LRforMP
{
    void run()
    {
	    while(true)
	    {
	 	   // The next section will provide a better way to do this.
		    if(Link->InputL)
		    {
			    if(Link->InputR)
			    {
				    Link->MP += 2;
			    }
		    }
		    Waitframe();
	    }
    }
}
34. Warp to another screen if A is pressed.
// This script warps Link to another screen when the player presses A.

const int AWARP_DEST_DMAP = 1;
const int AWARP_DEST_SCREEN = 0x24;

ffc script WarpOnA
{
    void run()
    {
	    // While A isn't pressed, just wait
	    while(!Link->InputA)
	    {
		    Waitframe();
	    }
	    Link->Warp(AWARP_DEST_DMAP, AWARP_DEST_SCREEN);
    }
}
35. Script acts like a switch, opening the North Door.
// This script makes the FFC act as a switch that opens the north door for ten seconds
// when Link steps on it.

import "std.zh"

ffc script DoorSwitch
{
    void run()
    {
	    while(true)
	    {
		    // Check if Link has stepped on the switch.
		    // The reason for using Abs() like this is to give a few pixels' leeway;
		    // if the condition were Link->X == this->X && Link->Y == this->Y,
		    // Link would have to be perfectly aligned with the FFC to trigger it.
   		 if(Abs(Link->X - this->X) < 4 && Abs(Link->Y - this->Y) < 4)
		    {
			    // Change the FFC's combo and open the door, then wait ten seconds
			    // and do the opposite
			    this->Data += 1;
			    Screen->Door[DIR_UP] = D_OPENSHUTTER;
			    Game->PlaySound(SFX_SHUTTER);
			   
			    Waitframes(600);
			   
			    this->Data -= 1;
			    Screen->Door[DIR_UP] = D_1WAYSHUTTER;
			    Game->PlaySound(SFX_SHUTTER);
		    }
		   
		    Waitframe();
	    }
    }
}
//This script will allow Link to spend MP to heal by holding L and R
// if he has the amulet.

import "std.zh"

global script HealingAmulet
{
    void run()
    {
	    while(true)
	    {
		    // It's often clearer to split longer conditions in two
		    if(Link->Item[I_AMULET1] && Link->InputL && Link->InputR)
		    {
			    if(Link->HP < Link->MaxHP && Link->MP > 0)
		  	  {
				    Link->MP -= 1;
				    Link->HP += 1;
			    }
		    }
		    Waitframe();
	    }
    }
}
36. If EX1 is pressed & Link is not already in the air, Link jumps.
const int EX1_JUMP_VELOCITY = 4;

global script Ex1Jump
{
    void run()
    {
	    while(true)
	    {
		    if(Link->Z == 0 && Link->PressEx1)
		    {
			    Link->Jump = EX1_JUMP_VELOCITY;
		    }
		    Waitframe();
	    }
    }
}
37. The SwitchLeftAndRight script from the previous section rewritten using logical operators instead of nested ifs.
ffc script SwitchLeftAndRight2
{
    void run()
    {
	    while(true)
	    {
		    if(Link->InputLeft && !Link->InputRight)
		    {
			    Link->InputRight = true;
			    Link->InputLeft = false;
		    }
		    else if(Link->InputRight && !Link->InputLeft)
		    {
			    Link->InputLeft = true;
			    Link->InputRight = false;
		    }
		    Waitframe();
	    }
    }
}
38. Plays a sound & opens a door if Link has two items, plays a message string if he doesn't
const int KEY_ITEM_1 = 155;
const int KEY_ITEM_2 = 156;
const int KEY_ITEM_MSG = 20;

ffc script ItemCheck
{
    void run()
    {
	    if(Link->Item[KEY_ITEM_1] && Link->Item[KEY_ITEM_2])
	    {
		    Game->PlaySound(SFX_SECRET);
		    Screen->Door[DIR_UP] = D_OPENSHUTTER;
	    }
	    else
	    {
		    Screen->Message(KEY_ITEM_MSG);
	    }
    }
}
39. Moves a FFC in a circle around Link
// This script will make the FFC move in a circle around Link.
const float ORBIT_SPEED = 2.5;
const float ORBIT_RADIUS = 48;

ffc script OrbitLink
{
    void run()
    {
	    float angle;
	    for(angle = 0; true; angle = (angle + ORBIT_SPEED) % 360)
	    {
		    this->X = Link->X + ORBIT_RADIUS * Cos(angle);
		    this->Y = Link->Y + ORBIT_RADIUS * Sin(angle);
		    Waitframe();
	    }
    }
}
40. FFC moves across the screen to the right in a Sine Wave pattern
const int SWR_AMPLITUDE = 32;

ffc script SineWaveRight
{
    void run()
    {
	    int centerY = this->Y; // The center of the sine wave
	    int counter = 0; // Used with the sine function to find the offset from center
	   
	    this->Vx = 1;
	    while(true)
	    {
		    this->Y = centerY + SWR_AMPLITUDE * Sin(counter);
		    Waitframe();
		   
		    // The counter increases by 1 each frame and resets to 0 when it hits 360
		    counter = (counter + 1) % 360;
	    }
    }
}
41. Two scripts join together to create an item that allows Link to float in the air

bool floating = false; // This allows the item and global scripts to communicate

item script FloatItem
{
    void run()
    {
	    floating = !floating; // Switches between true and false
    }
}

global script FloatGlobal
{
    void run()
    {
	    // Make sure the variable gets reset after continuing the game
	    floating = false;
	   
	    while(true)
	    {
		    if(floating)
		    {
			    if(Link->Z < 32)
			    {
				    Link->Jump = 1;
			    }
			    else
			    {
				    // Prevent Link from falling
				    Link->Jump = 0;
			    }
		    }
		    Waitframe();
	    }
    }
}
42. Two item scripts: One remembers the current screen; the other warps him to that screen. (Kinda like like Farore's wind in Ocarina of Time)
int warpDestDMap = -1;
int warpDestScreen = -1;

item script RememberScreen
{
    void run()
    {
	    warpDestDMap = Game->GetCurDMap();
	    warpDestScreen = Game->GetCurDMapScreen();
    }
}

item script WarpToScreen
{
    void run()
    {
	    // If RememberScreen hasn't been used yet, don't do anything
	    if(warpDestScreen == -1)
	    {
		    Quit();
	    }
	   
    	Link->PitWarp(warpDestDMap, warpDestScreen);
    }
}
43. Heals Link if he steps on this FFC but only once per screen
const int IDX_STEP_HEAL = 0; // Screen->D[] index

ffc script StepHeal
{
    void run()
    {
	    if(Screen->D[IDX_STEP_HEAL] == 1)
	    {
		    // The script already ran, so quit.
		    Quit();
	    }
	   
	    while(true)
	    {
		    if(Abs(Link->X - this->X) < 4 && Abs(Link->Y - this->Y) < 4)
		    {
			    // Using DCounter will make Link's HP refill gradually
			    Game->DCounter[CR_LIFE] = Link->MaxHP;
			    Screen->D[IDX_STEP_HEAL] = 1;
			    Quit();
		    }
		    Waitframe();
	    }
    }
}
44. Reverse left & right script but with no conditional statements at all this time.
ffc script SwitchLeftAndRight3
{
    void run()
    {
	    bool temp;
	   
	    while(true)
	    {
		    temp = Link->InputLeft;
		    Link->InputLeft = Link->InputRight;
		    Link->InputRight = temp;
		   
		    Waitframe();
	    }
    }
}
45. Closes all doors when there are no enemies in the room
ffc script EnemiesHoldDoors
{
    void run()
    {
	    int direction; // The direction currently being checked
	    int doorState; // This is just used to make it easier to write
	   
	    // Enemies don't appear for four frames; the script needs to wait for them
	    // to appear before waiting for them to disappear
	    Waitframes(4);
	   
	    while(Screen->NumNPCs() > 0)
	    {
		    Waitframe(); // Just wait until the monsters are gone
	    }
	   
	    // Cycle through the four doors - the directions are 0-3
	    for(direction = 0; direction < 4; direction += 1)
	    {
		    // Make sure the door is open before closing it;
		    // you wouldn't want to turn a wall into a door
		    doorState = Screen->Door[direction];
		    if(doorState == D_OPEN || doorState == D_OPENSHUTTER ||
			   doorState == D_UNLOCKED || doorState == D_BOSSUNLOCKED)
		    {
			    Screen->Door[direction] = D_1WAYSHUTTER;
		    }
	    }
    }
}​
46. Finds every combo that has the flag "Combo Flag Script 1" and changes those combos
import "std.zh"

ffc script Flag98Changer
{
    void run()
    {
        int index;
        for(index = 0; index < 176; index += 1)
        {
            if(Screen->ComboF[index] == CF_SCRIPT1 || Screen->ComboI[index] == CF_SCRIPT1)
            {
                Screen->ComboD[index] += 1;
            }
        }
    }
}
47. Rewards Link with rupees with the amount based on how long it took to defeat enemies in a room.
ffc script TimeBonus
{
    void run()
    {
        int timer;
        float seconds;
        int bonus;
        
        // Wait for enemies to appear
        Waitframes(4);
        
        // If there are no enemies in the first place, just quit. Otherwise,
        // Link would get the maximum reward for doing nothing.
        if(Screen->NumNPCs() == 0)
        {
            Quit();
        }
        
        for(timer = 0; Screen->NumNPCs() > 0; timer += 1)
        {
            // Just wait
            Waitframe();
        }
        
        // All enemies are dead; calculate the bonus
        seconds = timer / 60; // time in frames / 60 = time in seconds
        bonus = 250 - (5 * seconds); // 250 rupees minus 5 per second
        Game->DCounter[CR_RUPEES] += Max(bonus, 0); // What happens without Max()?
    }
}
48. Displays one of two messages depending on whether Link has a certain item; the item ID and message numbers are script arguments.
ffc script ItemCheck
{
    void run(int itemID, int haveItemMsg, int lackItemMsg)
    {
        if(Link->Item[itemID])
            Screen->Message(haveItemMsg);
        else
            Screen->Message(lackItemMsg);
    }
}
49. Randomizes the HP of every enemy on screen.
item script EnemyHPRandomizer
{
    void run()
    {
        npc enemy;
        
        // This is a very common way of iterating over every enemy on the screen
        for(int counter = 1; counter <= Screen->NumNPCs(); counter++)
        {
            enemy = Screen->LoadNPC(counter);
            enemy->HP = Rand(1, 20);
        }
    }
}
50. Launches a fast-moving arrow in the same direction Link is facing.
item script Arrow
{
    void run()
    {
        lweapon arrow = Screen->CreateLWeapon(LW_ARROW);
        
        // Again, you can usually skip the validity check with CreateLWeapon(),
        // but it certainly doesn't hurt to make sure.
        if(!arrow->isValid())
        {
            Quit();
        }
        
        arrow->X = Link->X;
        arrow->Y = Link->Y;
        arrow->Dir = Link->Dir;
        arrow->Step = 500;
        arrow->Damage = 4;
        
        // Adjust the arrow's tile for the direction
        // Up is default, so it's skipped
        if(arrow->Dir == DIR_DOWN)
        {
            arrow->Flip = 2;
        }
        else if(arrow->Dir == DIR_LEFT)
        {
            arrow->Tile += 1;
            arrow->Flip = 1;
        }
        else if(arrow->Dir == DIR_RIGHT)
        {
            arrow->Tile += 1;
        }
    }
}
51. Makes the FFC follow Link around and removes any enemy weapons that get close to him. The FFC should be 2x2 tiles.

ffc script Barrier
{
    void run()
    {
        eweapon wpn;
        
        while(true)
        {
            this->X = Link->X - 8;
            this->Y = Link->Y - 8;
            
            // Cycle through every enemy weapon on the screen
            for(int counter = 1; counter <= Screen->NumEWeapons(); counter++)
            {
                wpn = Screen->LoadEWeapon(counter);
                
                if(Distance(Link->X, Link->Y, wpn->X, wpn->Y) < 20)
                {
                    wpn->DeadState = WDS_DEAD;
                }
            }
            
            Waitframe();
        }
    }
}
52. Spawns enemies on a screen at intervals, unless there are already too many on screen.
ffc script EnemySpawner
{
    void run(int enemyID, int interval, int maxEnemies)
    {
        npc enemy;
        
        if(interval <= 0) // Just in case
        {
            interval = 1;
        }
        
        while(true)
        {
            Waitframes(interval);
            
            if(Screen->NumNPCs() < maxEnemies)
            {
                enemy = Screen->CreateNPC(enemyID);
                if(enemy->isValid())
                {
                    enemy->X = this->X;
                    enemy->Y = this->Y;
                }
            }
        }
    }
}
53. Modified barrier script to protect an enemy, instead of Link.
ffc script Barrier
{
    void run()
    {
        npc enemy;
        lweapon wpn;
        
        // Rather than waiting four frames, you can wait until enemies appear
        while(Screen->NumNPCs() == 0)
        {
            Waitframe();
        }
        
        enemy = Screen->LoadNPC(1);
        
        while(IsAlive(enemy))
        {
            this->X = enemy->X - 8;
            this->Y = enemy->Y - 8;
            
            for(int counter = 1; counter <= Screen->NumLWeapons(); counter++)
            {
                wpn = Screen->LoadLWeapon(counter);
                
                if(Distance(enemy->X, enemy->Y, wpn->X, wpn->Y) < 20)
                {
                    wpn->DeadState = WDS_DEAD;
                }
            }
            
            Waitframe();
        }
        
        this->Data = 0;
    }
    
    bool IsAlive(npc en)
    {
        if(!en->isValid())
            return false;
        if(en->HP <= 0)
            return false;
        return true;
    }
}
54. Arrow weapon leaves behind fire when it disappears.
ffc script FireArrow
{
    void run()
    {
        int x;
        int y;
        lweapon arrow;
        lweapon fire;
        bool foundAnArrow=false;
        
        for(int counter = 1; counter <= Screen->NumLWeapons(); counter++)
        {
            arrow = Screen->LoadLWeapon(counter);
            if(arrow->ID == LW_ARROW)
            {
                foundAnArrow=true;
                break;
            }
        }
        
        if(!foundAnArrow)
            Quit();
        
        // Found an arrow; track its position until it becomes invalid
        while(arrow->isValid())
        {
            x = arrow->X;
            y = arrow->Y;
            Waitframe();
        }

        // The arrow isn't valid anymore; put a fire at its last known location
        fire = Screen->CreateLWeapon(LW_FIRE);
        if(fire->isValid())
        {
            fire->X = x;
            fire->Y = y;
            fire->Damage = 4;
            fire->Step = 0;
            Game->PlaySound(SFX_FIRE);
        }
    }
}
55. An item script to be added to a custom item's action script slot & works in conjunction with the previous script. It essentially will launch the FFC script when this item is used.
item script RunFireArrow
{
    void run()
    {
        ffc scriptRunner = Screen->LoadFFC(1);
        scriptRunner->Data = 1; // Combo 1 should be invisible
        scriptRunner->Script = 1;
    }
}
56. Creates four fireball weapons that circle around Link.
const int FB_RADIUS = 24;
const float FB_SPEED = 2.5;
const int FB_SPRITE = 17;
const int FB_DAMAGE = 2;

ffc script FireballBarrier
{
    void run()
    {
        lweapon fireballs[4];
        float baseAngle;
        float angle;
        
        // Each fireball will be recreated any time its pointer isn't valid,
        // so there's no reason to set them up in advance.
        
        for(baseAngle = 0; true; baseAngle = (baseAngle + FB_SPEED) % 360)
        {
            for(int index = 0; index < 4; index++)
            {
                if(!fireballs[index]->isValid())
                {
                    fireballs[index] = Screen->CreateLWeapon(LW_SCRIPT1);
                    fireballs[index]->UseSprite(FB_SPRITE);
                    fireballs[index]->Damage = FB_DAMAGE;
                }
                
                // Each fireball is offset by 90 degrees from the last one
                angle = baseAngle + 90 * index;
                fireballs[index]->X = Link->X + (FB_RADIUS * Cos(angle));
                fireballs[index]->Y = Link->Y + (FB_RADIUS * Sin(angle));
            }
            
            Waitframe();
        }
    }
}
57. Creates a simple snow effect
const int NUM_SNOWFLAKES = 80;
const int COLOR_WHITE = 1;

global script Snow
{
    void run()
    {
        int snowflakeX[80];  // X position of each snowflake
        int snowflakeY[80];  // Y position
        int snowflakeVx[80]; // X velocity
        int snowflakeVy[80]; // Y velocity
        
        // Randomize their positions and velocities
        for(int sf = 0; sf < NUM_SNOWFLAKES; sf++)
        {
            snowflakeX[sf] = Rand(256);
            snowflakeY[sf] = Rand(176);
            snowflakeVx[sf] = Randf(-0.2, 0.2);
            snowflakeVy[sf] = Randf(0.5, 1.0);
        }
        
        while(true)
        {
            // This is a very simple effect. Each snowflake moves in a straight line
            // and wraps around the edges of the screen.
            for(int sf = 0; sf < NUM_SNOWFLAKES; sf++)
            {
                snowflakeX[sf] += snowflakeVx[sf];
                snowflakeY[sf] += snowflakeVy[sf];
                
                if(snowflakeY[sf] > 175) // Fell off the bottom
                    snowflakeY[sf] = 0;
                
                if(snowflakeX[sf] < 0) // Off the left
                    snowflakeX[sf] = 255;
                else if(snowflakeX[sf] > 255) // Off the right
                    snowflakeX[sf] = 0;
                
                Screen->PutPixel(6, snowflakeX[sf], snowflakeY[sf], COLOR_WHITE, 0, 0, 0, OP_OPAQUE);
            }
            
            Waitframe();
        }
    }
}
58. Makes an enemy invincible until all others are killed first.
ffc script KillMeLast
{
    void run()
    {
        int storedDefenses[18];
        npc enemy;
        
        // Wait for enemies to appear
        while(Screen->NumNPCs() == 0)
        {
            Waitframe();
        }
        
        // Copy the enemy's defenses
        enemy = Screen->LoadNPC(1);
        for(int def = 0; def<18; def++)
        {
            storedDefenses[def] = enemy->Defense[def];
            enemy->Defense[def] = NPCDT_BLOCK;
        }
        
        // Wait for everything else to die
        while(Screen->NumNPCs() > 1)
        {
            Waitframe();
        }
        
        // And restore the defenses
        if(enemy->isValid()) // Just in case...
        {
            for(int def = 0; def<18; def++)
            {
                enemy->Defense[def] = storedDefenses[def];
            }
        }
    }
}
59. Find all instances of flag CF_SCRIPT1 on the screen. When every combo with that flag changes to a different one (watch Screen->ComboD[]), trigger secrets.
ffc script Flag98Secrets
{
    void run()
    {
        int flagLocations[16]; // For a maximum of 16 flags
        int flagCombos[16];
        int numFlags = 0;
        int location;
        bool allTriggered;
        
        // Find every instance of the flag on the screen and remember what combo
        // was there originally. numFlags is used as both a pointer and a counter.
        for(int index = 0; index < 176; index++)
        {
            if(Screen->ComboF[index] == CF_SCRIPT1 ||
               Screen->ComboI[index] == CF_SCRIPT1)
            {
                flagLocations[numFlags] = index;
                flagCombos[numFlags] = Screen->ComboD[index];
                numFlags++;
            }
        }
        
        // Wait for all the combos to change
        do
        {
            Waitframe();
            
            // allTriggered is set to true here; if any flag is found not to have
            // been triggered, it will be set back to false, making the loop continue
            allTriggered = true;
            
            for(int index = 0; index < numFlags; index++)
            {
                location = flagLocations[index];
                
                if(Screen->ComboD[location] == flagCombos[index])
                {
                    // This flag has not been triggered yet
                    allTriggered = false;
                    break; // No need to check the rest
                }
            }
        } while(!allTriggered);
        
        Screen->TriggerSecrets();
        Game->PlaySound(SFX_SECRET);
    }
}
60. Item Script changes the save file name to "THIEF" when the item is collected.
item script Shoplift
{
    void run()
    {
        int thiefStr[] = "THIEF";
        Game->SetSaveName(thiefStr);
    }
}
61. This function will play the given DMap's music. It will try to play enhanced music first; if that fails, it will play a MIDI instead.
void PlayDMapMusic(int dmap)
{
    int filename[256];
    int track;
    bool success;
    
    Game->GetDMapMusicFilename(dmap, filename);
    track = Game->GetDMapMusicTrack(dmap);
    
    success = Game->PlayEnhancedMusic(filename, track);
    if(!success)
    {
        Game->PlayMIDI(Game->DMapMIDI[dmap]);
    }
}
62. This script will set up an FFC to run the script named AnFFCScript.
item script RunScript
{
    void run()
    {
        int scriptName[] = "AnFFCScript";
        int scriptNum = Game->GetFFCScript(scriptName);
        ffc theFFC;
        
        if(scriptNum == -1) // No such script
        {
            Quit();
        }
        
        theFFC = Screen->LoadFFC(1);
        theFFC->Data = 1;
        theFFC->Script = scriptNum;
    }
}
63. Activates level 4 cheats if the save file's name is "Zelda". Make it case-insensitive.
global script ZeldaCheat
{
    void run()
    {
        int saveName[9];
        int zelda[] = "zelda";
        
        Game->GetSaveName(saveName);
        UpperToLower(saveName); // Convert to lower-case so it will match the lower-case string
        
        if(strcmp(saveName, zelda) == 0)
        {
            Game->Cheat = 4;
        }
    }
}
64. Displays "You got <itemname>!" on the screen whenever Link is holding up an item.
global script ItemMessage
{
    void run()
    {
        int itemMsgBuffer[80];
        int lastHeldItem = -1;
        
        while(true)
        {
            if(GetHeldItem() > -1)
            {
                if(Link->HeldItem != lastHeldItem)
                {
                    // Remember what item Link is holding; that way, the message
                    // only needs to be set up once when a new item is picked up
                    lastHeldItem = Link->HeldItem;
                    SetUpItemMessage(itemMsgBuffer, 80);
                }
                
                Screen->DrawString(6, 128, 48, FONT_Z1, 1, 0, TF_CENTERED, itemMsgBuffer, OP_OPAQUE);
            }
            Waitframe();
        }
    }
    
    void SetUpItemMessage(int buffer, int bufferSize)
    {
        int format[] = "You got %s!"; // "%s" substitutes a string
        int itemName[64];
        itemdata data;
        
        data = Game->LoadItemData(Link->HeldItem);
        data->GetName(itemName);
        
        // Make sure the buffer is empty!
        for(int index = 0; index < bufferSize; index++)
        {
            buffer[index] = 0;
        }
        
        sprintf(buffer, format, itemName);
    }
    
    int GetHeldItem()
    {
        // Make sure Link's holding up an item first;
        // just checking Link->HeldItem is unreliable.
        if(!(Link->Action == LA_HOLD1LAND || Link->Action == LA_HOLD2LAND ||
           Link->Action == LA_HOLD1WATER || Link->Action == LA_HOLD2WATER))
        {
            return -1;
        }
        
        return Link->HeldItem;
    }
}
65. Disables Link's collision detection if the screen flag "General Use 1 (Scripts)" is set. std.zh provides a function to check a single screen flag, but don't use it.
global script InvincibilityFlag
{
    void run()
    {
        int lastDMap = -1;
        int lastScreen = -1;
        
        while(true)
        {
            // Watch for the screen to change
            if(lastDMap != Game->GetCurDMap() ||
               lastScreen != Game->GetCurDMapScreen())
            {
                if((Screen->Flags[SF_MISC] & 100b) !=0)
                {
                    Link->CollDetection = false;
                }
                else
                {
                    Link->CollDetection = true;
                }
                
                lastDMap = Game->GetCurDMap();
                lastScreen = Game->GetCurDMapScreen();
            }
            
            Waitframe();
        }
    }
}
*FINISHED!*


  • a30502355 likes this

#2 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Gender:Male
  • Location:I wish I knew

Posted 08 August 2016 - 08:52 PM

Hmm instead of scripts I think posting just the methods would be more helpful to people trying to learn scripting because as you know a script is just an algorithm to preform a task, and most tasks are usually more complex than these.

 

Just my opinion. Otherwise nice to have.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users