Jump to content

Photo

ghost.zh


  • Please log in to reply
645 replies to this topic

#271 Saffith

Saffith

    IPv7 user

  • Members

Posted 10 April 2013 - 09:42 PM

QUOTE(LordVolcanon @ Apr 7 2013, 10:11 PM) View Post
Can we use Ghost_Waitframe() as the condition for the main loop of our autoghost enemies?

Sure.

QUOTE(Ebola Zaire @ Apr 10 2013, 09:59 PM) View Post
If I'm using SetEWeaponMovement() with EWM_THROW as the type, does setting arg1 to -1 account for the Z position of the projectile when the function is called? It's slightly off depending on Link's position, and I'm thinking that the starting Z value of 20 might be throwing it off.

Yeah, that'll throw it off. It's just a rough approximation. I'll see if I can improve it.

#272 Mitchfork

Mitchfork

    no fun. not ever.

  • Members
  • Real Name:Mitch
  • Location:Alabama

Posted 10 April 2013 - 10:10 PM

QUOTE(Saffith @ Apr 10 2013, 09:42 PM) View Post
Yeah, that'll throw it off. It's just a rough approximation. I'll see if I can improve it.
Cool. icon_thumbsup.gif I was playing with using 2D motion equations to find it but I couldn't get anything that was accurate enough.


#273 SpacemanDan

SpacemanDan

  • Members
  • Location:Ontario, Canada

Posted 12 April 2013 - 01:48 PM

So which misc variable handles if a weapon is blockable or not? I'm looking to check for it so I can make a sort of shield that will ignore weapons with the unblockable flag checked. Or is there an easier way of checking?

#274 Saffith

Saffith

    IPv7 user

  • Members

Posted 13 April 2013 - 08:20 AM

Check eweapon->Dir. If it's 0-7, it's blockable. If it's 8-15, it's not.

#275 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 16 April 2013 - 08:59 AM

QUOTE(ZoriaRPG @ Apr 7 2013, 06:50 AM) View Post

I have a global script and would also like to use GhostZHAcriveScript... Where can I insert the code from my global script so that it becomes part of GhostZHActiveScript?


This is my global script now; does anything here look horribly wrong for use with ghost.zh?

CODE

global script hpmpcounters{
    void run(){
    
        
        while(true)
        {
            Game->Counter[CR_SCRIPT2] = Link->HP;
            Game->Counter[CR_SCRIPT3] = Link->MP;
Game->Counter[CR_SCRIPT4] = Link->MaxHP;
Game->Counter[CR_SCRIPT5] = Link->MaxMP;
UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();
            
            AutoGhost();
            DrawGhostFFCs();
{
        if (Link->Item[231] == true) //If Link has the fake item designated in D0
        {
           Link->Item[230] = false; //Removes the fake item user selects in D0
           Link->Item[231] = false; //Removes the item the user selects in in D1  
        Link->MP += 256; //Increases MP by value of D3
        Link->MaxMP += 256; //Increases Max MP by value of D2
        }
        else (Link->Item[230] == true); //Gives Link the specified item in D4.{
        
            Waitframe();
        }



float angle;
      {
      if (usebombodo == 1)
      {            
      slower ++;
      if (slower == 5)
      {  
      rad++;
      slower = 0;
      }  
      angle = (angle + ORBIT_SPEED) % 360;          
      f1 = 100 + rad * Cos(angle);
      f2 = 100 + rad * Sin(angle);
      Screen->FastCombo(6, f1, f2, 80, 2, 128);
        
      r1 = 40+Rand(150);
      r2 = 40+Rand(100);
            
      slowera++;
      if (slowera  == 20)
         {
            slowera = 0;
            if (bombs < 30)
            {
            bombs ++;  
            lweapon bomb = CreateLWeaponAt(LW_BOMBBLAST, r1, r2);
            Game->PlaySound(SFX_BOMB);
            if (bombs == 30) usebombodo = 0;
            }
         }
      }
      
      Waitframe();
      
      }
       if ( ringOn && Link->MP ){                
                //Decrement magic
                ringTimer = (ringTimer+1) % ringTimePerMP;
                if ( !ringTimer ) Link->MP--;
                
                if ( Link->MP <= 0 //If magic ran out
                || Link->Action == LA_SCROLLING //Or left screen
                ){ //Take off ring
                    ringOn = false;
                    Link->CollDetection = true;
                    Link->Invisible = false;
                }

            }
            else if ( !ringOn ){ //Disable ring
                Link->CollDetection = true;
                Link->Invisible = false;
            }
}
}
}


Something in ghost.zh is draining the magic counter when I enable it. I tried disabling both strings.zh and ghost.zh and the counters were fine. then, I enabled strings.zh and the counters were fine.

It is only after I add the ghost.zh entry and the ghost.zh global stuff that the counter drains, at a rate of 1 per frame.

As soon as I use an item that drains magic (e.g. item script cane; item script OneRing) the drain stops. Using the item causes its intended drain, and when I stop using it, the drain ends as normal, but when I load the quest it begins draining MP without using any of these items. Am I missing a Waitframe() somewhere?

Edited by ZoriaRPG, 16 April 2013 - 09:30 AM.


