Jump to content

Photo

Defeat Enemies In Specific Order


  • Please log in to reply
4 replies to this topic

#1 idontknow8

idontknow8

    Senior

  • Members

Posted 25 January 2021 - 12:25 AM

A Script where you must defeat enemies in a certain order - maybe literally in numerical order, enemy #1, #2, #3...etc.

 

Let's say you have three darknuts, each of a different color: Red, Blue, Green.  You must defeat them in that order.

 

A few possible scenarios:  One could be that both the blue & green darknuts are invincible (that is, the enemy ignores all weapons) until the red one is defeated, at which point the green darknut remains invincible but the blue one can now be attacked....once the blue one is defeated, green one can be attacked (and so on if there were more)

 

Or it could be that you could attack any enemies BUT when you defeat an enemy out of order, an "error" sound effect plays (D0) and then it respawns / tribbles into itself.  Only once all enemies in order number before it are defeated, does an enemy stay defeated...I think I might prefer this method.

 

There could be clues within the room - or even on adjacent screens - as to which order is correct.


Edited by idontknow8, 25 January 2021 - 12:26 AM.

  • SkyLizardGirl likes this

#2 P-Tux7

P-Tux7

    💛

  • Members

Posted 25 January 2021 - 02:07 AM

Wasn't this done in Link's Awakening with the pols voice and stalfos room?


  • SkyLizardGirl likes this

#3 Mitchfork

Mitchfork

    no fun. not ever.

  • Contributors
  • Real Name:Mitch
  • Location:Alabama

Posted 25 January 2021 - 10:01 AM

What version of ZC are you using? How I'd do this in 2.55 is pretty different to how I'd have to do it in 2.53.
 
EDIT: Well, not that different.  But I'd handle it as a screendata script in 2.55 which 2.53 doesn't have, so...
 
For reference, here is a possible 2.55 implementation.  This script just respawns the enemy and plays an error sound (D0) if it's killed out of order.  The order is set by the enemy order on screen - Enemy 0 is killed last and Enemy 2 is killed first (lines up with the ZC respawn rules kind of).

This one just sets a specific X/Y coordinate (D1 and D2) that enemies always respawn at. This could be changed.

Also, this script will probably not work if there are ever less than three enemies on screen, so you'd have to flag "Enemies Always Respawn". You could fix this by adding in some Screen->NumNPCs check at the very beginning to handle it. I'm not sure how ZC's default spawning behavior handles respawning enemies though, so it may be cleaner to just use the screen flag.
 

screendata script enemyOrder {
	void run(int errorSFX, int xSpawn, int ySpawn) {
		//load NPC's
		npc firstEnemy = Screen->LoadNPC(2);
		npc secondEnemy = Screen->LoadNPC(1);
		npc thirdEnemy = Screen->LoadNPC(0);
		int firstID = firstEnemy->ID;
		int secondID = secondEnemy->ID;
		int thirdID = thirdEnemy->ID;
		
		while(true) {
			//handle all enemies being alive
			if (firstEnemy->isValid() and secondEnemy->isValid() and thirdEnemy->isValid()) {
				//do nothing
			}
			
			//handle if second or third are dead and first is alive
			else if (firstEnemy->isValid()) {
				if (!secondEnemy->isValid()) {
					secondEnemy = CreateNPCAt(secondID,xSpawn,ySpawn);
					Audio->PlaySound(errorSFX);
				}
				if (!thirdEnemy->isValid()) {
					thirdEnemy = CreateNPCAt(thirdID,xSpawn,ySpawn);
					Audio->PlaySound(errorSFX);
				}
			}
			
			//handle if second enemy is alive, but third is dead
			else if (secondEnemy->isValid()) {
				if (!thirdEnemy->isValid()) {
					thirdEnemy = CreateNPCAt(thirdID,xSpawn,ySpawn);
					Audio->PlaySound(errorSFX);
				}
			}
			
			//if all enemies are dead, quit the script
			else if (!firstEnemy->isValid() and !secondEnemy->isValid() and !thirdEnemy->isValid()) {
				//You can add additional things here if necessary
				Quit();
			}
			Waitframe();
		}
	}
}

Edited by Mitchfork, 25 January 2021 - 11:01 AM.

  • SkyLizardGirl likes this

#4 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 29 January 2021 - 03:00 AM

In 2.55, you can read Screen->Enemy[] om screen init, to get the IDs in order. This is a much simpler way of doing things. 



#5 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 29 January 2021 - 03:15 AM

Incomplete, rough idea:
 

screendata script enemiesinorder
{
	void run(int max)
	{
		if ( max < 1 ) max = 10;
		int orig_order[10];
		int tmp[20];
		int curr = 0;
		int count = Count___EnemiesAlive();
		bool success = false;
		for ( int q = 0; q < count; ++q )
		{
			orig_order[q]  Screen->Enemy(q);
		}
		Waitframes(6);
		//loop through enemies and give them an order number and pup an array pointer into them
		npc n;
		for ( int q = 1; q <= count; ++q)
		{
			n = Screen->LoadNPC(q);
			n->Misc[0] = q;
			n->Misc[1] = temp;
		}
		while(EnemiesAlive())
		{
			int newcount = Count___EnemiesAlive();
			//loop through enemies
			if ( newcount < count ) 
			{
				//one has died
				++curr;
				//check to see if the lowest is the lowesgt spawned
				for ( int q = 1; q <= newcount; ++q)
				{
					n = Screen->LoadNPC(q);
					unless ( n->Misc[0] == curr )
					{
						//we killed out of order
						Quit();
					}
					
				}
			}
			//sort
			Waitframe();
		}
		//if we reach here, trigger whatever
		
	}
	//Returns if there are enemy NPCs alive on the current screen.
	int  Count___EnemiesAlive()
	{
		int numalive;
		for ( int q = Screen->NumNPCs(); q > 0; --q )
		{
			npc n = Screen->LoadNPC(q); 
			if ( n->Type != NPCT_PROJECTILE )
			{
				unless ( (n->MiscFlags&NPCMF_NOT_BEATABLE) )
				{
					if ( n->Type != NPCT_FAIRY )
					{
						if ( n->Type != NPCT_GUY )
						{
							++numalive;
						}
					}
				}
			}
		}
		return numalive;
	}

			



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users