Jump to content

Photo

Twin Amoeba (AutoGhost)

Enemy FFC

  • Please log in to reply
17 replies to this topic

#1 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 11 December 2012 - 09:37 AM

Twin Amoeba


Description

This enemy consists of two slimes and a single core. The core is the only part that can be damaged, and it jumps from one slime to the other when it gets hurt or Link is too close. Optionally, it can jump whenever a weapon is too close.

Screenshots and Demo

Demo

Code

Script


Setup

Set up two enemies as follows:

Core:
Type: Other
Animation: 2-Frame, 3-Frame, 4-Frame, Flip, or (None)
Attribute 1: ID number of slime enemy
Attribute 2: Jumping sound
Attribute 3: Landing sound
Attribute 4: Jump when any weapon is near?
- 0: No
- 1: Yes
Attribute 11: -1
Attribute 12: Script slot

Slime: Anything should work, but an ordinary walking enemy is generally recommended. Do not set misc. attributes 11 or 12.

Only the core enemy needs to be placed on the screen. The slimes will be spawned automatically.

Resources

Requires ghost.zh, std.zh, and string.zh.
Tiles are here.

#2 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 20 December 2012 - 05:24 PM

Help error noooooooo! icon_disgust.gif

Pass 1: Parsing
Pass 2: Preprocessing
Can't open input file
ghost.zh, line 89: Error P01 : Failure to parse imported file ghost_zh/update.zh.

my script

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


const float TWA_JUMP_SPEED=2; // Speed in pixels per frame when jumping

// npc->Attributes[] indices
const int TWA_ATTR_SLIME_ID=0;
const int TWA_ATTR_JUMP_SOUND=1;
const int TWA_ATTR_LAND_SOUND=2;
const int TWA_ATTR_JUMPY=3;