#276 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 16 April 2013 - 10:09 AM

(Double-posting due to scripts exceeding maximum post length.)

Here is my working script (without ghost.zh, file GoldenCenotaph47.z)

CODE

import "std.zh"
import "ffcscript.zh"
import "string.zh"
//import "ghost.zh"
int Drinks_Left;
const int SFX_DRINK = 52;
const int LW_EFFECT = 31;

//const int SFX_ERROR = 0; //In case you want an error SFX

const int SFX_MAGICCHARGE = 53;
const int SFX_LIGHTARROW = 1;
const int lightColor = 134; //Color of the charging ring: CSet# * 16 + color# (from 0 to 15)
const int WPS_NONE = 101; //Weapon sprite with an empty tile (for superlight arrow)
const float ORBIT_SPEED = 2.5;
const float ORBIT_RADIUS = 48;

int f1 = 0;
int f2 = 0;
int rad = 0;
int slower = 0;
int bombs = 0;
int r1 = 0;
int r2 = 0;
int slowera = 0;
int ffcslot = 1;
int usebombodo = 0;
const int ringTimePerMP = 15; //How many frames 1 unit of MP lasts with the One Ring
const int ringShadowTile = 0; //Shadow tile for invisble Link
const int ringShadowCSet = 7; //CSet of this tile
bool ringOn;
int ringTimer;

const int DRAW_OPAQUE = 128;
const int DRAW_TRANSPARENT = 64;

global script hpmpcounters{
    void run(){
    
        
        while(true)
        {
            Game->Counter[CR_SCRIPT2] = Link->HP;
            Game->Counter[CR_SCRIPT3] = Link->MP;
Game->Counter[CR_SCRIPT4] = Link->MaxHP;
Game->Counter[CR_SCRIPT5] = Link->MaxMP;
{
        if (Link->Item[231] == true) //If Link has the fake item designated in D0
        {
           Link->Item[230] = false; //Removes the fake item user selects in D0
           Link->Item[231] = false; //Removes the item the user selects in in D1  
        Link->MP += 256; //Increases MP by value of D3
        Link->MaxMP += 256; //Increases Max MP by value of D2
        }
        else (Link->Item[230] == true); //Gives Link the specified item in D4.{
        
            Waitframe();
        }



float angle;
      {
      if (usebombodo == 1)
      {            
      slower ++;
      if (slower == 5)
      {  
      rad++;
      slower = 0;
      }  
      angle = (angle + ORBIT_SPEED) % 360;          
      f1 = 100 + rad * Cos(angle);
      f2 = 100 + rad * Sin(angle);
      Screen->FastCombo(6, f1, f2, 80, 2, 128);
        
      r1 = 40+Rand(150);
      r2 = 40+Rand(100);
            
      slowera++;
      if (slowera  == 20)
         {
            slowera = 0;
            if (bombs < 30)
            {
            bombs ++;  
            lweapon bomb = CreateLWeaponAt(LW_BOMBBLAST, r1, r2);
            Game->PlaySound(SFX_BOMB);
            if (bombs == 30) usebombodo = 0;
            }
         }
      }
      
      Waitframe();
      
      }
       if ( ringOn && Link->MP ){                
                //Decrement magic
                ringTimer = (ringTimer+1) % ringTimePerMP;
                if ( !ringTimer ) Link->MP--;
                
                if ( Link->MP <= 0 //If magic ran out
                || Link->Action == LA_SCROLLING //Or left screen
                ){ //Take off ring
                    ringOn = false;
                    Link->CollDetection = true;
                    Link->Invisible = false;
                }

            }
            else if ( !ringOn ){ //Disable ring
                Link->CollDetection = true;
                Link->Invisible = false;
            }
}
}
}

//Enemies thqat break the hpmpcountrs script are Green Dragon Moldorm 10 Moldorm 20 digdogger Kid and BS Dodongo



//Item power: Same scale as any other item's damage stat
//D0: Time (in frames) to charge the arrow (Recommended: 25)
//D1: Weap/Misc sprite to use (34 is golden arrow sprite)
//D2: Magic required (expended as you start charging) (8)
//D3: Speed of the arrow (same scale as enemy step speed) (500 for normal; 2500 for super)
//D4: # of the FFC script (check as you assign it to a slot)
item script lightArrow{
    void run(int chargeTime, int arrowSprite, int magicCost, int speed, int ffcScriptNum){
        if ( Game->Counter[CR_MAGIC] < magicCost || !Game->Counter[CR_ARROWS] ){
            Game->PlaySound(SFX_ERROR);     //Comment out to remove error SFX
            return;
        }
        if(CountFFCsRunning(ffcScriptNum) == 0){
            int args[4] = {this->Power*2, chargeTime, arrowSprite, speed};
            Game->Counter[CR_MAGIC] -= magicCost;
            RunFFCScript(ffcScriptNum, args);
        }
    }
}

