Jump to content

Photo

ghost.zh


  • Please log in to reply
645 replies to this topic

#376 Avaro

Avaro

    >w<

  • Members

Posted 23 October 2014 - 11:17 AM

For some reason I can't download the demo quest and example scripts. Can someone else download them?

#377 Saffith

Saffith

    IPv7 user

  • Members

Posted 23 October 2014 - 12:56 PM

Sorry about that. FileSmelt died a while ago, and I forgot to update. It should work now.
  • Avaro likes this

#378 Avaro

Avaro

    >w<

  • Members

Posted 23 October 2014 - 01:59 PM

Okay so I'm trying to learn how to use ghost.zh. Here's my first enemy:

ffc script MyFirstEnemy{
    void run(int enemyID){
        npc ghost = Ghost_InitAutoGhost(this, enemyID);
        Ghost_SetFlag(GHF_NORMAL);
        while(true){
            Ghost_ConstantWalk4(-1, 50, 6, 0, 0);
            Ghost_Waitframe(this, ghost, true, true);
        }
    }
} 
Everything works well so far, except the movement. I'm trying to make a normal walking enemy here. However it won't walk correctly. What am I doing wrong?
  • David likes this

#379 Saffith

Saffith

    IPv7 user

  • Members

Posted 23 October 2014 - 02:28 PM

It needs a counter to store data between frames.
 
ffc script MyFirstEnemy{
    void run(int enemyID){
        npc ghost = Ghost_InitAutoGhost(this, enemyID);
        int walkCounter=-1;
        Ghost_SetFlag(GHF_NORMAL);
        while(true){
            walkCounter=Ghost_ConstantWalk4(walkCounter, 50, 6, 0, 0);
            Ghost_Waitframe(this, ghost, true, true);
        }
    }
} 


#380 Avaro

Avaro

    >w<

  • Members

Posted 23 October 2014 - 03:40 PM

Oh okay! Thank you, and also thank you saffith for making this great header! It all works so nicely and it's almost like an extended enemy editor :D

Edited by Avataro, 23 October 2014 - 03:41 PM.

  • David likes this

#381 Mero

Mero

    Touch Fluffy Tail

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

Posted 23 October 2014 - 05:01 PM

