Jump to content

Photo

ghost.zh


  • Please log in to reply
645 replies to this topic

#46 Saffith

Saffith

    IPv7 user

  • Members

Posted 14 August 2011 - 11:15 AM

Another update.
  • Added script versions of some of ZC's built-in movement functions
  • Added EWM_DRIFT and EWM_DRIFT_WAIT
  • The hitbox adjustments made by Ghost_SetHitOffsets() are now taken into account by Ghost_CanMove()


QUOTE(blackbishop89 @ Aug 9 2011, 12:23 PM) View Post
To make it so the ghost_data is set to 0 "vanishing" when link dies or the screen is scrolling. Only needed for ffcs where it's visible.

I added code to do this, but it turns out that modifying FFCs while scrolling doesn't work as of RC2. It'll clear them when Link dies, at least.

QUOTE
EDIT: Question Saffith, beside lowering ghost_HP is there another way to simulate an enemy being hit?

No. If you can't do what you need for whatever reason, you could create an lweapon on top of the enemy so that it actually does get it.

#47 Mero

Mero

    Touch Fluffy Tail

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

Posted 14 August 2011 - 12:29 PM

This is just awesome. I've got a lot of work ahead of me to update my scripts. icon_razz.gif

EDIT: Question Saffith which would be better to reproduce the detached gleeok head movement. Ghost_ConstantWalk8 or Ghost_VariableWalk8?

Answer: It's turn rate seems to vary quite a bit. So I'm going to say Ghost_ConstantWalk8 is best.

EDIT2: What should turncheck time be set to reproduce the default movements of the enemies with this pattern?

Answer: It appears to change direction at random intervals, Manhandla and Digdogger use one divisible 16 while patra seems to use one divisible by 8.

EDIT3: I'm confused how counter works with the other movements other then Ghost_HaltingWalk4 since they don't halt. Which the description for the counter argument is that it's set to remain halt time. Does it mean it's always 0 for constant walk?

Still don't know about this.

Edited by blackbishop89, 15 August 2011 - 12:56 PM.


#48 Mero

Mero

    Touch Fluffy Tail

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

Posted 15 August 2011 - 12:21 PM

Just thought I mention but would moldorms use a different type of walk function other then constantwalk8. I compared the two and the main difference is that the built in moldorms turn 45 degrees when they change direction. Is there something I need to do to reproduce this behavior when using ConstantWalk8?

#49 Colossal

Colossal

    Illustrious

  • Members
  • Location:Canada

Posted 15 August 2011 - 03:27 PM

Those movement functions sure will be helpful.

However, I've noticed that there appears to be something wrong with solidity detection. I can knock back a ghosted enemy leftward into solid combos, for instance. Same goes for those using Ghost_MoveAtAngle(). The enemies aren't reacting properly to partially solid combos either.