ffc script lightArrowFFC{
    void run(int power, int chargeTime, int arrowSprite, int speed){
        int startHP = Link->HP;
        lweapon lArrow;
        Game->PlaySound(SFX_MAGICCHARGE);
        for(int i = chargeTime; i > 0; i--){ //Charge duration
            NoAction(); //Freeze Link
            //Display charging animation: gold circle (non-filled) appears and shrinks (radius)
            Screen->Circle ( 7, Link->X+8, Link->Y+8, 20*i/chargeTime, lightColor, 1, 0, 0, 0, false, 64 );
            if ( Link->HP < startHP )
                return; //If Link is hurt, quit
            Waitframe();
        }
        
        //Charging done! Shoot that arrow!
        Link->Action = LA_ATTACKING;
        Game->Counter[CR_ARROWS]--;
        Game->PlaySound(SFX_LIGHTARROW);
        lArrow = NextToLink(LW_ARROW, 8);                        //Create in front of Link
        lArrow->UseSprite(arrowSprite);                            //Graphics
        lArrow->Damage = power;                                    //Damage
        lArrow->Step = speed;                                    //Speed
        if ( Link->Dir == DIR_DOWN ){                            //Sprite selection/rotation
            lArrow->Flip = 3;
        }
        else if ( Link->Dir == DIR_LEFT ){
            lArrow->Tile++;
            lArrow->Flip = 1;
        }
        else if ( Link->Dir == DIR_RIGHT ){
            lArrow->Tile++;
        }
    }
}

ffc script superLightArrowFFC{
    void run(int power, int chargeTime, int arrowSprite, int speed){
        int startX;
        int startY;
        int startHP = Link->HP;
        lweapon lArrow;
        Game->PlaySound(SFX_MAGICCHARGE);
        for(int i = chargeTime; i > 0; i--){ //Charge duration
            NoAction(); //Freeze Link
            //Display charging animation: random lines from Link of random length
            for ( int j = 0; j < 5; j++ ){
                int angle = Rand(360);
                Screen->Arc(7, Link->X+8, Link->Y+8, Rand(50)+1, angle, angle+1, lightColor, 1, 0, 0, 0, true, false, 128);
            }
            if ( Link->HP < startHP )
                return; //If Link is hurt, quit
            Waitframe();
        }
        
        //Charging done! Shoot that arrow!
        startX = Link->X+8;
        startY = Link->Y+8;
        Link->Action = LA_ATTACKING;
        Game->Counter[CR_ARROWS]--;
        Game->PlaySound(SFX_LIGHTARROW);
        lArrow = NextToLink(LW_ARROW, 8);                        //Create in front of Link
        lArrow->UseSprite(WPS_NONE);                            //Graphics (invisible)
        lArrow->Damage = power;                                    //Damage
        lArrow->Step = speed;                                    //Speed
        
        for ( int i = 0; i < 30; i++ ){ //For 30 frames
            Screen->Line(4, startX, startY, lArrow->X+8, lArrow->Y+8, lightColor, 1, 0, 0, 0, 128); //Draw a line from Link to the arrow
            lArrow->DeadState = WDS_ALIVE; //Keep it alive at all times
            Waitframe();
        }
        lArrow->DeadState = WDS_DEAD;
    }
}



//Usable Clock (Or other things??)
//D0 - Item to use for clock.(or whatever) If doing clock, this needs to be a clock item with duration set.
//Note: The default clock item is 4.
//D1 - Amount of time to Jinx link. (0 for no Jinx)
//Note: The Jinx can be used to create a small pause before the item
//can be used again. You can also make it the clock duration, but this
//is only recommended in quests that aren't using the B+A item setting
//configuration.

item script usedclock{

void run(int clockitem, int jinxtime){

item givenclock = Screen->CreateItem(4);
givenclock->X = Link->X;
givenclock->Y = Link->Y;
givenclock->Z = Link->Z;
Link->ItemJinx = 2;


}

}


//Timestop Scroll
item script timestopscroll{
void run(int clockitem, int jinxtime){
if (Game->Counter[CR_SCRIPT1] >= 1){
Game->Counter[CR_SCRIPT1] -= 1;
item givenclock = Screen->CreateItem(4);
givenclock->X = Link->X;
givenclock->Y = Link->Y;
givenclock->Z = Link->Z;
Link->ItemJinx = 2;
}
    else{
    Game->PlaySound(errorsfx);
    }

}

}

//Script above works, but item vanishes from in entory on 1st use; counter remains intact. How do I keep it in inventory?


//Magical Key
//D0 - Item to use for clock.(or whatever) If doing clock, this needs to be a clock item with duration set.
//Note: The default clock item is 4.
//D1 - Amount of time to Jinx link. (0 for no Jinx)
//Note: The Jinx can be used to create a small pause before the item
//can be used again. You can also make it the clock duration, but this
//is only recommended in quests that aren't using the B+A item setting
//configuration.

item script magicalkey{

void run(int keyitem, int jinxtime){

item givenkey = Screen->CreateItem(9);
givenkey->X = Link->X;
givenkey->Y = Link->Y;
givenkey->Z = Link->Z;
Link->ItemJinx = 0;



}


}

int healsfx = 39; //Sound effect to play when Link is healed
int errorsfx = 65; //Sound effect to play when Link's HP is full or MP is empty