ffc script TwinAmoeba
{
    void run(int enemyID)
    {
        npc ghost;
        npc slime[2];
        int currentSlime;
        bool jumpy;
        lweapon wpn;
        int i;
        
        // Initialize
        ghost=Ghost_InitAutoGhost(this, enemyID);
        Ghost_SetFlag(GHF_NO_FALL);
        Ghost_SetFlag(GHF_CLOCK);
        Ghost_SetFlag(GHF_SET_OVERLAY);
        Ghost_SpawnAnimationPuff(this, ghost);
        currentSlime=0;
        jumpy=ghost->Attributes[TWA_ATTR_JUMPY]!=0;
        
        // Create the first slime at the core's position; the second is randomly placed
        slime[0]=Screen->CreateNPC(ghost->Attributes[TWA_ATTR_SLIME_ID]);
        slime[0]->X=Ghost_X;
        slime[0]->Y=Ghost_Y;
        slime[1]=SpawnNPC(ghost->Attributes[TWA_ATTR_SLIME_ID]);
        
        Ghost_SetAllDefenses(slime[0], NPCDT_IGNORE);
        Ghost_SetAllDefenses(slime[1], NPCDT_IGNORE);
        
        while(true)
        {
            // If the core just got hit, jump to the other slime
            if(Ghost_GotHit())
            {
                SlimeJump(this, ghost, slime[currentSlime], slime[currentSlime^1], true);
                currentSlime^=1; // Switch index between 0 and 1
            }
            // If Link is too close and the other slime is farther, jump over
            else if(Distance(Ghost_X, Ghost_Y, Link->X, Link->Y)<32)
            {
                if(SlimeJump(this, ghost, slime[currentSlime], slime[currentSlime^1], false))
                    currentSlime^=1;
            }
            else if(jumpy)
            {
                // Jumpy ones jump whenever a weapon is too close
                for(i=Screen->NumLWeapons(); i>0; i--)
                {
                    wpn=Screen->LoadLWeapon(i);
                    
                    // This could be a lot of checks, so just look at X and Y difference
                    if(Abs(wpn->X-Ghost_X)<32 && Abs(wpn->Y-Ghost_Y)<32)
                    {
                        SlimeJump(this, ghost, slime[currentSlime], slime[currentSlime^1], true);
                        currentSlime^=1;
                        break;
                    }
                }
            }
            
            Ghost_X=slime[currentSlime]->X;
            Ghost_Y=slime[currentSlime]->Y;
            
            TwAWaitframe(this, ghost, slime[0], slime[1]);
        }
    }
    
    
    // Jump from one slime to the other. If not forced, it won't jump if the other slime is
    // closer to Link. Returns true if it jumps, false if not.
    bool SlimeJump(ffc this, npc ghost, npc startSlime, npc destSlime, bool force)
    {
        // If not forced, see if the destination slime is closer to Link than the starting slime;
        // if so, don't do anything
        if(!force)
        {
            if(Distance(startSlime->X, startSlime->Y, Link->X, Link->Y)>=Distance(destSlime->X, destSlime->Y, Link->X, Link->Y))
                return false;
        }
    
        int startX;
        int startY;
        int targetX;
        int targetY;
        float angle;
        float totalDist;
        float currentDist;
        
        // Ignore clocks while jumping so the core doesn't get stuck in midair
        Ghost_UnsetFlag(GHF_CLOCK);
        Game->PlaySound(ghost->Attributes[TWA_ATTR_JUMP_SOUND]);
        
        // Jump
        do
        {
            // Get the current position of the two slimes
            startX=startSlime->X;
            startY=startSlime->Y;
            targetX=destSlime->X;
            targetY=destSlime->Y;
            
            // Move toward one from the other
            angle=Angle(Ghost_X, Ghost_Y, targetX, targetY);
            Ghost_X+=VectorX(TWA_JUMP_SPEED, angle);
            Ghost_Y+=VectorY(TWA_JUMP_SPEED, angle);
            
            // Set height based on how much of the total distance has been covered
            totalDist=Distance(startX, startY, targetX, targetY);
            currentDist=Distance(Ghost_X, Ghost_Y, targetX, targetY);
            Ghost_Z=totalDist/2*Sin(currentDist/totalDist*180);
            
            TwAWaitframe(this, ghost, startSlime, destSlime);
        } while(currentDist>1);
        
        Ghost_Z=0;
        Ghost_SetFlag(GHF_CLOCK);
        Game->PlaySound(ghost->Attributes[TWA_ATTR_LAND_SOUND]);
        return true;
    }
    
    
    void TwAWaitframe(ffc this, npc ghost, npc slime1, npc slime2)
    {
        // The slimes should be invincible, but if one becomes invalid, kill everything
        if(!slime1->isValid())
        {
            ghost->HP=0;
            if(slime2->isValid())
                slime2->HP=0;
            this->Data=0;
            Quit();
        }
        else if(!slime2->isValid())
        {
            ghost->HP=0;
            slime1->HP=0;
            this->Data=0;
            Quit();
        }
        
        // Still valid - try to keep them alive, no matter what
        else
        {
            if(slime1->HP<32768)
                slime1->HP=32768;
            if(slime2->HP<32768)
                slime2->HP=32768;
        }
        
        // If the core is dead, kill the slimes as well
        if(!Ghost_Waitframe(this, ghost, true, false))
        {
            slime1->HP=0;
            slime2->HP=0;
            Quit();
        }
    }
}

I'm using Autoghost script version 2.5 RC5 latest version

Edited by Da Masta Sord, 20 December 2012 - 05:25 PM.


#3 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 20 December 2012 - 05:49 PM

You probably didn't extract the ghost_zh directory, which needs to go into the ZC directory along with ghost.zh.

#4 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 20 December 2012 - 06:03 PM

I didn't see a ghost_zh directory in the ghost.zh download 2.5 RC5 version file
do you extract the files with a zip program first because I did that.Is there a ghost_zh directory somwhere ?
I did see the ghost_legacy.zh

Edited by Da Masta Sord, 20 December 2012 - 07:55 PM.


#5 MoscowModder

MoscowModder

    Still fighting the inevitable

  • Members
  • Gender:Male
  • Location:Wisconsin (WHAT)

Posted 20 December 2012 - 11:19 PM

Ghost.zh does not come with ZC. It needs to be downloaded separately, from the ghost.zh thread.

