Jump to content

Photo

BS Dodongo Animation Wolf - harm hero and enemies

npc script ghost

  • Please log in to reply
15 replies to this topic

#1 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 10 December 2019 - 01:28 PM

I'm struggling with my wolf enemy.

I want it to move like bs dodongo (draw 2 tiles height and 1 wide when Walking up-/dowards

but 1 height and 2 wide, when walking right/left) without setting Dodongo (Dinosaur) Enemy Type.
I tried everything! Changing size, motion etc.

If it's possible to make an enemy the does damage to other enemies, like it does to Link,

it would be great if the script could include this function.

It shall not count as beatable enemy...
Defenses all = ignore

If it's possible without scripting, pleaaaaase tell me how
Help an old man...  :puppyeyes: 


Thanks for your attention

 


Please exuse my terrible english :wow:

...it's not my first language.


Edited by Bagu, 10 December 2019 - 01:27 PM.


#2 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 10 December 2019 - 02:05 PM

I'm pretty sure this is not possible without scripting. 2.55 has options for bigger enemies but I don't believe they change size with direction like the BS dodongo does. I could try making a ghost.zh script for 2.53 or npc script for 2.55 is you'd be willing to put up with setting it up. 


  • Bagu likes this

#3 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 10 December 2019 - 02:25 PM

I'm pretty sure this is not possible without scripting. 2.55 has options for bigger enemies but I don't believe they change size with direction like the BS dodongo does. I could try making a ghost.zh script for 2.53 or npc script for 2.55 is you'd be willing to put up with setting it up. 

Great, thank you!!!

It would be so amazing if you could wirte an npc script for 2.55 Alpha like that for me.

I'm trying to leran more about zscript.

I can already Combine scripts, but I'm stil a totaly beginner


Edited by Bagu, 10 December 2019 - 02:59 PM.


#4 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 10 December 2019 - 03:02 PM

p.S.: Sorry for late reply



#5 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 10 December 2019 - 03:22 PM

npc script FleshyDodongo
{
	void run()
	{
		//Make the first instance of the enemy invisible
		this->DrawYOffset = -1000;
		this->CollDetection = false;
		
		//Spawn a second enemy for the body with no script
		npc body = CreateNPCAt(this->ID, this->X, this->Y);
		body->Script = 0;
		body->Extend = 3;
		
		int vars[16];
		//vars[0] - Animation Clock
		
		while(true)
		{
			//The controller enemy handles movement
			this->ConstantWalk({this->Rate, this->Homing, this->Hunger});
			//Then update's the body's position and animation
			FD_UpdateBody(this, vars, body);
			
			//When the body dies, center it and kill the controller too
			if(body->HP<=0)
			{
				int x = CenterX(body);
				int y = CenterY(body);
				body->X = x-8;
				body->Y = y-8;
				body->TileWidth = 1;
				body->TileHeight = 1;
				body->HitWidth = 16;
				body->HitHeight = 16;
				this->HP = -1000;
				this->ItemSet = 0;
				Quit();
			}
			
			Waitframe();
		}
	}
	void FD_UpdateBody(npc this, int vars, npc body)
	{
		++vars[0];
		//Get the enemy's current frame based off F.Rate
		int f4 = Floor(vars[0]/(this->ASpeed/4));
		//Keep the frame wrapped from 0-3
		if(f4==4)
		{
			f4 = 0;
			vars[0] = 0;
		}
		
		//Update tiles, hitboxes, and position based on the controller's
		switch(this->Dir)
		{
			case DIR_DOWN:
				body->X = this->X;
				body->Y = this->Y-16;
				body->TileWidth = 1;
				body->TileHeight = 2;
				body->HitWidth = 16;
				body->HitHeight = 32;
				body->Tile = this->OriginalTile + 4 + f4;
				body->OriginalTile = body->Tile;
			
				break;
			case DIR_LEFT:
				body->X = this->X;
				body->Y = this->Y;
				body->TileWidth = 2;
				body->TileHeight = 1;
				body->HitWidth = 32;
				body->HitHeight = 16;
				body->Tile = this->OriginalTile + 40 + f4 * 2;
				body->OriginalTile = body->Tile;
			
				break;
			case DIR_RIGHT:
				body->X = this->X-16;
				body->Y = this->Y;
				body->TileWidth = 2;
				body->TileHeight = 1;
				body->HitWidth = 32;
				body->HitHeight = 16;
				body->Tile = this->OriginalTile + 60 + f4 * 2;
				body->OriginalTile = body->Tile;
			
				break;
			default:
				body->X = this->X;
				body->Y = this->Y;
				body->TileWidth = 1;
				body->TileHeight = 2;
				body->HitWidth = 16;
				body->HitHeight = 32;
				body->Tile = this->OriginalTile + f4;
				body->OriginalTile = body->Tile;
		}
	}
}