item script heal6heart{
  void run(int m, int h){
    if(Link->MP >= m && Link->HP < Link->MaxHP){
        Link->HP += 96;
        Link->MP -= 64;
        Game->PlaySound(39);
    }
    else{
    Game->PlaySound(errorsfx);
    }
    
  }
}


item script heal12heart{
  void run(int m, int h){
    if(Link->MP >= m && Link->HP < Link->MaxHP){
        Link->HP += 196;
        Link->MP -= 200;
        Game->PlaySound(39);
    }
    else{
    Game->PlaySound(errorsfx);
    }
    
  }
}



item script restoremagic{
  void run(int m, int h){
    if(Link->HP >= m && Link->MP < Link->MaxMP){
        Link->HP += 0;
        Link->MP += 200;
        Game->PlaySound(healsfx);
    }
    else{
    Game->PlaySound(errorsfx);
    }
    
  }
}

//D0 = Rupeegain

ffc script GetRupees{
    void run(int rup){
    Game->Counter[CR_RUPEES]+rup;
    }
}


//Rupee Loss - Jinx

ffc script LoseRupees{
    void run(int rup){
    Game->Counter[CR_RUPEES]-rup;
    }
}


//Mirror Teleporter Script


const int SFX_MIRROR = 62; //Sound on successful warp
const int SFX_ERROR = 61; //SFX number of an error sound
const int CMB_AUTOWARPA = 0; //Transparent combo with "Auto Side Warp A" combo type

item script mirror{
    void run (){
        int targetDMap; //DMap to warp to
        int targetMap; //Map (not DMap) to warp to
        if (Game->GetCurDMap() == 1){ //First possible DMap
            targetDMap = 1; //Sample origin/destination DMap change
            targetMap = 2;
        }
        else if (Game->GetCurDMap() == 2){ //Second DMap
            targetDMap = 0; //All other ones start with "else"
            targetMap = 1;
        }
        else{ //Invalid DMap
            Game->PlaySound(SFX_ERROR);
            return;
        }
        if ( Game->GetComboSolid(targetMap, Game->GetCurScreen(), ComboAt(Link->X+8,Link->Y+8)) ){
            Game->PlaySound(SFX_ERROR);
            return;
        }
        Game->PlaySound(SFX_MIRROR);
        Screen->SetSideWarp(0, Game->GetCurDMapScreen(), targetDMap, WT_IWARPWAVE);
        Screen->ComboD[0] = CMB_AUTOWARPA; //Trigger the warp
    }
}

// //Timestop Scroll Item

//const int CR_TSCROLL = 0;

//Game->Counter(CR_TSCROLL) == 0;

//bool CanPickupTScroll
//{
//    return(Game->Counter(CR_TSCROLL) = < 255)
//}


item script pickupsernaran{

void run(int m){

item givenitem = Screen->CreateItem(143);
givenitem->X = Link->X;
givenitem->Y = Link->Y;
givenitem->Z = Link->Z;

}
}


//item script increaseMaximumDCounterCount
//{
//void run(int increaseitem1, int increaseItemAmount1, int valueid, int increaseItemAmount2)
//{
//if (Link->Item[(increaseitem1)] == 1)
//{
//  Game->MCounter[valueid] = increaseItemAmount1;
//Game->Counter[valueid] += 1;   //Adds +1 to the same counter. Avoids need to setup counter info for item.
//}
//}
//}


item script increaseMaximumDCounterCount
{
void run(int increaseitem1, int increaseItemAmount1, int valueid, int increaseItemAmount2)
{
if (Link->Item[(increaseitem1)] == 1)
{
  Game->MCounter[valueid] = increaseItemAmount1;
}
}
}






item script mcp2{
void run(int m){
Link->Item[230] = false;
item givenitem = Screen->CreateItem(58);
givenitem->X = Link->X;
givenitem->Y = Link->Y;
givenitem->Z = Link->Z;


}
}

////D0:Is the fake item you pick up
////D1:Is the item that will disapear
////D2:Is the amount of Max MP gained
////D3:Is the amount of MP refill
////D4:Is item given if D0 is not in inventory.

//ffc script MCP3{
//    void run(int i, int j, int k, int mg, int mx)
//    {
//       while(true)
//       {
//        if (Link->Item[i] == true) //If Link has the fake item designated in D0
//        {
//           Link->Item[i] = false; //Removes the fake item user selects in D0
//           Link->Item[j] = false; //Removes the item the user selects in in D1  
//        Link->MP[mg]; //Increases MP by value of D3
//        Link->MaxMP[mx]; //Increases Max MP by value of D2
//        }
//        else (Link->Item[k] == true); //Gives Link the specified item in D4.{
//       Waitframe();
//       }
//    }
//}

//D0:Is the fake item you pick up
//D1:Is the item that will disapear
//D2:Is the amount of Max MP gained
//D3:Is the amount of MP refill
//D4:Is item given if D0 is not in inventory.

