User Tag List

Page 4 of 5 FirstFirst ... 2 3 4 5 LastLast
Results 31 to 40 of 42

Thread: ghost.zh - A header file for ghosted enemy scripts

  1. #31
    Is this the end?
    ZC Developer
    Saffith's Avatar
    Join Date
    Jan 2001
    Age
    41
    Posts
    3,389
    Mentioned
    178 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,432
    Level
    24
    vBActivity - Bars
    Lv. Percent
    69.88%
    Hey, I'm actually updating it. How about that.

    The biggest change this time is the __GH_ALWAYS_USE_NAME setting. If it's enabled, AutoGhost() will always read an enemy's name to get the script and combo number. Misc. attributes 11 and 12 will be free for other scripts to use.
    The script and combo number both go after @ in the name. Order and spacing aren't important, and other characters are allowed afterward. Either of these will work:
    Goriya (LttP, Green) [@Goriya_LttP, @25804]
    Goriya (LttP, Green) @25804@Goriya_LttP
    You have to provide the script name, but if you don't specify a combo, it'll default to GH_INVISIBLE_COMBO. This will work fine:
    Armos @Armos_LttP

    The downside to this is that enemy scripts can no longer assume misc. attribute 11 specifies the base combo. I don't think that was a common thing to do, anyway.

    Other notable changes:
    The files in the ghost_zh directory have been moved to a numbered subdirectory. This will allow multiple versions to coexist.
    Ghost_TileWidth and Ghost_TileHeight should now be considered read-only. Ghost_SetSize() should be used to set them.
    You can now control what constitutes a pit by editing the __IsPit() function in the main file.
    There's also a __HaveAmulet() function, used to determine if enemies are visible when the "All Enemies Are Invisible" screen flag is used.
    Weapons can now have fake Z movement, both individually and globally.
    Added a new death animation, as well as constants to use as arguments to Ghost_DeathAnimation() and Ghost_Waitframe().

    There haven't been any changes to global data, so this version should be compatible with existing saves using 2.7.x. Still, be careful.

  2. #32
    Here lies mero. Died by his own dumbassitude.
    Join Date
    May 2011
    Posts
    929
    Mentioned
    102 Post(s)
    Tagged
    2 Thread(s)
    vBActivity - Stats
    Points
    5,527
    Level
    23
    vBActivity - Bars
    Lv. Percent
    13.96%
    You just made my day. Thanks Saffith.


    edit: I use this meme way too much. XD
    @Saffith
    I am laughing so hard right now. Burt the Bashful anyone?

    * GHD_SHRINK
    * The enemy grows slightly and then shrinks away to nothing. This does not
    * work with enemies that use additional combos.
    Last edited by Tamamo; 10-06-2015 at 01:53 PM.

  3. #33
    The Timelord
    QDB Manager
    ZC Developer

    Join Date
    Oct 2006
    Location
    Prydon Academy
    Posts
    1,396
    Mentioned
    112 Post(s)
    Tagged
    1 Thread(s)
    vBActivity - Stats
    Points
    4,761
    Level
    21
    vBActivity - Bars
    Lv. Percent
    69.08%
    Nice one. Are you adding a backward-compatibility setting, as a constant for this?

    Code:
    const int GHOST_USE_ENEMY_NAMES_FOR_SCRIPTS = 1; 
    
    if ( GHOST_USE_ENEMY_NAMES_FOR_SCRIPTS ) gohst_use_at_sign_routines();
    else ghost_use_misc11_misc12();
    Something like that would be good. Just set the constant in the main header file, and use it as needed. That will prevent conflicts with games that are built on the old system.

  4. #34
    Is this the end?
    ZC Developer
    Saffith's Avatar
    Join Date
    Jan 2001
    Age
    41
    Posts
    3,389
    Mentioned
    178 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,432
    Level
    24
    vBActivity - Bars
    Lv. Percent
    69.88%
    __GH_ALWAYS_USE_NAME. It's disabled by default.

  5. #35
    The Timelord
    QDB Manager
    ZC Developer

    Join Date
    Oct 2006
    Location
    Prydon Academy
    Posts
    1,396
    Mentioned
    112 Post(s)
    Tagged
    1 Thread(s)
    vBActivity - Stats
    Points
    4,761
    Level
    21
    vBActivity - Bars
    Lv. Percent
    69.08%
    Quote Originally Posted by Saffith View Post
    __GH_ALWAYS_USE_NAME. It's disabled by default.
    Gorgeous.

  6. #36
    Here lies mero. Died by his own dumbassitude.
    Join Date
    May 2011
    Posts
    929
    Mentioned
    102 Post(s)
    Tagged
    2 Thread(s)
    vBActivity - Stats
    Points
    5,527
    Level
    23
    vBActivity - Bars
    Lv. Percent
    13.96%
    @Saffith

    Have an issue with sideview shenanigans "Sideview Gravity ugh..."
    So just ghost.zh take care of it on its' own as far Ghost_Z is concerned?

  7. #37
    Is this the end?
    ZC Developer
    Saffith's Avatar
    Join Date
    Jan 2001
    Age
    41
    Posts
    3,389
    Mentioned
    178 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,432
    Level
    24
    vBActivity - Bars
    Lv. Percent
    69.88%
    What problem are you having?

    Hm, I thought Ghost_Z affected ghost->Y in sideview, but it looks like it's not as consistent as it should be. It's likely to be a bit messy at best, but I could probably improve on it.

  8. #38
    Here lies mero. Died by his own dumbassitude.
    Join Date
    May 2011
    Posts
    929
    Mentioned
    102 Post(s)
    Tagged
    2 Thread(s)
    vBActivity - Stats
    Points
    5,527
    Level
    23
    vBActivity - Bars
    Lv. Percent
    13.96%
    That may be my problem then.
    I'm setting Ghost_Y to 160 each frame. "It's Barba"

  9. #39
    Here lies mero. Died by his own dumbassitude.
    Join Date
    May 2011
    Posts
    929
    Mentioned
    102 Post(s)
    Tagged
    2 Thread(s)
    vBActivity - Stats
    Points
    5,527
    Level
    23
    vBActivity - Bars
    Lv. Percent
    13.96%
    CODE: Show
    const int BARBA_QUAKE_TIME = 80; //Time in frames to shake the screen for.
    const int BARBA_QUAKE_SFX = 61; //This should loop on it's own. LTTP has a good one. DO NOT SET TO BARBA'S DEFAULT ROAR SFX! IT WILL BREAK EVERYTHING!
    const int BARBA_WATER_OKAY = 1; //Whether he will surface from water.
    const int BARBA_PITS_OKAY = 1; //Whether he will emerge from pits.

    ffc script Barba
    {
    void run(int enemyID)
    {
    // Init
    npc head = Ghost_InitAutoGhost(this,enemyID);
    npc body = Screen->CreateNPC(enemyID);
    head->DrawXOffset+=1000;
    body->DrawXOffset+=1000;
    Ghost_MarkAsInUse(body);
    Ghost_SetAllDefenses(body, NPCDT_IGNORE);

    // Position, Resize, and store Ghost_Data
    Ghost_X=256; Ghost_Y=176; //Spawn off screen;
    Ghost_Transform(this,head,-1,-1,2,1);
    int baseCombo=Ghost_Data;

    // Flags
    Ghost_SetFlag(GHF_4WAY);
    Ghost_SetFlag(GHF_NO_FALL);

    // Movement
    int movestate;
    int counter;
    int basePos; //Combo
    int ZVelocity=Ghost_GetAttribute(head,0,160)/100;
    int segmentCount=Ghost_GetAttribute(head,1,3,1,6);
    int segmentLag=Ghost_GetAttribute(head,2,10);
    int segmentCombo=Ghost_Data+12;
    int xoffsets[] = {-1,0,1,0,-1,0,1,0};
    // int movehistory[128]; //removed as their is no use now.

    // Attacking
    int attackTimer;
    int wDamage=head->WeaponDamage;
    int wSprite=Ghost_GetAttribute(head,3,-1);
    int wSound=Ghost_GetAttribute(head,4,-1);

    // Misc
    int dSound=head->SFX;
    int frame;
    int defenses[18];
    Ghost_StoreDefenses(head, defenses);

    // Barba Time!
    do
    {
    if(movestate==0) //Quake
    {
    if(head->SFX!=BARBA_QUAKE_SFX) BarbaQuake(head);
    else if(Screen->Quake==0)
    {
    movestate=1;
    counter=0;
    head->SFX=dSound;
    Ghost_SetDefenses(head,defenses);
    basePos = FindSpawnPoint(false,false,BARBA_WATER_OKAY,BARBA_ PITS_OKAY);
    BarbaHitOffsets(head);
    Ghost_X=ComboX(basePos)-8;
    Ghost_Y=ComboY(basePos);
    }
    }
    else if(movestate==1) //Surfacing
    {
    Ghost_Data=baseCombo;
    counter++;
    Ghost_Z+=ZVelocity;
    if(counter==segmentCount*segmentLag)
    {
    Ghost_Z=(segmentCount*16);
    movestate=2;
    counter=0;
    attackTimer=0;
    }
    SegmentDrawing(head, basePos, counter, segmentLag, segmentCombo, xoffsets);
    }
    else if(movestate==2) //Attacking
    {
    Ghost_Data=baseCombo+4;
    if(counter==32)
    {

    Ghost_Data=baseCombo+8;
    if(attackTimer==0)
    attackTimer=Rand(50,99);
    if(attackTimer%8==0)
    {
    float x=BarbaMouthX();
    float y=head->Y+InFrontY(Ghost_Dir,3);
    eweapon e=FireAimedEWeapon(EW_FIREBALL, x, y, 0, 300, wDamage,wSprite,wSound,NULL); //|EWF_UNBLOCKABLE); No... and never again rapid fire unblockable is a bad idea.
    }
    attackTimer--;
    }
    else if(counter==48)
    {
    movestate=3;
    counter=segmentCount*segmentLag;
    }
    if(attackTimer==0)
    counter++;
    SegmentDrawing(head, basePos, segmentCount*segmentLag, segmentLag, segmentCombo, xoffsets);
    }
    else if(movestate==3) //Submerging
    {
    Ghost_Data=baseCombo;
    counter--;
    Ghost_Z-=ZVelocity;
    if(counter<=0)
    {
    movestate=0;
    counter=0;
    Ghost_Z=0;
    Ghost_X=256+Ghost_TileWidth;
    }
    SegmentDrawing(head, basePos, counter, segmentLag, segmentCombo, xoffsets);
    }
    frame++;
    if(frame%8==0)
    {
    //pushfront and loop front to back
    int front = xoffsets[0];
    memmove(xoffsets, 0, xoffsets, 1, 7);
    xoffsets[7]=front;
    frame=0;
    }
    BarbaWaitframe(this,head,body,basePos);
    } while(Ghost_HP>0)
    if(movestate==2)
    counter=segmentCount*segmentLag;
    BarbaExplode(this, head, body, counter, segmentLag, segmentCombo, xoffsets, basePos);
    }
    void BarbaQuake(npc head)
    {
    Screen->Quake=BARBA_QUAKE_TIME;
    head->SFX=BARBA_QUAKE_SFX;
    Ghost_SetAllDefenses(head,NPCDT_IGNORE);
    }

    int BarbaMouthX()
    {
    int aimx=Ghost_X+8;
    return aimx+InFrontX(Ghost_Dir, 3);
    }
    void BarbaHitOffsets(npc head)
    {
    if(Ghost_Dir==DIR_LEFT)
    Ghost_SetHitOffsets(head,0,0,0,.25);
    else if(Ghost_Dir==DIR_RIGHT)
    Ghost_SetHitOffsets(head,0,0,.25,0);
    else // if(Ghost_Dir==DIR_UP || Ghost_Dir==DIR_DOWN);
    Ghost_SetHitOffsets(head,0,0,.25,.25);
    }
    void BarbaWaitframe(ffc this, npc head, npc body, int basePos)
    {
    body->X=ComboX(basePos);
    if(IsSideview())
    {
    body->Y=160;
    body->Jump=0; //keep it from falling do to sideview gravity
    if(Ghost_X+8>=Link->X) Ghost_Dir=DIR_LEFT;
    else Ghost_Dir=DIR_RIGHT;
    }
    else
    {
    body->Y=ComboY(basePos);
    Ghost_Dir=RadianAngleDir4(ArcTan(Link->X-(Ghost_X+8),Link->Y-Ghost_Y));
    }
    body->HitZHeight=Ghost_Z;
    Ghost_Waitframe(this,head,false,false);
    }
    void BarbaExplode(ffc this, npc head, npc body, int counter, int segmentLag, int segmentCombo, int xoffsets, int basePos) //Custom Death cause why not? o_O
    {
    //Miscellaneous Crap that has to be done first.
    body->ItemSet=IS_NONE;
    body->HP=HP_SILENT;
    body->X=1024;
    __DeathAnimStart(this, head);
    __DeathAnimSFX(head->ID, head->X);
    __Ghost_FlashCounter=10000; //Should last long enough.
    int baseX=ComboX(basePos);
    int baseY=ComboY(basePos);
    int segmentCount = Div(counter,segmentLag);
    int layer=3; int x; int y; int x2; int y2;
    int timer;
    int j=0;
    if(!IsSideview())
    {
    head->DrawXOffset-=1000;
    Ghost_Y-=Ghost_Z;
    Ghost_Z=0;
    }
    lweapon explosion;

    while(j<segmentCount)
    {

    for(int i=j; i < segmentCount; i++)
    {
    x = baseX+xoffsets[i];
    y = Cond(IsSideview(),160,baseY)-16*i;
    y -= Ghost_Y%16;
    if(i==j)
    {
    x2=x;
    y2=y;
    }
    Screen->FastCombo(layer,x,y-2,segmentCombo+Ghost_Dir,Ghost_CSet,128);
    }
    timer++;
    if(timer%16==0)
    {
    explosion=Screen->CreateLWeapon(LW_BOMBBLAST);
    explosion->X=x2;
    explosion->Y=y2;
    explosion->CollDetection=false;
    j++;
    }
    Ghost_SetPosition(this, head); // Make sure it doesn't wander off
    __Ghost_UpdateFlashing(this, head);
    Ghost_WaitframeLight(this,head);
    }

    baseX=Ghost_X+head->DrawXOffset;
    baseY=Ghost_Y+head->DrawYOffset;

    // One explosion every 16 frames, 15 times
    for(int i=0; i<15; i++)
    {
    explosion=Screen->CreateLWeapon(LW_BOMBBLAST);
    explosion->X=baseX+Rand(16*Ghost_TileWidth)-8;
    explosion->Y=baseY+Rand(16*Ghost_TileHeight)-8;
    explosion->CollDetection=false;

    for(int j=0; j<16; j++)
    {
    Ghost_SetPosition(this, head); // Make sure it doesn't wander off
    __Ghost_UpdateFlashing(this, head);
    Ghost_WaitframeLight(this, head);
    }
    }

    __DeathAnimEnd(this, head);
    }
    void SegmentDrawing(npc head, int basePos, int counter, int segmentLag, int segmentCombo, int xoffsets)
    {
    int baseX=ComboX(basePos);
    int baseY=Cond(IsSideview(),160,ComboY(basePos));
    int segmentCount = Div(counter,segmentLag);
    int layer=2;
    int x; int y;
    for(int i; i < segmentCount; i++)
    {
    x = baseX+xoffsets[i];
    y = baseY-(16*i);
    if(!IsSideview() && (i*16) >= GH_DRAW_OVER_THRESHOLD) //additional segments have a drawover threshold.
    {
    layer=4;
    }
    y-=Ghost_Z%16;
    Screen->FastCombo(layer,x,y-2,segmentCombo+Ghost_Dir,Ghost_CSet,128);
    }
    int w=1;
    if(Ghost_Dir==DIR_LEFT||Ghost_Dir==DIR_RIGHT) w=2;
    x-=8;
    y=baseY-Ghost_Z;
    layer=Cond(Ghost_Z>=GH_DRAW_OVER_THRESHOLD,4,2);
    Screen->DrawCombo(4,x,y-2,Ghost_Data+Ghost_Dir,w,1,Ghost_CSet,-1,-1,0,0,0,0,0,true,128);
    }
    }


    example quest

    Lot of issues here, best to turn on collision hitbox cheat and see for yourself what's happening. Should reproduce the battle in sideview perfectly, but it does not.

    edit: Fixed!
    Last edited by Tamamo; 11-15-2015 at 02:07 PM.

  10. #40
    Here lies mero. Died by his own dumbassitude.
    Join Date
    May 2011
    Posts
    929
    Mentioned
    102 Post(s)
    Tagged
    2 Thread(s)
    vBActivity - Stats
    Points
    5,527
    Level
    23
    vBActivity - Bars
    Lv. Percent
    13.96%
    @Saffith
    I have a few suggestions.

    GHF_NO_SHADOW
    Unless there's a way to disable the shadow that I don't know of.

    EWM_VEER_ANGLE
    EWM_DRIFT_ANGLE
    EWM_DRIFT_WAIT_ANGLE
    Same as normal except they move towards an angle.

    EWD_FIRETRAIL.
    For the pyro in all of us.
    Last edited by Tamamo; 11-15-2015 at 02:07 PM.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
About us
Armageddon Games is a game development group founded in 1997. We are extremely passionate about our work and our inspirations are mostly drawn from games of the 8-bit and 16-bit era.
Social