Jump to content

Photo

ghost.zh


  • Please log in to reply
615 replies to this topic

#586 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 29 December 2016 - 01:05 PM

@Saffith is there a way to retrieve the config from enemy editor? for ghosted enemies attached to builtin enemies?

 

basicly what I'm asking is is there a way to retrieve the following from the enemy editor

- HP

- Damage

- W. Damage

- Random Rate

- Halt Rate

- Homing Factor

- Step Speed

- Etc...

 

I ask this so that I can set my ghosted attributes to what they are defined as


Edited by Shadowblitz16, 29 December 2016 - 01:06 PM.


#587 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Gender:Male
  • Location:I wish I knew

Posted 29 December 2016 - 01:35 PM

You can access this information from the standard npc class found in std.zh then pass it to the appropriate ghost variables.

#588 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 29 December 2016 - 03:59 PM

how though I don't see anything regarding the options in the enemy editor listed in on the zc wiki

I see it it was in the zscript.txt file

 

however I was wondering how do I check for the hp of the ghosted enemy?

do I just use the npc parameter directly?

found this one too (inside ghostzh.txt)

 

also is there a way to disable collision with link? its for a leever.

found out that I just do  "ghost->CollDetection = false;"

 

however I would like to know how to access the ghosted ffc script's variables in outside functions

I tried passing "ffc this" and "npc ghost" to the function but the compilers say that it doesn't have that pointer type.


Edited by Shadowblitz16, 30 December 2016 - 02:42 PM.


#589 cavthena

cavthena

    Apprentice

  • Members
  • Real Name:Clayton
  • Gender:Male
  • Location:I wish I knew

Posted 30 December 2016 - 07:08 PM

however I would like to know how to access the ghosted ffc script's variables in outside functions

I tried passing "ffc this" and "npc ghost" to the function but the compilers say that it doesn't have that pointer type.

 

What exactly are you trying to access and from where?

 

Ghost has a mix of global and local variables.  You can pass all of them as arguments into a function.

Here is a snip-it from one of my enemies as an example of accessing and passing information from/into a function.

[...]
while(Ghost_Waitframe(this, Dragon, true, false)){
		
			//Dragon Movement.
			SegmentMove(DragonID, Rate, Dragon, this);
			
			//Update Timer and Rate.
			if(Rate == 0){
				Rate = 180;
			}
			else{
				Rate--;
			}
		
		}
[...]

void SegmentMove(int DragonID, int Rate, npc Dragon, ffc this){

	int X = Dragon->X;
	int Y = Dragon->Y;
	int Z = Dragon->Z;
	int X2;
	int Y2;
	int Z2;
	float DragonStep = Dragon->Step;
	
	//Find step speed
	for(int a = Screen->NumNPCs(); a > 0; a--){
		npc Temp = Screen->LoadNPC(a);
		if(Temp->isValid()){
			if(Temp->ID == Dragon->Attributes[1] && Temp->Misc[0] == DragonID){
				DragonStep -= 5;
			}
		}
	}
	
	if(!Ghost_CanMove(Ghost_Dir, DragonStep/100, 2) || Rate == 0){ //Find new direction.
		Ghost_Dir = Rand(0, 7);
	}
	else{
		Ghost_Move(Ghost_Dir, DragonStep/100, 2);
	}
	
	for(int Segment = Dragon->Attributes[0]; Segment >= -1; Segment--){
		for(int a = Screen->NumNPCs(); a > 0; a--){
			npc Temp = Screen->LoadNPC(a);
			if(Temp->isValid()){
				if((Temp->ID == Dragon->Attributes[1] || Temp->ID == Dragon->Attributes[2]) && Temp->Misc[0] == DragonID && Temp->Misc[1] == Segment){
				
					//Check if Distance is greater than 16.
					if(DragonCheckDistance(X, Y, Temp)){
						return;
					}
				
					//Save this segment's pos.
					X2 = Temp->X;
					Y2 = Temp->Y;
					Z2 = Temp->Z;
					//Set this segment's pos.
					Temp->X = Temp->X + (X - Temp->X); // /2
					Temp->Y = Temp->Y + (Y - Temp->Y); // /2
					//If Tail, set new direction.
					if(Temp->Misc[1] == -1){
						if(Temp->X == X2 && Temp->Y < Y2){ //DIR_UP
							Temp->Dir = DIR_UP;
						}
						else if(Temp->X > X2 && Temp->Y < Y2){ //DIR_RIGHTUP
							Temp->Dir = DIR_RIGHTUP;
						}
						else if(Temp->X > X2 && Temp->Y == Y2){ //DIR_RIGHT
							Temp->Dir = DIR_RIGHT;
						}
						else if(Temp->X > X2 && Temp->Y > Y2){ //DIR_RIGHTDOWN
							Temp->Dir = DIR_RIGHTDOWN;
						}
						else if(Temp->X == X2 && Temp->Y > Y2){ //DIR_DOWN
							Temp->Dir = DIR_DOWN;
						}
						else if(Temp->X < X2 && Temp->Y > Y2){ //DIR_LEFTDOWN
							Temp->Dir = DIR_LEFTDOWN;
						}
						else if(Temp->X < X2 && Temp->Y == Y2){ //DIR_LEFT
							Temp->Dir = DIR_LEFT;
						}
						else if(Temp->X < X2 && Temp->Y < Y2){ //DIR_LEFTUP
							Temp->Dir = DIR_LEFTUP;
						}
					}
					//Move saved [X,Y,Z] to Stored values.
					X = X2;
					Y = Y2;
					Z = Z2;
				}
			}
		}
	}
}