Here's what I came up with. It's not exactly accurate to the dodongo movement but uses the same animation layout. 

 

To set it up:

  • #include the script in the buffer as you would any other script file
  • Copy a dodongo enemy to a new slot
  • Change the Type to Other
  • Change E. Anim to (None)
  • Give it an F. Rate (I went with 32)
  • In the Scripts tab under NPC Action Script assign it the FleshyDodongo script


#6 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 10 December 2019 - 04:32 PM

npc script FleshyDodongo
{
	void run()
	{
		//Make the first instance of the enemy invisible
		this->DrawYOffset = -1000;
		this->CollDetection = false;
		
		//Spawn a second enemy for the body with no script
		npc body = CreateNPCAt(this->ID, this->X, this->Y);
		body->Script = 0;
		body->Extend = 3;
		
		int vars[16];
		//vars[0] - Animation Clock
		
		while(true)
		{
			//The controller enemy handles movement
			this->ConstantWalk({this->Rate, this->Homing, this->Hunger});
			//Then update's the body's position and animation
			FD_UpdateBody(this, vars, body);
			
			//When the body dies, center it and kill the controller too
			if(body->HP<=0)
			{
				int x = CenterX(body);
				int y = CenterY(body);
				body->X = x-8;
				body->Y = y-8;
				body->TileWidth = 1;
				body->TileHeight = 1;
				body->HitWidth = 16;
				body->HitHeight = 16;
				this->HP = -1000;
				this->ItemSet = 0;
				Quit();
			}
			
			Waitframe();
		}
	}
	void FD_UpdateBody(npc this, int vars, npc body)
	{
		++vars[0];
		//Get the enemy's current frame based off F.Rate
		int f4 = Floor(vars[0]/(this->ASpeed/4));
		//Keep the frame wrapped from 0-3
		if(f4==4)
		{
			f4 = 0;
			vars[0] = 0;
		}
		
		//Update tiles, hitboxes, and position based on the controller's
		switch(this->Dir)
		{
			case DIR_DOWN:
				body->X = this->X;
				body->Y = this->Y-16;
				body->TileWidth = 1;
				body->TileHeight = 2;
				body->HitWidth = 16;
				body->HitHeight = 32;
				body->Tile = this->OriginalTile + 4 + f4;
				body->OriginalTile = body->Tile;
			
				break;
			case DIR_LEFT:
				body->X = this->X;
				body->Y = this->Y;
				body->TileWidth = 2;
				body->TileHeight = 1;
				body->HitWidth = 32;
				body->HitHeight = 16;
				body->Tile = this->OriginalTile + 40 + f4 * 2;
				body->OriginalTile = body->Tile;
			
				break;
			case DIR_RIGHT:
				body->X = this->X-16;
				body->Y = this->Y;
				body->TileWidth = 2;
				body->TileHeight = 1;
				body->HitWidth = 32;
				body->HitHeight = 16;
				body->Tile = this->OriginalTile + 60 + f4 * 2;
				body->OriginalTile = body->Tile;
			
				break;
			default:
				body->X = this->X;
				body->Y = this->Y;
				body->TileWidth = 1;
				body->TileHeight = 2;
				body->HitWidth = 16;
				body->HitHeight = 32;
				body->Tile = this->OriginalTile + f4;
				body->OriginalTile = body->Tile;
		}
	}
}

Here's what I came up with. It's not exactly accurate to the dodongo movement but uses the same animation layout. 

 

To set it up:

  • #include the script in the buffer as you would any other script file
  • Copy a dodongo enemy to a new slot
  • Change the Type to Other
  • Change E. Anim to (None)
  • Give it an F. Rate (I went with 32)
  • In the Scripts tab under NPC Action Script assign it the FleshyDodongo script

 

 

Just seen your answer.
Sorry, gonna try your script now…

Thank you very much


It works... Thanks so much!
U R GREAT!


  • Moosh likes this

#7 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 12 December 2019 - 09:13 AM

Why did you need a dummy/controller npc for this?
 

case DIR_DOWN:
				body->X = this->X;
				body->Y = this->Y-16;
				body->TileWidth = 1;
				body->TileHeight = 2;
				body->HitWidth = 16;
				body->HitHeight = 32;
				body->Tile = this->OriginalTile + 4 + f4;
				body->OriginalTile = body->Tile;

Does that not work on the main enemy using this-> ?

You can get the tile info with:
 

body->Tile = (Game->LoadNPCData(this->ID)->Tile) + 4 + f4; //originaltile for any npc

Cache to a local var if you want to reduce its instructions, perhaps?

 

Ah, I see. You want a relative x/y. :shrug:


  • Bagu likes this