ffc script MCP4{
    void run(int i, int j, int k, int mg, int mx)
    {
       while(true)
       {
        if (Link->Item[i] == true) //If Link has the fake item designated in D0
        {
           Link->Item[i] = false; //Removes the fake item user selects in D0
           Link->Item[j] = false; //Removes the item the user selects in in D1  
        Link->MP += 256; //Increases MP by value of D3
        Link->MaxMP += 256; //Increases Max MP by value of D2
        }
        else (Link->Item[k] == true); //Gives Link the specified item in D4.{
       Waitframe();
       }
    }
}


//D0:Is the fake item you pick up
//D1:Is the item that will disapear
//D2:Is the amount of Max MP gained
//D3:Is the amount of MP refill
//D4:Is item given if D0 is not in inventory.

item script MCP4I{
    void run(int i, int j, int k, int mg, int mx)
    {
       while(true)
       {
        if (Link->Item[i] == true) //If Link has the fake item designated in D0
        {
           Link->Item[i] = false; //Removes the fake item user selects in D0
           Link->Item[j] = false; //Removes the item the user selects in in D1  
        Link->MP += 256; //Increases MP by value of D3
        Link->MaxMP += 256; //Increases Max MP by value of D2
        }
        else (Link->Item[k] == true); //Gives Link the specified item in D4.{
       Waitframe();
       }
    }
}

item script lon_lon_milk_pickup

{
   void run()
      {
         Drinks_Left = 3;
      }
}

item script lon_lon_milk

{
   void run()
      {
         Link->HP += 80;  //Link regains 5 hearts
         Game->PlaySound(56); //Play SFX when used.

         if(Link->HP >= Link->MaxHP)  //If Link has too much HP
            {
               Link->HP = Link->MaxHP;  //It's brought down to the maximum
            }

         Drinks_Left -= 1;  //Link loses 1 serving of milk

         if(Drinks_Left == 0)  //If Link is out of milk
            {
               Link->Item[123] = false;  //The item is gone
            }
      }
}

item script Bombos_Item{
    void run(int ffcScriptNum, int comboNum, int flameNum, float speed, float radius, int explosionNum, int explosionSpread, int explosionDamage){
        float args[8] = {comboNum, flameNum, speed, radius, explosionNum, explosionSpread, explosionDamage};
        RunFFCScript(ffcScriptNum, args);
    }
}

ffc script Bombos_Action{
    void run(int comboNum, int flameNum, float speed, float radius, int explosionNum, int explosionSpread, int explosionDamage){
        Link->CollDetection = false;
        Link->Invisible = true;
        this->X = Link->X - 16;
        this->Y = Link->Y - 16;
        this->TileWidth = 3;
        this->TileHeight = 3;
        this->CSet = 6;
        this->Data = comboNum;
        //Wait till the animation finishes before starting
        while(this->Data == comboNum){
            WaitNoAction();
        }
        lweapon flame[16];
        float angle[16];
        float radiusInternal = radius;
        for(int i; i < flameNum; i++){
            flame[i] = Screen->CreateLWeapon(LW_EFFECT);
            angle[i] = (360/flameNum)*i;
            flame[i]->UseSprite(35);
            flame[i]->CollDetection = false;
            flame[i]->X = Link->X + radiusInternal*Cos(angle[i]*speed);
            flame[i]->Y = Link->Y + radiusInternal*Sin(angle[i]*speed);
        }
        int timer = 120;
        while(timer > 0){
            for(int i; i < flameNum; i++){
                flame[i]->X = Link->X + radiusInternal*Cos(angle[i]*speed);
                flame[i]->Y = Link->Y + radiusInternal*Sin(angle[i]*speed);
                angle[i] %= 360;
                angle[i]++;
            }
            timer--;
            radiusInternal = radius*(timer/120);
            WaitNoAction();
        }
        for(int i; i < flameNum; i++) flame[i]->DeadState = WDS_DEAD;
        while(explosionNum > 0){
            explosionNum--;
            int x;
            int y;
            while(true){
                x = Rand(Link->X - radius, Link->X + radius);
                y = Rand(Link->Y - radius, Link->Y + radius);
                if(Distance(Link->X, Link->Y, x, y) <= radius) break;
            }
            lweapon l = CreateLWeaponAt(LW_BOMBBLAST, x, y);
            l->Damage = explosionDamage;
            Game->PlaySound(SFX_BOMB);
            WaitNoAction(explosionSpread);
        }
        this->Data = 0;
        timer = 16;
        while(timer > 0){
           timer--;
           WaitNoAction();
        }
        this->TileWidth = 1;
        this->TileHeight = 1;
        Link->CollDetection = false;
        Link->Invisible = false;
    }
}



item script tremor
{        
   void run()
   {
Screen->Quake = 20;
Screen->Wavy = 10;
Waitframes(4);
npc enemys;
   for(int i = 1; i<=Screen->NumNPCs(); i++)
         {
         enemys = Screen->LoadNPC(i);
         enemys->HP-=10;
         }
   }
}

item script bombodositem
{        
   void run()
   {
   bombs = 0;
   slower = 0;
   slowera = 0;
   rad = 0;
   usebombodo = 1;
   npc enemys;
   for(int i = 1; i<=Screen->NumNPCs(); i++)
         {
         enemys = Screen->LoadNPC(i);
         enemys->HP-=1;
         }
   }
}