#590 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 31 December 2016 - 11:33 AM

@cavthena I'm trying to access custom variables that I have defined within a the ghosted ffc script  in a function outside the ghosted ffc script.



#591 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 31 December 2016 - 12:56 PM

You're gonna have to be more specific. Could you post the relevant code?

#592 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 31 December 2016 - 01:46 PM

I can post an example

//This enemy behaves like a Leever, but homes in on Link whenever it's above ground.
// This approximately recreates the behavior of Leevers in Link's Awakening,
// among other games.
//
//Enemy Attributes Used:
// -Step Speed: Determines speed (standard: 50)
// -Misc. Attr. 1: Frames that the enemy will spend underground (default: 60)
// -Misc. Attr. 2: Frames that the enemy will spend aboveground (default: 120)
// -Misc. Attr. 11: Combo index for enemy graphics
// -Misc. Attr. 12: FFC Script Slot
//
//The combos must be four consecutive combos:
// 1. Initial surfacing combo
// 2. Second surfacing combo
// 3. Above ground combo
// 4. Below ground combo (usually blank)
//The combos play in the order 4-1-2-3-2-1-4-1-2-3... etc.

//Misc. Attribute Indexes
const int Z4LEEVER_COMBO_INDEX = 10;
const int Z4LEEVER_UNDER_TIME_INDEX = 0;
const int Z4LEEVER_ABOVE_TIME_INDEX = 1;

int angle;


ffc script Ghosted_Z4Leever {
    void run(int enemyID) {

        npc ghost;
		int combo;
        float step;
        int belowTime;
        int aboveTime;
        float lastX; //<-- defined in the ffc script
		
		//Initialize
		ghost = Ghost_InitAutoGhost(this, enemyID);
		Ghost_SetFlag(GHF_NORMAL);
		combo = Ghost_GetAttribute(ghost, Z4LEEVER_COMBO_INDEX, 0);
		step = ghost->Step/100;
		belowTime = Ghost_GetAttribute(ghost, Z4LEEVER_UNDER_TIME_INDEX, 60);
		aboveTime = Ghost_GetAttribute(ghost, Z4LEEVER_ABOVE_TIME_INDEX, 120);
			
		while(true) {

			
			//underground
			Ghost_Data = combo+3;
			ghost->CollDetection = false; //Make ghost intangible
			Ghost_Waitframes(this, ghost, true, true, belowTime);
			Change_Pos(this, ghost, Link->X, Link->Y, step);
			
			//surfacing
			Ghost_Data = combo;
			Ghost_Waitframes(this, ghost, true, true, 10);
			Ghost_Data = combo+1;
			Ghost_Waitframes(this, ghost, true, true, 10);
			
			//aboveground
			Ghost_Data = combo+2;
			ghost->CollDetection = true; //Make ghost tangible
			for(int i=0; i<aboveTime + Rand(30, 60); i++) {
				Ghost_MoveTowardLink(step, 0);
				Ghost_Waitframe(this, ghost, true, true);
			}
			
			//digging
			Ghost_Data = combo+1;
			ghost->CollDetection = false; //Make ghost intangible
			Ghost_Waitframes(this, ghost, true, true, 10);
			Ghost_Data = combo;
			Ghost_Waitframes(this, ghost, true, true, 10);
        }
    }
}
void Change_Pos(ffc this, npc ghost, int x, int y, int step)
{
	bool canSurface = false;
	lastX = 0; //<-- accessed in the external function
	
	while(!canSurface)
	{
		if (Ghost_X > x - 32 && Ghost_X < x + 47) Ghost_X = Rand(0, 304);
		if (Ghost_Y > y - 32 && Ghost_Y < y + 47) Ghost_Y = Rand(0, 160);
		
		if (((Ghost_X < x - 32 || Ghost_X > x + 47) && (Ghost_Y < y - 32 || Ghost_Y > y + 48)) && (Ghost_CanMove(Ghost_Dir, step, 0)))
			canSurface = true;
		else
			canSurface = false;
	}	
}