#6 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 21 December 2012 - 12:38 AM

I downloaded that whole pack into my 2.5 RC5 folder my game folder I don't know what to do I get this error Pass 1: Parsing
Pass 2: Preprocessing
Can't open input file
ghost.zh, line 89: Error P01 : Failure to parse imported file ghost_zh/update.zh

I looked at your post in ghost.zh I found the awnser I did not EXTRACT it into the file but it works now Thank You Soooooo mutch!
Moscow Modder I always appreciate your help you always come through for me.

#7 The Satellite

The Satellite

    May the way of the Hero lead to the Triforce.

  • Administrators
  • Real Name:Michael
  • Gender:Male

Posted 21 December 2012 - 01:02 AM

Da Master Sord, I have merged your posts. Please, there is no need to make a second post if a significant amount of time hasn't passed; just use the IPB Image button if you need to update your post.

#8 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 21 December 2012 - 01:14 AM

I get this weird glitch The enemies spawn and randomly a whole bunch of Amoeba cores head to the bottem right corner of the screen dissapearing off of it It also spawns more Cores than one and no Twin Amoebas and then it spawns random grass tiles under the Cores I don't know what to do I think I followed everything to a T

#9 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 21 December 2012 - 08:18 AM

You're seeing grass tiles because you haven't set the shadow constants in ghost.zh. It's spawning more and flying offscreen because you put the core's ID as attribute 1 rather than the slime's.

#10 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 21 December 2012 - 10:48 AM

okay Thank You

#11 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 21 December 2012 - 11:27 AM

Where are the shadow constants

#12 ShadowTiger

ShadowTiger

    ยท

  • Members
  • Gender:Unspecified

Posted 21 December 2012 - 11:37 AM

My guess, is that it's the following lines at the top of ghost.zh:

CODE
// Shadow settings
const int GH_SHADOW_TILE = 1816;
const int GH_SHADOW_CSET = 6;
const int GH_SHADOW_TRANSLUCENT = 0; // 0 = No, 1 = Yes
const int GH_SHADOW_FLICKER = 0; // 0 = No, 1 = Yes


Open Ghost.zh in Notepad++ (Google for it) or just notepad, and it's pretty much at the top. You can see which tile it is in ZQuest's tile pages when you click on the shadow, it shows you near the bottom-center of the screen.

#13 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 21 December 2012 - 12:22 PM

They still have the grass tiles under them and they jump and die immediatly HOW do you set the Shadow Constans in std.zh like what numbers do you use right now i'm using the DOR tileset 2.0 so where are the shadow tiles

Edited by Da Masta Sord, 21 December 2012 - 12:39 PM.


#14 MoscowModder

MoscowModder

    Still fighting the inevitable

  • Members
  • Gender:Male
  • Location:Wisconsin (WHAT)

Posted 21 December 2012 - 10:03 PM

The shadow constants are in ghost.zh, not std.zh. Edit ghost.zh to change them.

To find them, open up your tilepage and look for a tile that looks like a shadow.

#15 Da Masta Sord

Da Masta Sord

    The Official Masta Sord of ZC.

  • Members
  • Gender:Male
  • Location:In a pedastal in the lost woods.

Posted 22 December 2012 - 01:55 AM

I edited it and the Slimes work fine icon_w00t.gif but the core still has that grass tile under icon_dead.gif it but it acts right so my last problem is that

My ghost.zh

CODE
// ghost.zh
// Version 2.5.1

// See ghost.txt for documentation.

// Standard settings -----------------------------------------------------------

// Shadow settings
const int GH_SHADOW_TILE = 631;
const int GH_SHADOW_CSET = 2;
const int GH_SHADOW_FRAMES = 4;
const int GH_SHADOW_ANIM_SPEED = 8;
const int GH_SHADOW_TRANSLUCENT = 1; // 0 = No, 1 = Yes
const int GH_SHADOW_FLICKER = 0; // 0 = No, 1 = Yes