void Ghost_WaitframeLight(ffc this, npc ghost)
{
    // Remember all the global variables
   
    // Initializing the array is faster than setting it up afterward...
    // but the difference is probably negligible, realistically
    float tempGhostData[24] = {
        Ghost_X, // 0
        Ghost_Y, // 1
        Ghost_Z, // 2
        Ghost_Jump, // 3
        Ghost_Vx, // 4
        Ghost_Vy, // 5
        Ghost_Ax, // 6
        Ghost_Ay, // 7
        __Ghost_PrevX, // 8
        __Ghost_PrevY, // 9
        Ghost_CSet, // 10
        Ghost_Dir, // 11
        Ghost_Data, // 12
        Ghost_TileWidth, // 13
        Ghost_TileHeight, // 14
        __Ghost_Flags, // 15
        __Ghost_Flags2, // 16
        __Ghost_InternalFlags, // 17
        __Ghost_FlashCounter, // 18
        __Ghost_KnockbackCounter, // 19
        Ghost_HP, // 20
        __Ghost_XOffsets, // 21
        __Ghost_YOffsets // 22
        // 23 is for either drawingData or tempGhostAdditionalCombos;
        // update DrawGhostFFCs if that changes
    };
    int tempGhostAdditionalCombos[21]; // Same size as __Ghost_AdditionalCombos
                                       // Change it in the loop below, too
    if(__Ghost_AdditionalCombos[0]>0)
    {
        for(int i=0; i<21; i++)
            tempGhostAdditionalCombos[i]=__Ghost_AdditionalCombos[i];
    }
    else
        __Ghost_AdditionalCombos[0]=0; //this is all I added
   
    // Give ghost an array pointer so its data can be found by other scripts
    if(ghost->isValid())
        ghost->Misc[__GHI_NPC_DATA]=0x10000|tempGhostData;
   
    // Position additional FFCs, set draw data, make FFCs invisible if flickering.
    do
    {
        if(ghost->isValid())
        {
            // Set up drawing array if needed. The array size depends on what
            // might need drawn. If only ZScript had malloc...
            if(__GH_USE_DRAWCOMBO!=0)
            {
                // DrawCombo and additional combos
                if(__Ghost_AdditionalCombos[__GHI_AC_COUNT]>0)
                {
                    // Array size is 4 + (__GH_AC_MAX_ADDITIONAL_COMBOS + 1) * __GHCD_DATA_SIZE
                    int drawData[34];
                    __SetUpDrawingArray(this, ghost, drawData);
                    tempGhostData[23]=drawData;
                    __HideFFCAndWait(this);
                }
               
                // DrawCombo and no additional combos
                else
                {
                    // 4 + __GHCD_DATA_SIZE
                    int drawData[10];
                    __SetUpDrawingArray(this, ghost, drawData);
                    tempGhostData[23]=drawData;
                    __HideFFCAndWait(this);
                }
            }
            else // __GH_USE_DRAWCOMBO==0
            {
                // Additional combos, no DrawCombo
                if(__Ghost_AdditionalCombos[__GHI_AC_COUNT]>0)
                {
                    // 4 + __GH_AC_MAX_ADDITIONAL_COMBOS * __GHCD_DATA_SIZE
                    int drawData[28];
                    __SetUpDrawingArray(this, ghost, drawData);
                    tempGhostData[23]=drawData;
                   
                    // Hide the FFC if the enemy is flickering.
                    if(__Ghost_IsFlickering(ghost) &&
                       (__ghzhData[__GHI_GLOBAL_FLAGS]&__GHGF_FLICKER)!=0)
                        __HideFFCAndWait(this);
                    else
                        Waitframe();
                }
               
                // No DrawCombo or additional combos
                else
                {
                    if(__Ghost_IsFlickering(ghost) &&
                       (__ghzhData[__GHI_GLOBAL_FLAGS]&__GHGF_FLICKER)==0)
                        __HideFFCAndWait(this);
                    else
                        Waitframe();
                }
            }
        }
        else // ghost is not valid
            __HideFFCAndWait(this);
       
        // Restore the global variables
        Ghost_X=tempGhostData[0];
        Ghost_Y=tempGhostData[1];
        Ghost_Z=tempGhostData[2];
        Ghost_Jump=tempGhostData[3];
        Ghost_Vx=tempGhostData[4];
        Ghost_Vy=tempGhostData[5];
        Ghost_Ax=tempGhostData[6];
        Ghost_Ay=tempGhostData[7];
        __Ghost_PrevX=tempGhostData[8];
        __Ghost_PrevY=tempGhostData[9];
        Ghost_CSet=tempGhostData[10];
        Ghost_Dir=tempGhostData[11];
        Ghost_Data=tempGhostData[12];
        Ghost_TileWidth=tempGhostData[13];
        Ghost_TileHeight=tempGhostData[14];
        __Ghost_Flags=tempGhostData[15];
        __Ghost_Flags2=tempGhostData[16];
        __Ghost_InternalFlags=tempGhostData[17];
        __Ghost_FlashCounter=tempGhostData[18];
        __Ghost_KnockbackCounter=tempGhostData[19];
        Ghost_HP=tempGhostData[20];
        __Ghost_XOffsets=tempGhostData[21];
        __Ghost_YOffsets=tempGhostData[22];
       
        if(tempGhostAdditionalCombos[0]>0)
        {
            for(int i=0; i<21; i++)
                __Ghost_AdditionalCombos[i]=tempGhostAdditionalCombos[i];
        }
       
    } while((__ghzhData[__GHI_GLOBAL_FLAGS]&__GHGF_SUSPEND)!=0);
   
    if(ghost->isValid())
        ghost->Misc[__GHI_NPC_DATA]=0x10000;
}

 

For some reason when I upgraded to the current version of ghost.zh and reincorporated the change to fix the carryover issue it no longer works. any ides why?