item script theOneRing{
    void run(int onSFX, int offSFX){
        if ( !ringOn && Link->MP > 0 ){
            ringOn = true;
            Game->PlaySound(56);
            
            Link->CollDetection = false;
            Link->Invisible = true;
        }
        else if ( ringOn ){
            ringOn = false;
            Game->PlaySound(offSFX);
        }
    }
}

item script cane{
    void run(int onSFX, int offSFX){
        if ( !ringOn && Link->MP > 0 ){
            ringOn = true;
            Game->PlaySound(onSFX);          
            Link->CollDetection = true;
            Link->Invisible = false;
        }
        else if ( ringOn ){
            ringOn = false;
            Game->PlaySound(offSFX);
        }
    }
}

//Beamos Script
//fires a laser at Link when he comes within a certain range.
//Only the burning tip will hurt link.
//D0: the radius, in pixels, of the beamos's range
//D1: the time, in frames, it takes for the beamos to activate its laser before it fires
//D2: how far, in pixels, the beam tip can travel in a frame
//D3: the color of the beam
//D4: the weapon used for the beam's tip
//D5: the amount of damage the tip does
//D6: sound to be played when it detects Link
//D7: beam sound effect. looped every 4 frames.
ffc script Beamos{
    void run(int range, int delay, float beamspeed, int beamcolor, int beamwpn, int damage, int alert_sfx, int beam_sfx) {
        float sx; float sy;
        int counter;
        eweapon wpn;
        while(true) {
            if(Distance(this->X, this->Y, Link->X, Link->Y) <= range) {
                sx = Link->X;
                sy = Link->Y;
                if(alert_sfx)
                    Game->PlaySound(alert_sfx);
                Waitframes(delay);
                wpn = Screen->CreateEWeapon(EW_SCRIPT1);
                wpn->X = sx;
                wpn->Y = sy;
                wpn->UseSprite(beamwpn);
                wpn->Damage = damage;
                while(Distance(this->X, this->Y, Link->X, Link->Y) <= range && wpn->isValid()) {
                    float angle = ArcTan(Link->X - wpn->X, Link->Y - wpn->Y);
                    wpn->Dir = AngleToDir(ArcTan(wpn->X - this->X, this->Y - wpn->Y));
                    sx += beamspeed * RadianCos(angle);
                    sy += beamspeed * RadianSin(angle);
                    wpn->X = sx;
                    wpn->Y = sy;
                    Screen->Line(3, wpn->X+7, wpn->Y+7, this->X+7, this->Y+7,
                                 beamcolor, 1, 0, 0, 0, 128);
                    if(beam_sfx && counter == 0)
                        Game->PlaySound(beam_sfx);
                    counter = (counter + 1) % 4;
                    Waitframe();
                }
                wpn->DeadState = WDS_DEAD;
            }
            
            Waitframe();
        }
    }
}

int AngleToDir(float angle) {
    float deg = angle * 180 / PI;
    if(deg >= 0) {
        if(deg < 90) {
            if(deg < 45)
                return DIR_RIGHT;
            else
                return DIR_RIGHTUP;
        }
        else {
            if(deg < 135)
                return DIR_UP;
            else
                return DIR_LEFTUP;
        }
    }
    else {
        if(deg >= -90) {
            if(deg >= -45)
                return DIR_RIGHTDOWN;
            else
                return DIR_DOWN;
        }
        else {
            if(deg >= -135)
                return DIR_LEFTDOWN;
            else if(deg < -180)
                return DIR_LEFT;
            else
                return DIR_LEFTUP;
        }
    }
}

////


//D0: Time (in frames) to charge the arrow (Recommended: 25)
//D1: Weap/Misc sprite to use (34 is golden arrow sprite)
//D2: Magic required (expended as you start charging) (8)
//D3: Speed of the arrow (same scale as enemy step speed) (500 for normal; 2500 for super)
//D4: # of the FFC script (check as you assign it to a slot)
item script bolt{
    void run(int chargeTime, int arrowSprite, int magicCost, int speed, int ffcScriptNum){
     Screen->Wavy = 10;
Waitframes(4);
npc enemys;
   for(int i = 1; i<=Screen->NumNPCs(); i++)
         {
         enemys = Screen->LoadNPC(i);
         enemys->HP-=10;
         }
        if ( Game->Counter[CR_MAGIC] < magicCost || !Game->Counter[CR_ARROWS] ){
            Game->PlaySound(SFX_ERROR);     //Comment out to remove error SFX
            return;
        }
        if(CountFFCsRunning(ffcScriptNum) == 0){
            int args[4] = {this->Power*2, chargeTime, arrowSprite, speed};
            Game->Counter[CR_MAGIC] -= magicCost;
            RunFFCScript(ffcScriptNum, args);
        }
    }
}





/////






    


  