I've also noticed allegro.log occasionally getting flooded with this, though I haven't yet figured out why.
QUOTE
Invalid pointer (0) passed to array (don't change the values of your array pointers)



#50 Saffith

Saffith

    IPv7 user

  • Members

Posted 16 August 2011 - 11:15 AM

QUOTE
EDIT: Question Saffith which would be better to reproduce the detached gleeok head movement. Ghost_ConstantWalk8 or Ghost_VariableWalk8?

Answer: It's turn rate seems to vary quite a bit. So I'm going to say Ghost_ConstantWalk8 is best.

The built-in ones use variable_walk_8, but they also have some other code to keep them from moving too far. I don't see a good way to handle that in ZScript.

QUOTE
EDIT3: I'm confused how counter works with the other movements other then Ghost_HaltingWalk4 since they don't halt. Which the description for the counter argument is that it's set to remain halt time. Does it mean it's always 0 for constant walk?

That's not the only thing it can mean. They're mainly used internally to count down to when they should stop or turn. The halting walk counter does that, too, but it's actually two counters combined. It's set up so that only integer values >=0 indicate the enemy is halted, since that's the information you're most likely to want to use. Other movement types always return integers.

QUOTE
Just thought I mention but would moldorms use a different type of walk function other then constantwalk8. I compared the two and the main difference is that the built in moldorms turn 45 degrees when they change direction. Is there something I need to do to reproduce this behavior when using ConstantWalk8?

Honestly, I don't know. They probably have some special handling for that, but I can't find it.

QUOTE
However, I've noticed that there appears to be something wrong with solidity detection. I can knock back a ghosted enemy leftward into solid combos, for instance. Same goes for those using Ghost_MoveAtAngle(). The enemies aren't reacting properly to partially solid combos either.

Hm, seems I overlooked a couple of things. icon_redface.gif Hopefully, that's fixed now...

QUOTE
I've also noticed allegro.log occasionally getting flooded with this, though I haven't yet figured out why.
QUOTE
Invalid pointer (0) passed to array (don't change the values of your array pointers)

I'm not seeing that one. Another array bug, probably... Is it happening with a particular script?

#51 Colossal

Colossal

    Illustrious

  • Members
  • Location:Canada

Posted 16 August 2011 - 01:01 PM

QUOTE(Saffith @ Aug 16 2011, 09:15 AM) View Post
I'm not seeing that one. Another array bug, probably... Is it happening with a particular script?

Yeah, it only happens with some scripts, and I never saw it in 2.0. With the new version, it's showing up twice when some ghosted enemies are loaded (at least it isn't flooding allegro.log now). I'll see if I can pinpoint a cause.

EDIT: It seems to be quest-specific; it doesn't happen if I load the scripts in a different quest, just the one I'm seeing it in.

Edited by Colossal, 16 August 2011 - 01:45 PM.


#52 SpacemanDan

SpacemanDan

  • Members
  • Location:Ontario, Canada

Posted 16 August 2011 - 01:05 PM

I'm trying out an older enemy script in RC2 using Ghost_Legacy and I think I broke something or another, but can't quite figure out what.

CODE
const int SLM_BALL = 88; //The slime projectile that shoots to create more slimes.
const int SLM_COMBO = 3820; //Slime combo
const int SLM_SOUND = 62; //Sound when the slime shoots a smaller slime
const int SLM_ZOL = 180; //ID of the Zol to spawn
const int SLM_EXPLODE = 63; //Sound when slime explodes.

ffc script slime
{
    void run()
    {
        eweapon wpn;
        eweapon wpn2;
        eweapon wpn3;
        
        npc ghost;
        Waitframes(4);
        int frame = 0;
    
        //Swap to invisible combo temporarily
        this->Data = 0;
        
        ghost=GhostInitWait2(this,183,false,SLM_COMBO);
        
        while(true)
        {
            frame ++;
            if(frame%120 == 0)
            {
                
                wpn = FireAimedEWeapon(EW_SCRIPT1 ,CenterX(this),CenterY(this),0,50,4,false,SLM_BALL,SLM_SOUND,6);
                SetEWeaponMovement(wpn,EWM_THROW,Rand(25,60)/10);
                SetEWeaponDeathEffect(wpn,EWD_VANISH,0);
                
                wpn2 = FireAimedEWeapon(EW_SCRIPT1,CenterX(this),CenterY(this),DegtoRad(45),50,4,false,SLM_BALL,0,6);
                SetEWeaponMovement(wpn2,EWM_THROW,Rand(25,60)/10);
                SetEWeaponDeathEffect(wpn2,EWD_VANISH,0);
                
                wpn3 = FireAimedEWeapon(EW_SCRIPT1,CenterX(this),CenterY(this),DegtoRad(360-45),50,4,false,SLM_BALL,0,6);
                SetEWeaponMovement(wpn3,EWM_THROW,Rand(25,60)/10);
                SetEWeaponDeathEffect(wpn3,EWD_VANISH,0);
            }
            SlimWaitFrame(this,ghost,1);
        }
    }
    
    void SlimWaitFrame(ffc this, npc ghost, int numframes)
    {
        eweapon wpn;
        if(GotHit(ghost))
        {
            wpn = FireAimedEWeapon(EW_SCRIPT1,CenterX(this),CenterY(this),0,50,4,false,SLM_BALL,SLM_SOUND,6);
            SetEWeaponMovement(wpn,EWM_THROW,Rand(25,60)/10);
            SetEWeaponDeathEffect(wpn,EWD_SPAWN_NPC,SLM_ZOL);
            if(ghost->HP<100)
            {
                // Randomly placed harmless explosions
                lweapon explosion;
                this->CSet=this->CSet++;
                ghost->Y=176;
                this->Vx=0;
                this->Vy=0;
                for(int i=0; i<10; i++)
                {
                    explosion=Screen->CreateLWeapon(LW_BOMBBLAST);
                    explosion->X=Rand(this->X, this->X+16*this->TileWidth);
                    explosion->Y=Rand(this->Y, this->Y+32);
                    explosion->CollDetection=false;
                    Waitframes(30);
                    GhostWaitframeF(this,ghost,true,false);
                }
                
                // Kill NPC and clear combos
                Game->PlaySound(SLM_EXPLODE);
                ghost->HP=-1000;
                this->Data=0;
            
                Quit();
            }
        }
        Ghost_Waitframe2(this,ghost,true,false);
    }    
}


Here's how it's supposed to work: [Link]. I didn't alter the script much aside from changing a slight thing or two in the weapon firing and how much HP the boss needs before it dies. (And I made sure to set it above that in the editor.)

The problem is that it starts exploding the moment I enter the room, then dies. It also jumps around, since it's a tektite enemy, but it keeps being 'teleported' to the middle. Any ideas on what I'm doing wrong here?


#53 Saffith

Saffith

    IPv7 user

  • Members

Posted 16 August 2011 - 02:39 PM

QUOTE(Colossal @ Aug 16 2011, 02:01 PM) View Post
EDIT: It seems to be quest-specific; it doesn't happen if I load the scripts in a different quest, just the one I'm seeing it in.

Have you already saved the game in this quest? I added a couple of global variables and an array, so old saved data will be invalid with the latest version. I'll have to be sure to note those changes in future updates...


QUOTE(SpacemanDan @ Aug 16 2011, 02:05 PM) View Post
I'm trying out an older enemy script in RC2 using Ghost_Legacy and I think I broke something or another, but can't quite figure out what.

You're using the new Ghost_Waitframe2 with an otherwise old-style script. The old init functions don't set Ghost_HP, so it's dying on the first Waitframe.

#54 Colossal

Colossal

    Illustrious

  • Members
  • Location:Canada

Posted 16 August 2011 - 03:27 PM

QUOTE(Saffith @ Aug 16 2011, 12:39 PM) View Post

Have you already saved the game in this quest? I added a couple of global variables and an array, so old saved data will be invalid with the latest version. I'll have to be sure to note those changes in future updates...

That's exactly what it was. The save file I used wasn't new, so I created a new one and there are no more log errors.


#55 XMSB

XMSB

    Furry Friends Furever

  • Members
  • Real Name:Joseph Watson
  • Location:San Antonio, Texas

Posted 16 August 2011 - 04:12 PM

Just a quick question. Whenever you import ghost.zh and compile it, you get a global variable titled 'GhoshZHActiveScript'. But in my current quest project, I also have the following global script in my script file:
Sound Combo
Since there would then be 2 global variables to be used with the active slot, would it be possible to get both of them to work, or would I have to sacrifice the sound combo variable just to use the 'GhoshZHActiveScript' variable?

#56 Mero

Mero

    Touch Fluffy Tail

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

Posted 16 August 2011 - 04:38 PM

QUOTE(XMuppetSB @ Aug 16 2011, 03:12 PM) View Post

Just a quick question. Whenever you import ghost.zh and compile it, you get a global variable titled 'GhoshZHActiveScript'. But in my current quest project, I also have the following global script in my script file:
Sound Combo
Since there would then be 2 global variables to be used with the active slot, would it be possible to get both of them to work, or would I have to sacrifice the sound combo variable just to use the 'GhoshZHActiveScript' variable?


Those aren't variables those are scripts. And if you combine them you have nothing to worry about, unless they can't be combined.

#57 Colossal

Colossal

    Illustrious

  • Members
  • Location:Canada

Posted 16 August 2011 - 04:39 PM

You can merge the scripts together and they will both work. Open ghost.zh and look for GhostZHActiveScript, which is not far from the top of ghost.zh and merge that with your global script. Note the use of Waitdraw().


#58 XMSB

XMSB

    Furry Friends Furever

  • Members
  • Real Name:Joseph Watson
  • Location:San Antonio, Texas

Posted 16 August 2011 - 04:55 PM

Here's the script file from my questl:

CODE

import "std.zh"
import "string.zh"
import "ghost.zh"

bool NPC_Hastaken[99];
const int WSP_FALLING        = 100; //Weapon/Misc. sprite for Link falling down a hole
const int WSP_LAVA            = 101; //Weapon/Misc. sprite for Link drowning in lava
const int SFX_FALLING        = 61; //SFX for falling down a hole
const int SFX_LAVA            = 63; //SFX for drowning in lava
const int CMB_AUTOWARP        = 7; //Combo ID of a transparent AutoWarp A combotype

const int CT_HOLELAVA        = 143; //Combotype to give hole functionality to (default is Left Statue)

bool Falling;
bool usingLadder;
const int ClimbingFlag = 99;
const int SOUND_COMBO = 142;
const int SOUND_COMBO_SFX = 62;
bool soundCombos[176];
int scPrevScreen = -1;
int scPrevDMap = -1;

bool has_hover = false;
bool on_ladder = false;

bool isSolid(int x, int y) {
  
    if(x<0 || x>255 || y<0 || y>175) return false;
    int mask=1111b;
    
    if(x % 16 < 8)
      mask &= 0011b;
    else
      mask &= 1100b;
  
    if(y % 16 < 8)
      mask &= 0101b;
    else
      mask &= 1010b;
  
    int ret = Screen->ComboS[ComboAt(x, y)] & mask;
    return (ret!=0);

  }

  void ladder(int f) {
    int lc;
  
    lc = ComboAt(Link->X+8, Link->Y+15); //for speed
  
    if(Screen->ComboF[lc] == f || Screen->ComboI[lc] == f) {
      if(!on_ladder) {
        on_ladder = true;
        has_hover = Link->Item[I_HOVERBOOTS];
        Link->Item[I_HOVERBOOTS] = false;
      }
      Link->Jump = 0;
      Link->Z = 0;
      Link->Dir = DIR_UP;
    
      if(Link->InputDown) {
        Link->InputDown = false;
        Link->Action = LA_WALKING;
        if(!isSolid(Link->X, Link->Y + 16)) Link->Y += 1;
      }
      if(Link->InputUp) {
        Link->InputUp = false;
        Link->Action = LA_WALKING;
        if(!isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
      }
      if(Link->InputLeft) {
        Link->InputLeft = false;
        Link->Action = LA_WALKING;
        if(!isSolid(Link->X - 1 , Link->Y)) Link->X -= 1;
      }
      if(Link->InputRight) {
        Link->InputRight = false;
        Link->Action = LA_WALKING;
        if(!isSolid(Link->X + 16, Link->Y)) Link->X += 1;
      }
    } else {
      if(on_ladder) {
        Link->Item[I_HOVERBOOTS] = has_hover;
        on_ladder = false;
      }
    }
  }

void doSoundCombo()
{
    if(Link->Action == LA_SCROLLING)
        return;
    
    bool playSound = false;
    
    if(Game->GetCurDMap() != scPrevDMap || Game->GetCurDMapScreen() != scPrevScreen)
    {
        for(int i=0; i<176; i++)
            soundCombos[i] = false;
    }
    
    scPrevDMap = Game->GetCurDMap();
    scPrevScreen = Game->GetCurDMapScreen();
    
    for(int i=0; i<176; i++)
    {
        if(Screen->ComboT[i] == SOUND_COMBO && !soundCombos[i])
            playSound = true;
        soundCombos[i] = Screen->ComboT[i] == SOUND_COMBO;
    }
    
    if(playSound)
        Game->PlaySound(SOUND_COMBO_SFX);
}

global script soundCombo
{
    void run()
    {
        while(true)
        {
            //Other Global functions called before Waitdraw(); go here...
            
            
            
            //Climbing script functions...
            if((Screen->ComboF[ComboAt(Link->X+8, Link->Y+9)] == ClimbingFlag || Screen->ComboI[ComboAt(Link->X+8, Link->Y+9)] == ClimbingFlag) && Link->Z == 0){
                Link->InputA = false;
                Link->InputB = false;
                Link->InputL = false;
                usingLadder=true;
            }
            else if(usingLadder)
                usingLadder=false;

            Waitdraw();
            if(usingLadder)
                Link->Dir = 0;
            //Other Global Functions called after Waitdraw(); go here...

            doSoundCombo();
            ladder(98); // Change the number here to use a different flag
            Waitframe();
        }
    }
}

ffc script Signpost{
    void run(int m,int input){
        int loc = ComboAt(this->X,this->Y);
        while(true){
            while(!AgainstComboBase(loc) || !SelectPressInput(input)) Waitframe();
            SetInput(input,false);
            Screen->Message(m);
            Waitframe();
        }
    }
    bool AgainstComboBase(int loc){
        return Link->Z == 0 && (Link->Dir == DIR_UP && Link->Y == ComboY(loc)+8 && Abs(Link->X-ComboX(loc)) < 8);
    }
}

ffc script RealNPC{
    void run(int m, int sfx, int defdir, int d, int ffcnumber, int input){
        ffc NPC = this;
        if(ffcnumber != 0) Screen->LoadFFC(ffcnumber);
        NPC->Misc[0] = NPC->Data;
        if(d == 0) d = 40;
        
        while(true){
            SetGraphic(NPC,defdir,d);
            if(CanTalk(NPC,input)){
                SetInput(input,false);
                if(sfx != 0) Game->PlaySound(sfx);
                Screen->Message(m);
            }
            Waitframe();
        }
    }
    bool CanTalk(ffc NPC,int input){
        return (SelectPressInput(input) && Abs(NPC->X-Link->X) < 24 && Abs(NPC->Y-Link->Y) < 24 && Link->Z == 0);
    }
    void SetGraphic(ffc NPC, int defdir, int d){
        int dx = NPC->X-Link->X; int ax = Abs(dx);
        int dy = NPC->Y-Link->Y; int ay = Abs(dy);
        if(defdir != 0){
            if(ax < d && ay < d){
                if(ax <= ay){
                    if(dy >= 0) NPC->Data = NPC->Misc[0]+DIR_UP;
                    else NPC->Data = NPC->Misc[0]+DIR_DOWN;
                }else{
                    if(dx >= 0) NPC->Data = NPC->Misc[0]+DIR_LEFT;
                    else NPC->Data = NPC->Misc[0]+DIR_RIGHT;
                }
            }else NPC->Data = NPC->Misc[0]+(defdir-1);
        }
    }
}

item script Message{
    void run(int m){
        Screen->Message(m);
    }
}

item script Message2{
    void run(int filler, int m){
        Screen->Message(m);
    }
}

ffc script Shop{
    void run(int itm, int price,int input){
        while(true){
            if(CanBuy(this,input)){
                SetInput(input,false);
                if(Game->Counter[CR_RUPEES] >= price){
                    ShopItemThanks(itm);
                    DeductRupees(price);
                }else Screen->Message(S_NORUPEES);
            }
        Waitframe();
        }
    }
}

const int CMB_BLANK        = 0; //Set this to the ID of a transparent combo
const int CMB_NULL        = 0; //Leave this as 0!
ffc script ShopSingleSaleItem{
    void run(int itm, int price, int perm, int input){
        while(Screen->D[perm] == 0){
            if(CanBuy(this,input)){
                SetInput(input,false);
                if(Game->Counter[CR_RUPEES] >= price){
                    ShopItemThanks(itm);
                    this->Data = CMB_BLANK;
                    DeductRupees(price);
                    Screen->D[perm]++;
                }else Screen->Message(S_NORUPEES);
            }
        Waitframe();
        }
        this->Data = CMB_NULL;
    }
}

const int S_NORUPEES = 72;  //Message saying 'Not enough rupees'
const int S_THANKS     = 73; //Message saying 'Thanks for buying'

bool CanBuy(ffc buy,int input){
    return (Abs(Link->X-buy->X) < 8 && Abs(Link->Y-(buy->Y+8)) < 8 && SelectPressInput(input) && Link->Dir == DIR_UP);
}
void ShopItemThanks(int itm){
    Screen->Message(S_THANKS);
    Game->PlaySound(SFX_SCALE);
    WaitNoAction();
    CreatePickupItem(Link->X,Link->Y,itm);
    Game->PlaySound(SFX_PICKUP);
    WaitNoAction();
}
void CreatePickupItem(int x, int y, int itm){
    item Spawn = Screen->CreateItem(itm);
    Spawn->Pickup |= IP_TIMEOUT;
    Spawn->HitWidth = 16; Spawn->HitHeight = 16;
    Spawn->X = x; Spawn->Y = y;
}

void DeductRupees(int amount){
    FreezeScreen();
    for(int i=0;i<amount;i++){
        Game->PlaySound(SFX_MSG);
        Game->Counter[CR_RUPEES]--;
    Waitframe();
    }
    UnFreeze();
}

int FreezeID;
void FreezeScreen(){
    FreezeID = Screen->ComboT[0];
    Screen->ComboT[0] = CT_SCREENFREEZE;
}
void UnFreeze(){
    Screen->ComboT[0] = FreezeID;
}

bool SelectPressInput(int input){
    if(input == 0) return Link->PressA;
    else if(input == 1) return Link->PressB;
    else if(input == 2) return Link->PressL;
    else if(input == 3) return Link->PressR;
}
void SetInput(int input, bool state){
    if(input == 0) Link->InputA = false;
    else if(input == 1) Link->InputB = false;
    else if(input == 2) Link->InputL = false;
    else if(input == 3) Link->InputR = false;
}

ffc script FFCJumpCliff{

    void run(int verticalmovement, int horizontalmovement, int directiontopress) {
    
        int directiontopressmoreleft;
        int directiontopressmoreright;
        int LinkHmovementdone = 0;
        bool ffcsentlinkjumping = false;
    
        if (directiontopress==DIR_DOWN) {
            directiontopressmoreleft = DIR_RIGHTDOWN;
            directiontopressmoreright = DIR_LEFTDOWN;
        }
    
        else {
            if (directiontopress==DIR_UP) {
                directiontopressmoreleft = DIR_LEFTUP;
                directiontopressmoreright = DIR_RIGHTUP;
            }
            else {
                if (directiontopress==DIR_LEFT) {
                    directiontopressmoreleft = DIR_LEFTDOWN;
                    directiontopressmoreright = DIR_LEFTUP;
                }
                else {
                    if (directiontopress==DIR_RIGHT) {
                        directiontopressmoreleft = DIR_RIGHTUP;
                        directiontopressmoreright = DIR_RIGHTDOWN;
                    }
                    else {
                        if (directiontopress==DIR_LEFTDOWN) {
                            directiontopressmoreleft = DIR_DOWN;
                            directiontopressmoreright = DIR_LEFT;
                        }
                        else {
                            if (directiontopress==DIR_RIGHTDOWN) {
                                directiontopressmoreleft = DIR_RIGHT;
                                directiontopressmoreright = DIR_DOWN;
                            }
                            else {
                                if (directiontopress==DIR_LEFTUP) {
                                    directiontopressmoreleft = DIR_LEFT;
                                    directiontopressmoreright = DIR_UP;
                                }
                                else {
                                    if (directiontopress==DIR_RIGHTUP) {
                                        directiontopressmoreleft = DIR_UP;
                                        directiontopressmoreright = DIR_RIGHT;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        while (true){
    
            if (Link->Z==0) {
                LinkHmovementdone=0;
                ffcsentlinkjumping = false;
            }
    
            if ( (ffcsentlinkjumping)&&(LinkHmovementdone<Abs(horizontalmovement)) ) {
                if (horizontalmovement<0) {Link->X--;}
                if (horizontalmovement>0) {Link->X++;}
                LinkHmovementdone++;
            }
    
            if ( (LinkCollision(this))
                && ( (Link->Dir==directiontopress)
                ||(Link->Dir==directiontopressmoreleft)
                ||(Link->Dir==directiontopressmoreright) ) ) {
                
                if (Link->Z==0){
                    Game->PlaySound(SFX_JUMP);
                }
                ffcsentlinkjumping=true;
                Link->Y=Link->Y+verticalmovement;
                Link->Z=Link->Z+verticalmovement;
            }
            
            Waitframe();
        }
    }
}

ffc script RealNPCtrade{
    void run(int m, int sfx, int defdir, int itemid, int item2, int input, int npcid){
        ffc NPC = this;
        
        NPC->Misc[0] = NPC->Data;
        
        while(true){
            SetGraphic(NPC,defdir,40);
            if(CanTalk(NPC,input)){
            
            if(NPC_Hastaken[npcid]){
                SetInput(input,false);
                if(sfx != 0) Game->PlaySound(sfx);
                Screen->Message(m);
            }            
            else if(!NPC_Hastaken[npcid] && Link->Item[itemid]){
                NPC_Hastaken[npcid] = true;
                if(sfx!=0) Game->PlaySound(sfx);
                SetInput(input,false);
                Screen->Message(m+1);
                Link->Item[itemid] = false;
                Link->Item[item2] = true;
            }
            else if(!NPC_Hastaken[npcid] && !Link->Item[itemid]){
                 SetInput(input,false);
                if(sfx!=0) Game->PlaySound(sfx);
                Screen->Message(m+2);
            }
            

            }
            Waitframe();
        }
    }
    bool CanTalk(ffc NPC,int input){
        return (SelectPressInput(input) && Abs(NPC->X-Link->X) < 24 && Abs(NPC->Y-Link->Y) < 24 && Link->Z == 0);
    }
    void SetGraphic(ffc NPC, int defdir, int d){
        int dx = NPC->X-Link->X; int ax = Abs(dx);
        int dy = NPC->Y-Link->Y; int ay = Abs(dy);
        if(defdir != 0){
            if(ax < d && ay < d){
                if(ax <= ay){
                    if(dy >= 0) NPC->Data = NPC->Misc[0]+DIR_UP;
                    else NPC->Data = NPC->Misc[0]+DIR_DOWN;
                }else{
                    if(dx >= 0) NPC->Data = NPC->Misc[0]+DIR_LEFT;
                    else NPC->Data = NPC->Misc[0]+DIR_RIGHT;
                }
            }else NPC->Data = NPC->Misc[0]+(defdir-1);
        }
    }
}

ffc script RealNPCtakemoney{
    void run(int m, int sfx, int defdir, int increment, int decrement, int input, int npcid){
        ffc NPC = this;
        
        NPC->Misc[0] = NPC->Data;
        
        
        while(true){
            SetGraphic(NPC,defdir,40);
            if(CanTalk(NPC,input)){
            

                if(NPC_Hastaken[npcid]){
                    SetInput(input,false);
                    if(sfx != 0) Game->PlaySound(sfx);
                    Screen->Message(m);        
                }
                else if(!NPC_Hastaken[npcid] && Game->Counter[CR_RUPEES] >= decrement){
                    Game->Counter[CR_RUPEES] -= decrement;
                    Game->Counter[CR_RUPEES] += increment;
                    NPC_Hastaken[npcid] = true;
                    if(sfx!=0) Game->PlaySound(sfx);
                    SetInput(input,false);
                    Screen->Message(m+1);
                }
                else if(!NPC_Hastaken[npcid] && Game->Counter[CR_RUPEES] < decrement){
                    SetInput(input,false);
                    if(sfx!=0) Game->PlaySound(sfx);
                    Screen->Message(m+2);
                }
            

            
            }
            Waitframe();
        }
    }
    bool CanTalk(ffc NPC,int input){
        return (SelectPressInput(input) && Abs(NPC->X-Link->X) < 24 && Abs(NPC->Y-Link->Y) < 24 && Link->Z == 0);
    }
    void SetGraphic(ffc NPC, int defdir, int d){
        int dx = NPC->X-Link->X; int ax = Abs(dx);
        int dy = NPC->Y-Link->Y; int ay = Abs(dy);
        if(defdir != 0){
            if(ax < d && ay < d){
                if(ax <= ay){
                    if(dy >= 0) NPC->Data = NPC->Misc[0]+DIR_UP;
                    else NPC->Data = NPC->Misc[0]+DIR_DOWN;
                }else{
                    if(dx >= 0) NPC->Data = NPC->Misc[0]+DIR_LEFT;
                    else NPC->Data = NPC->Misc[0]+DIR_RIGHT;
                }
            }else NPC->Data = NPC->Misc[0]+(defdir-1);
        }
    }
}

ffc script HoleLava{
    void run(int lava, int warpto, int warptype, int damage){
        int graphic = WSP_FALLING; int sfx = SFX_FALLING;
        if(lava){ graphic = WSP_LAVA; sfx = SFX_LAVA; }
        if(this->X == 0 && this->Y == 0){
            Waitframes(5);
            this->X = Link->X; this->Y = Link->Y;
        }
        if(damage == 0) damage = 8;
    
        while(true){
            while(!OnPitCombo()) Waitframe();
            int pitclk = 0;
            while(OnPitCombo() && pitclk++ < 4) WaitCancelFeather();
            if(pitclk >= 5) Fall(this,sfx,graphic,damage,warpto,warptype);
        }
    }
    void Fall(ffc pos, int sfx, int graphic, int damage, int warpto, int warptype){
        Falling = true;
        Game->PlaySound(sfx);
        
        for(int i=1;i<=Screen->NumLWeapons();i++){
            lweapon l = Screen->LoadLWeapon(i);
            if(l->ID == LW_SWORD) l->DeadState = WDS_DEAD;
        }
        
        int wait = CreateGraphic(graphic);
        Link->CollDetection = false; Link->Invisible = true;
        for(int i=0;i<30;i++) WaitNoAction();
        Link->CollDetection = true; Link->Invisible = false;

        if(warpto) PitWarp(pos, warptype);

        Link->X = pos->X; Link->Y = pos->Y;
        Link->HP -= damage;
        Game->PlaySound(SFX_OUCH);
        Falling = false;
    }
    void PitWarp(ffc Warp, int warptype){
        int orig = Warp->Data;
    Link->Z = Link->Y;
        Warp->Data = CMB_AUTOWARP+warptype;
        Waitframe();
        Link->Z = Link->Y;
        Quit();
    }
    bool OnPitCombo(){
        return (Screen->ComboT[ComboAt(Link->X+8,Link->Y+8)] == CT_HOLELAVA && Link->Z <= 0 && Link->Action != LA_FROZEN);
    }
    int CreateGraphic(int sprite){
        lweapon l = Screen->CreateLWeapon(LW_SCRIPT1);
        l->HitXOffset = 500;
        l->UseSprite(sprite);
        l->DeadState = l->NumFrames*l->ASpeed;
        l->X = Link->X; l->Y = Link->Y;
        return l->DeadState;
    }
    void WaitCancelFeather(){
        if(GetEquipmentA() == I_ROCSFEATHER && Link->InputA) Link->InputA = false;
        if(GetEquipmentB() == I_ROCSFEATHER && Link->InputB) Link->InputB = false;
        Waitframe();
    }
}

ffc script Spawner
{
    void run(int ID)
    {
        Waitframes(4);
        npc n = CreateNPCAt(ID, this->X, this->Y);
        n->Dir = DIR_DOWN;
    }
}


But I'm not sure if I'll be able to merge all the global variables with this script from ghost.zh:

CODE

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

        while(true)
        {
            UpdateEWeapons();
            UpdateClock();
            CleanUpGhostFFCs();

            Waitdraw();

            AutoGhost();

            Waitframe();
        }
    }
}


#59 Colossal

Colossal

    Illustrious

  • Members
  • Location:Canada

Posted 16 August 2011 - 05:02 PM

CODE
global script soundCombo
{
    void run()
    {
        StartClock();
        while(true)
        {
            //Other Global functions called before Waitdraw(); go here...
            UpdateEWeapons();
            UpdateClock();
            CleanUpGhostFFCs();
            
            
            //Climbing script functions...
            if((Screen->ComboF[ComboAt(Link->X+8,  Link->Y+9)] == ClimbingFlag ||  Screen->ComboI[ComboAt(Link->X+8, Link->Y+9)] == ClimbingFlag)  && Link->Z == 0){
                Link->InputA = false;
                Link->InputB = false;
                Link->InputL = false;
                usingLadder=true;
            }
            else if(usingLadder)
                usingLadder=false;

            Waitdraw();
            if(usingLadder)
                Link->Dir = 0;
            //Other Global Functions called after Waitdraw(); go here...
            AutoGhost();

            doSoundCombo();
            ladder(98); // Change the number here to use a different flag
            Waitframe();
        }
    }
}  

I merged the global scripts for you, so you can replace the global script you are using with this.


#60 XMSB

XMSB

    Furry Friends Furever

  • Members
  • Real Name:Joseph Watson
  • Location:San Antonio, Texas

Posted 16 August 2011 - 05:28 PM

Well, it compiled successfully. Thanks. Now I just need to start importing some enemy FFCs here.


2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users