// AutoGhost settings
const int AUTOGHOST_MIN_FFC = 1; // Min: 1, Max: 32
const int AUTOGHOST_MAX_FFC = 32; // Min: 1, Max: 32
const int AUTOGHOST_MIN_ENEMY_ID = 20; // Min: 20, Max: 511
const int AUTOGHOST_MAX_ENEMY_ID = 511; // Min: 20, Max: 511

// Other settings
const int GH_DRAW_OVER_THRESHOLD = 32;
const float GH_GRAVITY = 0.16;
const float GH_TERMINAL_VELOCITY = 3.2;
const int GH_SPAWN_SPRITE = 22; // Min: 0, Max: 255, Default: 22
const int GH_FAKE_Z = 0; // 0 = No, 1 = Yes
const int GH_ENEMIES_FLICKER = 0; // 0 = No, 1 = Yes

// Top-left corner of a 4x4 block of blank tiles
const int GH_BLANK_TILE = 65456; // Min: 0, Max: 65456

// Invisible combo with no properties set
const int GH_INVISIBLE_COMBO = 1; // Min: 1, Max: 65279

// End standard settings -------------------------------------------------------



// Advanced settings -----------------------------------------------------------

// AutoGhost will read a script name from the enemy's name if attribute 12
// is set to this. Must be a negative number.
const int AUTOGHOST_READ_NAME = -1;

// When reading a script from the enemy name, this character marks the
// beginning of the script name
const int AUTOGHOST_DELIMITER = 64;

// Misc. attribute 11 can be set to this instead of GH_INVISIBLE_COMBO. Must be
// a negative number.
const int __GH_INVISIBLE_ALT = -1;

// This will use the invisible combo, but also set npc->Extend to 3, hiding
// the initial spawn puff. Must be a negative number.
const int __GH_INVISIBLE_EXTEND = -2;

// If enabled, the FFC will be invisible, and Screen->DrawCombo will be used
// to display enemies.
const int __GH_USE_DRAWCOMBO = 1;

// Enemies flash or flicker for this many frames when hit. This does not
// affect enemies that use the invisible combo.
// Default: 32
const int __GH_FLASH_TIME = 32;

// Enemies will be knocked back for this many frames when hit.
// Default: 16
// Max: 4095
const int __GH_KNOCKBACK_TIME = 16;

// The speed at which enemies are knocked back, in pixels per frame.
// Default: 4
const int __GH_KNOCKBACK_STEP = 4;

// npc->Misc[] index
// Set this so it doesn't conflict with other scripts. Legal values are 0-15.
const int __GHI_GHZH_DATA = 15;

// eweapon->Misc[] indices
// These must be unique numbers between 0 and 15.
const int __EWI_DUMMY_SOUND  = 1; // Only used by dummies
const int __EWI_DUMMY_STEP   = 2; // Only used by dummies
const int __EWI_DUMMY_SPRITE = 3; // Only used by dummies
const int __EWI_ID           = 4;
const int __EWI_XPOS         = 5;
const int __EWI_YPOS         = 6;
const int __EWI_WORK         = 7;
const int __EWI_WORK_2       = 8; // Only used by a few movement types
const int __EWI_MOVEMENT     = 9;
const int __EWI_MOVEMENT_ARG = 10;
const int __EWI_LIFESPAN     = 11;
const int __EWI_LIFESPAN_ARG = 12;
const int __EWI_ON_DEATH     = 13;
const int __EWI_ON_DEATH_ARG = 14;
const int __EWI_FLAGS        = 15; // Every index but this one can be used by non-ghost.zh EWeapons

// End advanced settings -------------------------------------------------------


//import "ghost_zh/clock.zh"
import "ghost_zh/common.zh"
import "ghost_zh/deprecated.zh"
import "ghost_zh/eweapon.zh"
import "ghost_zh/flags.zh"
import "ghost_zh/global.zh"
import "ghost_zh/init.zh"
import "ghost_zh/modification.zh"
import "ghost_zh/movement.zh"
import "ghost_zh/other.zh"
import "ghost_zh/scripts.zh"
import "ghost_zh/update.zh"

Edited by Da Masta Sord, 22 December 2012 - 02:01 AM.




Also tagged with one or more of these keywords: Enemy, FFC

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users