ffc script boltFFC{
    void run(int power, int chargeTime, int arrowSprite, int speed){
        int startX;
        int startY;
        int startHP = Link->HP;
        lweapon lArrow;
        Game->PlaySound(SFX_MAGICCHARGE);
        for(int i = chargeTime; i > 0; i--){ //Charge duration
            NoAction(); //Freeze Link
            //Display charging animation: random lines from Link of random length
            for ( int j = 0; j < 5; j++ ){
                int angle = Rand(360);
                Screen->Arc(7, Link->X+8, Link->Y+8, Rand(50)+1, angle, angle+1, lightColor, 1, 0, 0, 0, true, false, 128);
            }
            if ( Link->HP < startHP )
                return; //If Link is hurt, quit
            Waitframe();
        }
        
        //Charging done! Shoot that arrow!
        startX = Link->X+8;
        startY = Link->Y+8;
        Link->Action = LA_ATTACKING;
        Game->PlaySound(SFX_LIGHTARROW);
        lArrow = NextToLink(LW_ARROW, 8);                        //Create in front of Link
        lArrow->UseSprite(WPS_NONE);                            //Graphics (invisible)
        lArrow->Damage = power;                                    //Damage
        lArrow->Step = speed;                                    //Speed
        
        for ( int i = 0; i < 30; i++ ){ //For 30 frames
            Screen->Line(4, startX, startY, lArrow->X+8, lArrow->Y+8, lightColor, 1, 0, 0, 0, 128); //Draw a line from Link to the arrow
            lArrow->DeadState = WDS_ALIVE; //Keep it alive at all times
            Waitframe();
        }
        lArrow->DeadState = WDS_DEAD;
    }
}


#277 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 16 April 2013 - 12:00 PM

Could you possibly add an eweapon lifespan "EWL_NORMAL" for when the weapon is going to be deleted internally next frame. I believe that might be the best way to allow for death effects to trigger when the weapon is removed normally such as by a Block All combo.

Edited by LordVolcanon, 16 April 2013 - 12:06 PM.


#278 Saffith

Saffith

    IPv7 user

  • Members

Posted 16 April 2013 - 11:07 PM

QUOTE(ZoriaRPG @ Apr 16 2013, 09:59 AM) View Post
Something in ghost.zh is draining the magic counter when I enable it. I tried disabling both strings.zh and ghost.zh and the counters were fine. then, I enabled strings.zh and the counters were fine.

It is only after I add the ghost.zh entry and the ghost.zh global stuff that the counter drains, at a rate of 1 per frame.

As soon as I use an item that drains magic (e.g. item script cane; item script OneRing) the drain stops. Using the item causes its intended drain, and when I stop using it, the drain ends as normal, but when I load the quest it begins draining MP without using any of these items. Am I missing a Waitframe() somewhere?

It's hard to tell what's going on there, honestly, but something's definitely wrong. You've got two Waitframes, and there should only be one. When you combine global scripts, you generally want to divide them into two or three sections:
CODE
global script ActiveScript
{
    void run()
    {
        // Before loop
        while(true)
        {
            // Before Waitdraw
            Waitdraw();
            // After Waitdraw (only if Waitdraw is present)
            Waitframe();
        }
    }
}

You want to combine all the pre-loop, pre-Waitdraw, and post-Waitdraw parts individually. It's almost never okay to have multiple Waitframes or Waitdraws in the global script.

QUOTE(LordVolcanon @ Apr 16 2013, 01:00 PM) View Post
Could you possibly add an eweapon lifespan "EWL_NORMAL" for when the weapon is going to be deleted internally next frame. I believe that might be the best way to allow for death effects to trigger when the weapon is removed normally such as by a Block All combo.

Maybe. There are a couple of ways it could be done, but I don't like any I can think of. You can't detect when a weapon will be deleted, so, one way or another, this would involve tracking.

#279 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 20 April 2013 - 10:31 AM

I figured out why AutoGhost was conflicting with the other scripts. Bottom line: When you add ghost.zh, start a new .sav file.

That would have saved me days of messing with my global script.

#280 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 21 April 2013 - 09:01 PM

edit: See next post for up to date version.

Edited by LordVolcanon, 24 April 2013 - 10:51 AM.


#281 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 23 April 2013 - 06:27 PM

Think I finally got it working Saffith, let me know if you run into any problems. :)