#382 Saffith

Saffith

    IPv7 user

  • Members

Posted 23 October 2014 - 05:05 PM

You got the wrong if. You want the one at the end, just before while.

#383 Mero

Mero

    Touch Fluffy Tail

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

Posted 17 November 2014 - 02:01 PM

Any chance you could add in compatibility with custom pit scripts?



#384 Avaro

Avaro

    >w<

  • Members

Posted 21 November 2014 - 01:18 PM

Okay, so I've been learning the basics of ghost.zh and I can make enemies with it now. I have a couple questions though, so here we go! I hope someone can help me out, I would really appreciate it :)

 

1. How do I spawn ghosted enemies, other than using npc SpawnNPC(int id)? I know I can place them onto the screen like normal enemies, but what if I want to spawn them by a script? If I use that function, how do I set the spawn point (if I don't want to spawn the enemy in a random location)?

 

2. If an ghosted enemy has GHF_MOVE_OFFSCREEN enabled at the start in it's script, can I even make them spawn offscreen? Or do they first need to spawn somewhere on the screen, and then move them offscreen manually?

 

3. How do I use int findSpawnPoint(bool landOK, bool wallsOK, bool waterOK, bool pitsOK)? Is this integer the X or the Y position? I don't get it.

 

4. How do I "OR" together 2 or more constants?

 

That's all questions I have right now. Can you help me out?


Edited by Avataro, 21 November 2014 - 01:19 PM.


#385 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 21 November 2014 - 02:24 PM

1. Create it like any other enemy: npc enem = CreateNPCAt(id, x, y);

2. I don't know. I guess you can experiment with it.

3. It's the combo number. You can convert it to X/Y with ComboX() and ComboY().

4. int flag = FLAG_MYFLAG1 | FLAG_MYFLAG2;


  • Avaro likes this

#386 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 21 November 2014 - 02:27 PM

1. You can use one of the ghost init functions. Just remember that Ghost_Init doesn't return an npc pointer (all the other ones do, however). Personally, I don't like using those functions at all and just let autoghost handle everything. If you've done autoghost setup for the enemy already, you can just create it as normal with Screen->CreateNPC or SpawnNPC, and the global script will pick it up and ghost it for you. You can set the spawn point on the same frame you create it by simply adjusting ghost->X and ghost->Y.

 

2. Yes, you should be able to move or spawn it offscreen.

 

3. The return value of that function is the combo position, 0 to 175. You can use ComboX and ComboY to get an x/y out of it.

 

4. constant1 | constant2

 

You know what the | operator does, right? Might be helpful to read the bit in Saffith's ZScript tutorial about that.


  • Avaro likes this

#387 Avaro

Avaro

    >w<

  • Members

Posted 21 November 2014 - 02:44 PM

Alright, thank you both for helping me out with my questions! This is all very good to know. Well yes, all I knew about the | operator so far, is that I can use || in an if-check, much like how && means "and".

But yes, thanks!



#388 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 21 November 2014 - 03:04 PM

FYI, the single | is a bitwise operator. A bitwise operator goes through each bit in a number and performs that operation, just like a non-bitwise operator takes the values as a whole.

 

So, for example: 5 | 9 =

0101 = 5

1001 = 9

-------

1101 = 13

Each individual bit is OR-ed into the result.

 

Bitwise AND works similarly but with AND: 5 & 9 =

0101 = 5

1001 = 9

--------

0001 = 1

 

If you're still confused, you can look up bitwise operators or else just take our word for it.



#389 Avaro

Avaro

    >w<

  • Members

Posted 21 November 2014 - 03:59 PM

Hmm, I see. Looks like a lot of thought must have gone into making all of the EWF and EWM constants work.


Edited by Avataro, 15 December 2014 - 04:05 PM.


#390 Mero

Mero

    Touch Fluffy Tail

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

Posted 15 December 2014 - 04:00 PM

How does one get the ID's of the additional combos for purposes of collisions with Link and LWeapons.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users