#8 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 12 December 2019 - 09:35 AM

Sounds good, cause the controller flips around the ass of my wolf, when changing direction.
That's not a big problem to me, but it would look better without the "flip"

So how to edit the script?
Which lines have to be replaced by your changes?

And is it possible to make it harm other enemies? (2 damage) and hero (1 damage)
Cause the Wolf should be an independent creature. Not friend, not foe...
...just an animal


Edited by Bagu, 12 December 2019 - 09:39 AM.


#9 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 12 December 2019 - 10:04 AM

For grins, please compare this and tell me if the behaviour differs:
 
npc script wolfie
{
	void run()
	{
		int clks[1];
		while(1)
		{
			this->ConstantWalk({this->Rate, this->Homing, this->Hunger});
			nmes::transform2x1(this,clks);
			Waitframe();
		}
	}
}

namespace nmes
{		
	void transform2x1(npc n, int clk)
	{
		++clk[0];
		int f4 = Floor(clk[0]/(n->ASpeed/4));
		if( f4 >= 4 ) { f4 = 0; clk[0] = 0;}
		switch(n->Dir)
		{
			case DIR_DOWN:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 4 + f4;
				n->OriginalTile = n->Tile;
				n->HitXOffset = 0;
				n->HitYOffset = -16;
				n->DrawXOffset = 0;
				n->DrawYOffset = -16;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				break;
			case DIR_RIGHT:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 60 + (f4 * 2);
				n->OriginalTile = n->Tile;
				n->HitXOffset = -16;
				n->HitYOffset = 0;
				n->DrawXOffset = -16;
				n->DrawYOffset = 0;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				break;
			case DIR_LEFT:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 40 + (f4 *2);
				n->OriginalTile = n->Tile;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				n->HitXOffset = 0;
				n->HitYOffset = 0;
				n->DrawXOffset = 0;
				n->DrawYOffset = 0;
				break;
			case DIR_UP:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + f4;
				n->OriginalTile = n->Tile;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				n->HitXOffset = 0;
				n->HitYOffset = 0;
				n->DrawXOffset = 0;
				n->DrawYOffset = 0;
				break;
			
		}
	}
}

Sounds good, cause the controller flips around the ass of my wolf, when changing direction.
That's not a big problem to me, but it would look better without the "flip"

So how to edit the script?
Which lines have to be replaced by your changes?

And is it possible to make it harm other enemies? (2 damage) and hero (1 damage)
Cause the Wolf should be an independent creature. Not friend, not foe...
...just an animal


That's probably just because it's using ConstantWalk.
  • Bagu likes this

#10 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 12 December 2019 - 10:14 AM

Gonna try, right now  :approve: 
Thanks



#11 ywkls

ywkls

    Master

  • Members

Posted 12 December 2019 - 10:20 AM

I'm just wondering why there is a second enemy involved in this at all.

 

https://youtu.be/Wzu7mAFvpJI?t=331

 

It may seem a tiny bit jumpy, but it is completely possible to accomplish this same sort of effect with one npc.


Edited by ywkls, 12 December 2019 - 10:22 AM.

  • Bagu likes this

#12 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 12 December 2019 - 10:32 AM

For grins, please compare this and tell me if the behaviour differs:
 

npc script wolfie
{
	void run()
	{
		int clks[1];
		while(1)
		{
			this->ConstantWalk({this->Rate, this->Homing, this->Hunger});
			nmes::transform2x1(this,clks);
			Waitframe();
		}
	}
}

namespace nmes
{		
	void transform2x1(npc n, int clk)
	{
		++clk[0];
		int f4 = Floor(clk[0]/(n->ASpeed/4));
		if( f4 >= 4 ) { f4 = 0; clk[0] = 0;}
		switch(n->Dir)
		{
			case DIR_DOWN:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 4 + f4;
				n->OriginalTile = n->Tile;
				n->HitXOffset = 0;
				n->HitYOffset = -16;
				n->DrawXOffset = 0;
				n->DrawYOffset = -16;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				break;
			case DIR_RIGHT:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 60 + (f4 * 2);
				n->OriginalTile = n->Tile;
				n->HitXOffset = -16;
				n->HitYOffset = 0;
				n->DrawXOffset = -16;
				n->DrawYOffset = 0;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				break;
			case DIR_LEFT:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 40 + (f4 *2);
				n->OriginalTile = n->Tile;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				n->HitXOffset = 0;
				n->HitYOffset = 0;
				n->DrawXOffset = 0;
				n->DrawYOffset = 0;
				break;
			case DIR_UP:
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + f4;
				n->OriginalTile = n->Tile;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				n->HitXOffset = 0;
				n->HitYOffset = 0;
				n->DrawXOffset = 0;
				n->DrawYOffset = 0;
				break;
			
		}
	}
}