bool DeadEWeapon(eweapon wpn)
{
    //Get it's step speed.
    float xstep;
    float ystep;
    if(wpn->Angular)
    {
        xstep = VectorX(wpn->Step/100, RadtoDeg(wpn->Angle));
        ystep = VectorY(wpn->Step/100, RadtoDeg(wpn->Angle));
    }
    else if(wpn->Dir != -1);
    {
        int dir = __NormalizeDir(wpn->Dir);
        float step = wpn->Step/100;
        if(dir == DIR_UP) ystep = -step;
        else if(dir == DIR_DOWN) ystep = step;
        else if(dir == DIR_LEFT) xstep = -step;
        else if(dir == DIR_RIGHT) xstep = step;
        else
        {
            if(dir==DIR_LEFTUP || dir==DIR_LEFTDOWN) xstep = -step * 0.7071;
            else if(dir==DIR_RIGHTUP || dir==DIR_RIGHTDOWN) xstep = step * 0.7071;
            if(dir==DIR_LEFTUP || dir==DIR_RIGHTUP) ystep = -step * 0.7071;
            else if(dir==DIR_LEFTDOWN || dir==DIR_RIGHTDOWN) ystep = step * 0.7071;
        }
    }

    //Set a flag if it collided with link.
    bool linkhit;
    if(Abs(Link->X+8 - HitboxLeft(wpn) - (wpn->HitWidth/2) - xstep) <= 8 &&
       Abs(Link->Y+8 - HitboxTop(wpn) - (wpn->HitHeight/2) - ystep) <= <img src='http://www.purezc.com/forums/public/style_emoticons/<#EMO_DIR#>/icon_cool.gif' class='bbc_emoticon' alt='8)' /> linkhit = true;

    //Set a flag if it will move off screen.
    bool offscreen;
    if(wpn->X + xstep != Clamp(wpn->X+xstep, 0, 240) || wpn->Y + ystep != Clamp(wpn->Y+ystep, 0, 160))
    {
       wpn->X = Clamp(wpn->X+xstep, 0, 240);
       wpn->Y = Clamp(wpn->Y+ystep, 0, 160);
       wpn->Step = 0;
       offscreen = true;
    }

    //Set a flag if it collided with a solid combo.
    bool impact;
    if(wpn->ID == EW_ROCK || wpn->Misc[__EWI_LIFESPAN_ARG] != 0)
    {
        int imprecision = wpn->Misc[__EWI_LIFESPAN_ARG];
        int edgeStart;
        int edgeEnd;

        if(xstep != 0)
        {
            float x = wpn->X + wpn->HitXOffset + imprecision;
            if(xstep > 0) x += wpn->HitWidth - Max(1, imprecision);
            int edgeStart = wpn->Y + wpn->HitYOffset + imprecision;
            int edgeEnd = edgeStart + wpn->HitHeight - imprecision;
            for(int i = edgeStart; !impact && i < edgeEnd; i+=<img src='http://www.purezc.com/forums/public/style_emoticons/<#EMO_DIR#>/icon_cool.gif' class='bbc_emoticon' alt='8)' />
                impact = Screen->isSolid(x, i);
            if(!impact) impact = Screen->isSolid(x, edgeEnd - 1);
        }
        if(ystep != 0)
        {
            float y = wpn->Y + wpn->HitYOffset + imprecision;
            if(ystep > 0) y += wpn->HitHeight - Max(1, imprecision);
            int edgeStart = wpn->X + wpn->HitXOffset + imprecision;
            int edgeEnd = edgeStart + wpn->HitWidth - imprecision;
            for(int i = edgeStart; !impact && i < edgeEnd; i+=<img src='http://www.purezc.com/forums/public/style_emoticons/<#EMO_DIR#>/icon_cool.gif' class='bbc_emoticon' alt='8)' />
                impact = Screen->isSolid(i, y);
            if(!impact) impact = Screen->isSolid(edgeEnd - 1, y);
        }
    }

    if(wpn->DeadState == WDS_DEAD)    //Deadstate?
        return true;
    else if(linkhit)                  //Link collision?
        return true;
    else if(offscreen)                //Moved offscreen?
        return true;
    else if(impact)                   //Combo collision?
        return true;
    else                              //Should still be alive, so return false.
        return false;
}

Edited by LordVolcanon, 24 April 2013 - 10:52 AM.


#282 Avaro

Avaro

    >w<

  • Members

Posted 27 April 2013 - 11:25 AM

I'm pretty new to AutoGhost and want to use it in my quest. Have downloaded the zip file and extracted it into my zc directory. While reading the readme, I've set up the constants that needed to be set and finally added import "string.zh" and import "ghost.zh" to the top of my script file. Now I have to import the script into my global active slot, but I already have a global script?? Anyone know how to combine my autoghost script with my current global script?

Edit: Ok don't mind this. I've found the global script loop in the "scripts.zh" file. :D

Edit #2: Should I put my global script before or after the Waitdraw(); ? My global script doesn't use any waitdraws and I'm not sure what it is or if it will affect my current global script?

Edited by Avataro, 27 April 2013 - 11:35 AM.


#283 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 27 April 2013 - 12:29 PM

I think you should put it all before the Waitdraw(). I'm not sure if that's necessary, but it probably can't hurt.

#284 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 27 April 2013 - 01:53 PM

This is the default global scrip that comes with ghost.zh. And MoscowModder Waitdraw is completely necessary to imporate changes this frame such as preventing Ghost_Tile form drawn while the screen scrolls or Link dies. AutoGhost() allows for such npcs that spawn to have their ghost data initialized that frame so there normal behavior is ignored.

global script GhostZHActiveScript
{
    void run()
    {
        InitializeGhostZHData();

        while(true)
        {
            UpdateGhostZHData();
            UpdateEWeapons();
            CleanUpGhostFFCs(); // Only needed if __GH_USE_DRAWCOMBO is 0

            Waitdraw();

            AutoGhost();
            DrawGhostFFCs();

            Waitframe();
        }
    }
}


#285 Avaro

Avaro

    >w<

  • Members

Posted 28 April 2013 - 01:14 PM

Where can I find a tutorial that explains how to script autoghosted enemies and bosses? I want to make all my bosses, but I have NO clue how to start, how to set up the sprite, movement, attacks and what exactly is possible at all..


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users