User Tag List

Page 1 of 2 1 2 LastLast
Results 1 to 10 of 42

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

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    I shall exalt myself over all Armagedddon Games bigjoe's Avatar
    Join Date
    Apr 2000
    Age
    39
    Posts
    5,622
    Mentioned
    87 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,576
    Level
    24
    vBActivity - Bars
    Lv. Percent
    93.96%
    First boss I made with it:

    Code:
    // Zora King
    
    
    // Will work best with a Freeform Combo set to Combo W: 32, Combo H: 32, Tile W: 2, Tile H: 2, with provided graphics.
    // NOTE: Using a SkipX setting of 1 on the combo will allow 
    // you to animate using 2x2 tile chunks.
    // D0 - The number pointing to another Freeform Combo 
    // Used to display the diving, as well as house more variables.
    // (Check below for details)
    // D1 - The total duration the zora will stay on the screen. 
    // D2 - Enemy Type to use for ghosting
    // D3 - Total hit points
    // D4 - Fire every this amount of frames when above water;
    // D5 - Damage of projectile;
    // D6 - Fireballs Per Shot (set to an odd number up to 9. Even numbers may function but are not recommended)
    // D7 - Sprite to use for fireball
    
    
    // As mentioned above, further customization is allowed by
    // By using the D variables stored in the FFC called by D0
    // D0 = Projectile movement pattern(0 for normal shot)
    // D1 = Projectile movement argument (0 for none)
    // See ghost.zh for its EWM constants for what to use as patterns
    // See ghost_zh_readme.txt for what to use as argument.
    
    
    // Use ZRB_CHECKPOINT Floats to specify in percentages when the Zora will be submerged, rise, appear, and sink.
    
    const float ZRB_CHECKPOINT1 = 0.30;// Time From Phase 1 to 2. Decimal indicates a percentage.
    const float ZRB_CHECKPOINT2 = 0.45;// Time From Phase 2 to 3. Decimal indicates a percentage.
    const float ZRB_CHECKPOINT3 = 0.60;// Time from Phase 3 to 4. Decimal indicates a percentage.
    const float ZRB_CHECKPOINT4 = 0.75;// Time from Phase 4 to end(staytime). Decimal indicates a percentage.
    
    
    
    const int ZRB_PRJ_X_OFFSET = 8; // Offset of projectile from origin in X
    const int ZRB_PRJ_Y_OFFSET = 16; // Offset of projectile from origin in Y
    
    
    
    
    ffc script zora_king
    {
    
    
    //Running part of script
        void run(int diveffc_s, int staytime, int enemtype, int enemhp, int fireat, int firedmg, int fireperarc, int firesprite)
        {
        npc zoraboss;
        eweapon zora_fire;
        
    
    //Loads an FFC 
        ffc diveffc = Screen->LoadFFC(diveffc_s);
        int fire_mtype = diveffc->InitD[0];
        int fire_arg = diveffc->InitD[1];
        
        TraceNL();
        Trace(fire_mtype);
        TraceNL();
        Trace(fire_arg);
        
        
    
        
        
    
        int time_check = 0;
        int water_check = 1;
    
        int checkpoint_1 = (staytime*ZRB_CHECKPOINT1);
        int checkpoint_2 = (staytime*ZRB_CHECKPOINT2);
        int checkpoint_3 = (staytime*ZRB_CHECKPOINT3);
        int checkpoint_4 = (staytime*ZRB_CHECKPOINT4);
        
    
        int pop_up_x = 16 * Rand(15);
        int pop_up_y = 16 * Rand(10);
        
        zoraboss = GhostInitCreate(this,enemtype);
        SetHP(this,zoraboss,enemhp);
        
    
        while(true){
        
            if(water_check == 1){pop_up_x = 16 * Rand(15);pop_up_y = 16 * Rand(10); water_check = 0;}
        
        if(IsWater(ComboAt(pop_up_x,pop_up_y)) && IsWater(ComboAt(pop_up_x + 16,pop_up_y)) && IsWater(ComboAt(pop_up_x,pop_up_y + 16)) && IsWater(ComboAt(pop_up_x + 16,pop_up_y + 16))){} else {pop_up_x = 16 * Rand(15);pop_up_y = 16 * Rand(10);}
        
        if(time_check < staytime) time_check++;    
        
        if(time_check <= checkpoint_1){
        
        change_x_y_2(this, 256, 176, diveffc, 256, 176);
        
        }
        
        if(time_check > checkpoint_1 && time_check <= checkpoint_2){
        
        change_x_y_2(this, 256, 176, diveffc, pop_up_x, pop_up_y);
        
        }
    
        if(time_check > checkpoint_2 && time_check <= checkpoint_3){
        
        change_x_y_2(this, pop_up_x, pop_up_y, diveffc, 256, 176);
        
        if(time_check % fireat == 0){
        
        if (fireperarc >= 1){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0) SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        }
        
        if (fireperarc >= 3){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, -0.1, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0.1, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        
        }
        
        if (fireperarc >= 5){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, -0.2, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0.2, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        
        }
        
        if (fireperarc >= 7){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, -0.3, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0.3, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        }
        
        if (fireperarc >= 9){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, -0.4, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0.4, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        }
        
        if (fireperarc >= 11){
        
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, -0.5, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        zora_fire=FireAimedEWeapon(129, this->X + ZRB_PRJ_X_OFFSET, this->Y + ZRB_PRJ_Y_OFFSET, 0.5, 200, firedmg,false, firesprite, false, 0);
        if(fire_mtype > 0)SetEWeaponMovement(zora_fire, fire_mtype, fire_arg);
        
        }
        
        
        
        }
        
        }
    
        if(time_check > checkpoint_3 && time_check <= checkpoint_4){
        
        change_x_y_2(this, pop_up_x, pop_up_y, diveffc, 256, 176);
        
        }
        
        if(time_check > checkpoint_4 && time_check <= staytime){
        
        change_x_y_2(this, 256, 176, diveffc, pop_up_x, pop_up_y);
        }
        
        if(time_check >= staytime){water_check = 1; time_check = 0;}
    
        GhostWaitframeF(this, zoraboss, true, true);
        
        }
    
    
    
    
        }
        void change_x_y_2(ffc f1, int x1, int y1, ffc f2, int x2, int y2)
        {
        f1->X = x1;
        f1->Y = y1;
        
        f2->X = x2;
        f2->Y = y2;
        
        }
    
        }


  2. #2
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    Updated. It needs build 1326+ now, so it's only for Linux and the debug build at the moment.
    - Fixed a couple of small bugs.
    - Enemies can now have combos set automatically based on direction.
    - Added a function to adjust the enemy's hitbox.
    - Eweapons can now flicker and cast shadows, and there's now a falling movement type.
    - Added functions to create eweapons larger than 1x1.
    - The SetFlags() and all three FireEWeapon functions have changed; the old versions are deprecated.

    I've also added on to the demo. Do try it, I'm rather proud of it. If you can't/won't play it, I also made a video of it.

    Also, bigjoe, you'd suggested adding functions for lweapons and items? Not a bad idea, but I think that'd be a different file. I probably will do that in the future.

  3. #3
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    So, I kind of screwed up the last update. The link was pointing to an older version. Sorry. Fixed now.

  4. #4
    I shall exalt myself over all Armagedddon Games bigjoe's Avatar
    Join Date
    Apr 2000
    Age
    39
    Posts
    5,622
    Mentioned
    87 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,576
    Level
    24
    vBActivity - Bars
    Lv. Percent
    93.96%
    I have a suggestion for a function:

    GhostWaitframeR

    This would be the same as GhostWaitframeN but it would allow you to specify a location relative to the NPC. (Negative or positive integers.)

    The reason I suggest this is that when I try to do that manually using GhostWaitframeM, both npc and ffc fly diagonally until they disappear. I guess its because they both have to be the same in the function.


  5. #5
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    I was thinking about adding something like that at one point, but I couldn't come up with anything I liked. The idea being that you might not want the hitbox to match the enemy's appearance, which ended up as SetOffsets() instead. Do you have a different purpose in mind?

    Another possibility is that it could acknowledge the npc->DrawOffset variables and position the FFC where the enemy would normally be drawn. What do you think of that?

    Edit: Actually, come to think of it, could you just use the npc->HitOffsets?

  6. #6
    I shall exalt myself over all Armagedddon Games bigjoe's Avatar
    Join Date
    Apr 2000
    Age
    39
    Posts
    5,622
    Mentioned
    87 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,576
    Level
    24
    vBActivity - Bars
    Lv. Percent
    93.96%
    I think I've found a pretty reasonable workaround.. but what I was trying to do was make the FFC follow a position relative to the NPC. The collision would still be the same as the FFC, just the position would be different. This is to make a bigger enemy that behaves exactly like the small one(but has the larger collision)

    My workaround will use two separate npcs.


  7. #7
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    Updated.

    • All ffc->Misc[] data has been moved to npc->Misc[]. Any scripts accessing these directly or using GotHit() will have to be updated.
    • npc->Misc[GHI_BASE_CSET] is no longer needed; npc->CSet is used instead.
    • Added SetCSet() and RevertCSet().
    • GhostInitWait2() has changed; the argument specifying which enemy to use is no longer needed. Instead, it finds the first one that's not already in use by another script. The old version of the function is deprecated, and the obsolete argument is ignored.
    • Added flags to make enemies ignore solid combos, water, and pits.
    • npc->TileWidth and npc->TileHeight are now set by the Init functions and Transform(), so shadows should be drawn in the right place in beta 18 and up.
    • Added DrawSpawnAnimation(), which lets you show the enemy spawning graphic that gets cut off by the Init functions.
    • If GH_BLANK_TILE is set and the enemy used has a frame rate of 0 (or 256, since ZC changes 0 to 256), the enemy's tile will be set to a clear one automatically. This way, you can give the enemy a visible tile so it shows up in the enemy panel in ZQuest's large mode.
    • Added an internal EWeapon flag that marks the weapon as having been spawned by ghost.zh. This allows other scripts to use all but one element of eweapon->Misc[] without causing confusion.
    • Reworked SpawnNPC() to increase the minimum distance from Link.
    • ghost_zh_readme.txt has been renamed ghost.txt to match other header files' documentation.


    Edit: Sorry, quick update. I screwed up the arguments to SetCSet() and RevertCSet(). They worked, but they were inconsistent with other functions, and I'm trying to avoid that. Anyway, it's fixed now.

  8. #8
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    All right, big update. Complete overhaul, in fact. Here are the biggest changes this version:

    Most enemy properties are now handled by global variables. There are only two standard Waitframe functions, Ghost_Waitframe and Ghost_Waitframe2. There's also a Ghost_WaitframeLight, but that'll generally be used only when the enemy is inactive. A lot of things that used to require a function can now be done just be setting one of the global variables. You can, for instance, set Ghost_HP to set the enemy's HP, set Ghost_CSet to change its CSet, or set Ghost_Data to change its combo, even if GHF_4WAY is set.

    There are two major new eweapon death options. First, you can create a dummy eweapon with whatever properties you like, including its own scripted movement, and have an eweapon spawn copies of it on death. Second, you can set up an FFC to run a script where the eweapon died, so you can do whatever you like there.

    Finally, the biggest new addition, AutoGhost. With appropriately written enemy scripts, the global script can set up FFCs automatically when enemies appear. That means scripted enemies can be used as easily as built-in ones, with no manual FFC setup at all. This requires at least RC2.

    This version is not backward compatible with existing scripts. However, there is a separate file, ghost_legacy.zh, included for this purpose.

    Also, thanks to Blaman/SpacemanDan for putting up with me through this. I know I can get a bit impatient at times. :p

    ghost.zh
    Demo quest and sample scripts
    AutoGhost enemies
    AutoGhost setup demo video
    Last edited by Saffith; 08-16-2011 at 12:16 PM.

  9. #9
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    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()


    Edit: Quickly followed by a bugfix update. :p
    Last edited by Saffith; 08-16-2011 at 12:16 PM.

  10. #10
    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,435
    Level
    24
    vBActivity - Bars
    Lv. Percent
    70.5%
    Another update.

    • There's now built-in support for multi-FFC enemies like Iflyte.
    • It's now possible to use Screen->DrawCombo rather than making the FFC itself visible. There are three advantages to this:
      • Enemies will correctly be drawn above layers 2 and 4 rather than 1 and 3 (currently, FFCs do appear above layers 2 and 4, but that's a bug).
      • Enemies disappear when the screen is scrolling.
      • Multi-FFC enemies don't actually require multiple FFCs.
    • Enemy blocking combos and flags are now respected.
      • Added GHF_FLYING_ENEMY, which controls whether ground/jumping or flying enemy blockers are checked.
      • Ghost_CanMove and Ghost_CanMovePixel now take an optional argument indicating whether the enemy is in the air; this defaults to Ghost_Z>0.
    • Added flags to restrict an enemies movement to water, including or excluding shallow water.
    • Added a setting to make all Z-axis movement actually use the Y axis.
    • Added a setting to make enemies flicker instead of flash.
    • You can now use an alternate number (-1 by default) instead of GH_INVISIBLE_COMBO to make enemies use the invisible combo.
    • GHF_ flags can no longer be ORed together; they must be set individually. Unfortunate, but it can't be helped; I ran out of bits.
    • Ghost_SetFlags and the init functions with a flags argument are deprecated.
    • Ghost_WaitframeLight now takes ffc and npc arguments. The old version is deprecated and may not work correctly with existing scripts if DrawCombo is enabled.

Thread Information

Users Browsing this Thread

There are currently 2 users browsing this thread. (0 members and 2 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