Edited by Shadowblitz16, 31 December 2016 - 01:47 PM.


#593 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 31 December 2016 - 03:07 PM

You can't access a local variable declare in another function. If you want Change_Pos to have access to lastX, you need to pass it in as an argument. If it needs to set lastX, it can return a value.

#594 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 01 January 2017 - 06:42 PM

ok how about a slime split? the problem I have is checking if the slime is dead in the middle of script execution

I would just check if its hp is lower then 0 in all my functions but I don't know how to get past the wait frame functions

 

Edit: I also can seem to figure out how to access spawned gel ghosted variables and how to check for collisions between two gels


Edited by Shadowblitz16, 02 January 2017 - 11:02 AM.


#595 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 02 January 2017 - 07:23 PM

is there a reason I can't get Ghost_DeathAnimation to set my zols death animation to nothing?

also how do I make the death effect stop falling when my enemy is dead?

 

here is my code

	if (Ghost_HP <= 0)
		Ghost_SetFlag(GHF_NO_FALL);
	else
	if (Ghost_GotHit() && splits)
	{
		npc gel1 = Screen->CreateNPC(enemy);
		npc gel2 = Screen->CreateNPC(enemy);
		
		gel1->X = Ghost_X - 8;
		gel1->Y = Ghost_Y;
		gel2->X = Ghost_X + 8;
		gel2->Y = Ghost_Y;
		
		Ghost_DeathAnimation(this, ghost, 128);
		Ghost_HP = 0;
	}
	//Something here to make enemy stop falling


#596 isilmo

isilmo

    Recipient of Ways

  • Members
  • Gender:Unspecified

Posted 03 January 2017 - 06:56 PM

Will there be an update to this video:

 

https://www.youtube....D2gIfE7w&t=120s

 

or is it largely still accurate?



#597 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 04 January 2017 - 11:06 AM

I would just check if its hp is lower then 0 in all my functions but I don't know how to get past the wait frame functions

For something like that, you probably want to make your own Waitframe wrapper. Something like
void ZolWaitframe(ffc this, npc ghost)
{
    if(!Ghost_Waitframe(this, ghost, true, false))
    {
        // It's dead at this point; do whatever
        Quit();
    }
}

is there a reason I can't get Ghost_DeathAnimation to set my zols death animation to nothing?

If you don't want an animation, don't call the function. If you want to prevent even the regular death graphic, move the enemy offscreen so it's silently deleted.
 

also how do I make the death effect stop falling when my enemy is dead?

Do you mean how do you get your script to keep running? If the fourth argument to Ghost_Waitframe() is false, the script will keep running after the enemy dies.
 

Will there be an update to this video:
 
https://www.youtube....D2gIfE7w&t=120s
 
or is it largely still accurate?

I could perhaps update it. It's still accurate as far as it goes, but the new options to read data from the enemy's name are probably worth demonstrating.
  • isilmo likes this

#598 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 04 January 2017 - 04:45 PM

@Saffith

how do I change the fake z shadow on an enemy?

I have small slimes that use small shadows however I don't see anyway of doing this

 

Edit: also does ghost.zh use the npc->Attributes[]?

I was wondering since I am getting weird values when reading them


Edited by Shadowblitz16, 04 January 2017 - 06:08 PM.


#599 Saffith

Saffith

    IPv7 user

  • ZC Developers
  • Gender:Male

Posted 05 January 2017 - 10:07 AM

The shadow settings are global, shared by all enemies. If you want one enemy to have a different shadow than others, you'll have to draw it yourself.

npc->Attributes[] is only used to read AutoGhost data. But it's read-only, so there's nothing I could be doing to change the values, anyway.

#600 Shadowblitz16

Shadowblitz16

    Illustrious

  • Members

Posted 07 January 2017 - 03:09 PM

@Saffith how do I turn the ghost's shadow off so I can manually draw it?

also how do I set the ghosted npc's position to a combo found by FindSpawnPoint()?

it looks like it returns a combos 1d position but I don't know how to convert the npc's 2d position to 1d.


Edited by Shadowblitz16, 07 January 2017 - 06:00 PM.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users