That's probably just because it's using ConstantWalk.

 

 

It works very good, looks smoother, when changing direction
:love:  :love:  :love: 

But it would still be great if there was a "Damage to other npc" function added to the script


 



#13 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 12 December 2019 - 10:35 AM

I'm going to need to add Waitdraw to npc scripts this week. For now, just use what Moosh posted. I was working on a slow-down effect before turning, but Elvis can leave the building without Waitdraw, with writes to Step.

npc->RandomRate is also absent.
  • Bagu likes this

#14 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 12 December 2019 - 10:42 AM

All I had to change for the Wolfie script, was to enable 2 tiles heigth and width.
Looks good, as far.
If Wolfie will harm enemies soon, I will be the happiest Person in Hyrule   :love:  ;) 



#15 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 13 December 2019 - 10:23 AM

All I had to change for the Wolfie script, was to enable 2 tiles heigth and width.
Looks good, as far.
If Wolfie will harm enemies soon, I will be the happiest Person in Hyrule :love: ;)




This will do what you want, including the bite attack on other enemies, however it requires 2.55 Alpha 46. That build is now available on zeldaclassic.com. None of that x/y positioning was required to make this enemy function. The engine handles position based on size of enemies.

The npc should be a type of Other, and you will need to set its Defences to ignore Script 01 weapons.
 
npc script wolfie
{
	void run()
	{
		int clks[1];
		lweapon bite = Screen->CreateLWeapon(EW_SCRIPT1);
		bite->X = this->X;
		bite->Y = this->Y;
		bite->HitHeight = 8;
		bite->HitWidth = 16;
		bite->DrawYOffset = -32768;
		bite->Damage = 2;
		while(1)
		{
			this->ConstantWalk({this->Rate, this->Homing, this->Hunger});
			unless(bite->isValid()) 
			{
				bite = Screen->CreateLWeapon(EW_SCRIPT1);
				bite->DrawYOffset = -32768;
				bite->Damage = 2;
			}
			if(bite->isValid()) 
			{
				wolfnme::positionbite(this, bite);
				wolfnme::transformbite(this, bite);
				
			}
			Waitdraw();
			wolfnme::transform2x1(this,clks);
			Waitframe();
		}
	}
}

namespace wolfnme
{		
	void positionbite(npc n, lweapon bite)
	{
		switch(n->Dir)
		{
			case DIR_UP:
				bite->X = n->X; bite->Y = n->Y -1; bite->HitYOffset = -2; bite->HitXOffset = 0; break;
			case DIR_DOWN:
				bite->X = n->X; bite->Y = n->Y + 1; bite->HitYOffset = 24; bite->HitXOffset = 0; break;
			case DIR_LEFT:
				bite->X = n->X - 1; bite->Y = ((n->Y > 0) ? n->Y : n->Y + 1); bite->HitYOffset = 0; bite->HitXOffset = -2; break;
			case DIR_RIGHT:
				bite->X = n->X + 1; bite->Y = ((n->Y > 0) ? n->Y : n->Y + 1); bite->HitYOffset = 0; bite->HitXOffset = 25; break;
		}
	}
	void transformbite(npc n, lweapon l)
	{
		switch(n->Dir)
		{
			case DIR_DOWN:
			case DIR_UP:
			{
				l->HitWidth = 16;
				l->HitHeight = 8;
				break;
			}
			case DIR_RIGHT:
			case DIR_LEFT:
			{
				l->HitWidth = 8;
				l->HitHeight = 16;
				break;
			}
		}
	}

	void transform2x1(npc n, int clk)
	{
		++clk[0];
		int f4 = Floor(clk[0]/(n->ASpeed/4));
		if( f4 >= 4 ) { f4 = 0; clk[0] = 0;}
		switch(n->Dir)
		{
			case DIR_DOWN:
			{
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 4 + f4;
				n->OriginalTile = n->Tile;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				break;
			}
			case DIR_RIGHT:
			{
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 60 + (f4 * 2);
				n->OriginalTile = n->Tile;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				break;
			}
			case DIR_LEFT:
			{
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + 40 + (f4 *2);
				n->OriginalTile = n->Tile;
				n->TileWidth = 2;
				n->TileHeight = 1;
				n->HitWidth = 32;
				n->HitHeight = 16;
				break;
			}
			case DIR_UP:
			{
				n->Tile = (Game->LoadNPCData(n->ID)->Tile) + f4;
				n->OriginalTile = n->Tile;
				n->TileWidth = 1;
				n->TileHeight = 2;
				n->HitWidth = 16;
				n->HitHeight = 32;
				break;
			}
		}
	}
}

  • Bagu likes this



Also tagged with one or more of these keywords: npc script, ghost

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users