Jump to content

Photo

Metroid Escape Sequence (carry over timer needed)


  • Please log in to reply
8 replies to this topic

#1 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Location:Judgement Hall

Posted 11 September 2021 - 07:30 PM

heya guys. I would like to ask a script request. You certainly know about the infamous Metroid's Escape sequences with the timer right ? Well... I would like something similar in my quest. Let me explain: 

First i wanted to make a non-scripted cutscene for example the player lit a big bomb (in a mine with many TNT there and there) with a fire and then an alarm is played as well of a string and after that the "Escape Sequence" start (scripted) with a timer (preferably a carry over one that works with a FFC.). Now i explain it function: The timer start until the player reach the point where there's no ffc (that uses the Timer) which would be the safe point from the imminent death. If the player don't reach the said point before the timer is set to 0 many explosions would appears at the screen repeately almost if the screen is self-destruct and after a few second the player dies instantly no matter if the player have full heart and if the player did get the tunic's upgrade or not. 

So i was thinking that the D0 should be using for the time counter. (Example: 2,0000 would means 2 seconds while 20,0000 would means 2 minutes.). Or else we could use the old fashion time frame function.
The D1 would either enable the explosion background (that won't damage the player at all) or not while the timer still countdown. 
The D2 would be the explosion's tiles (or combo) that would appears should the player can't reach the safe point in time. (where there's no FFC of the timer).
and the D3 would be the damage that the player takes if the player doesn't reach the safe point in time before 0. (Preferably -1 for instant kill).

I know that there's already a timer script in the database but this one doesn't carry over screen after screen when i did tried it by putting ffc in rooms to make it works.



#2 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 12 September 2021 - 06:56 AM

Carry over FFCs are just bad, you frankly should avoid ever using them.


  • Mani Kanina likes this

#3 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Location:Judgement Hall

Posted 12 September 2021 - 08:27 AM

Oh. I should put only one timer ffc and put another ffc that would completely stop and remove the timer for the safe point ?

#4 Emily

Emily

    Scripter / Dev

  • ZC Developers

Posted 12 September 2021 - 10:19 AM

It shouldn't be an FFC if it requires more than 1 screen


  • Mani Kanina likes this

#5 Mani Kanina

Mani Kanina

    Rabbits!

  • Members

Posted 12 September 2021 - 11:20 AM

Yeah uh, a metroid esque escape sequence makes way more sense to put in the global scope.

And just generally speaking Sans, while it's perfectly fine to make a script request, it seems extraordinarily weird that when you make them you decide on how they should be structured and made, despite obviously not being the person coding it. It comes off as kinda badly, because you evidently don't seem that well versed in scripting yourself? And the person who take your request can more than likely do the structural design themselves, and very much so have a better idea of what is needed.

As for why carry-over FFCs are bad: When you carry over an FFC from one screen to another, it will eat the FFC on the destination screen that has the same ID, regardless of what that FFC ID might have been in the destination screen. So say, you have an FFC on the destination screen that look like at a tile, oops, now you have a graphical error. Or even worse, have the FFC in the destination screen be one that is supposed to run a script, now that won't happen.



#6 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Location:Judgement Hall

Posted 12 September 2021 - 11:33 AM

Well... you have a point... as for the scripting i'm very very very awful at that. I can only import scripts or edit some things but nothing more then that

#7 Alucard648

Alucard648

    Wizard

  • Members
  • Location:castle Dracula

Posted 12 September 2021 - 02:36 PM

alttimers.zh



#8 Mani Kanina

Mani Kanina

    Rabbits!

  • Members

Posted 12 September 2021 - 07:36 PM

Okay I took the time to script this, you'll need to do some set up on your end though:
 


int GlobalArray[999];
const int ESC_G_TIME = 1;				// What number of the global array keeps track of the countdown number.
const int ESC_FAIL_DMG = 9999;	// How much HP damage is applied to link when time runs out.

//Countdown related things, the Font used, where it draws on the X/Y, what colour the text is and what colour the dropshadow is as well as layer it's drawn on
const int ESC_FONT = 0;		// 0 is zelda 1's font
const int ESC_TXT_X = 0;
const int ESC_TXT_Y = 0;
const int ESC_TXT_CLR = 0x00;			//These are in hex for convenience. first number after the "x" is CSet row, second number is colour. Goes from 0-F     (...8 9 A B C, etc)
const int ESC_TXT_CLR2 = 0x0F;		
const int ESC_TXT_LAYER = 6;
//This is how much space is between characters, this will vary by font so tweak accordingly. "8" is a good value for the default zelda 1 font
const int ESC_TXT_SPACING = 8;

//Draws this screen from this map if explosion effect is set to draw
const int ESC_EXP_LAY_SCRN = 0x00;
const int ESC_EXP_LAY_MAP = 0;
const int ESC_EXP_DRAW = 1; 		//Set to 0 to not draw		Set to 1 to Draw layer		Set to 2 to Draw random explosions


void EscapeSequence(int StartScreen, int StartDMap, int EndScreen, int EndDMap, int Time, int GlobalEvent){
	
	if(GlobalArray[ESC_G_TIME] > 0){
		
		if(Link->HP <= 0) GlobalArray[ESC_G_TIME] = -1;		// Turns timer off if you die
		else if(Game->GetCurScreen() == EndScreen && Game->GetCurDMap() == EndDMap && GlobalArray[ESC_G_TIME] > 0){
			
			if(GlobalEvent > 0) GlobalArray[GlobalEvent] = 1;	// Making the check so the event does not run again.  If GlobalEvent is set to 0 or less, this will not save, for a re-usable event
			GlobalArray[ESC_G_TIME] = -1;								// Turns the timer off for reaching the end
			Game->SetScreenState(Game->DMapMap[EndDMap], StartScreen, ST_SECRET, true);	// Sets the secret on the STARTING screen.
		}
		else{
			
			GlobalArray[ESC_G_TIME] --;			// Counting down (needs to happen first in order to be able to kill Link in this implementation)
			
			//Draws explosion effects, be it layer or bomb blasts
			if(ESC_EXP_DRAW == 1) Screen->DrawLayer(6, ESC_EXP_LAY_MAP, ESC_EXP_LAY_SCRN, 0, 0, 0, 0, OP_OPAQUE);
			else if(ESC_EXP_DRAW == 2 && Rand(20) == 1){
				
				eweapon Explo;
				Explo = Screen->CreateEWeapon(EW_BOMBBLAST);
				Explo->CollDetection = false;
				Explo->Damage = 0;
				Explo->X = 16 + Rand(14) * 16;
				Explo->Y = 16 + Rand(10) * 16;
				
			}
			
			//Drawing counter for countdown
			int Mins = Floor((GlobalArray[ESC_G_TIME] / 60) / 60);
			int Secs = (GlobalArray[ESC_G_TIME] / 60 )% 60;
			int Offset = 2;
			if(Mins >= 10) Offset ++;
			if(Mins >= 100) Offset ++;
			
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + 1, ESC_TXT_Y + 0, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Mins, 0, OP_OPAQUE);
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + 1, ESC_TXT_Y + 1, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Mins, 0, OP_OPAQUE);
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + 0, ESC_TXT_Y + 1, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Mins, 0, OP_OPAQUE);
			
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X, ESC_TXT_Y, ESC_FONT, ESC_TXT_CLR, -1, -1, -1, Mins, 0, OP_OPAQUE);
			
			
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + (ESC_TXT_SPACING * Offset) + 1, ESC_TXT_Y + 0, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Secs, 0, OP_OPAQUE);
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + (ESC_TXT_SPACING * Offset) + 1, ESC_TXT_Y + 1, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Secs, 0, OP_OPAQUE);
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + (ESC_TXT_SPACING * Offset) + 0, ESC_TXT_Y + 1, ESC_FONT, ESC_TXT_CLR2, -1, -1, -1, Secs, 0, OP_OPAQUE);
			
			Screen->DrawInteger(ESC_TXT_LAYER, ESC_TXT_X + (ESC_TXT_SPACING * Offset), ESC_TXT_Y, ESC_FONT, ESC_TXT_CLR, -1, -1, -1, Secs, 0, OP_OPAQUE);
			
			// Killing Link when counter reaches 0
			if(GlobalArray[ESC_G_TIME] == 0){
				
				
				if(Link->HP - ESC_FAIL_DMG <= 0) Link->HP = 0;
				else{
					Link->HP = Link->HP - ESC_FAIL_DMG;
				}
				
			}
			else if(GlobalArray[ESC_G_TIME] < 14){	//explosions when time is running out
				
				if(GlobalArray[ESC_G_TIME] == 13) Game->PlaySound(3);
				eweapon Explo;
				Explo = Screen->CreateEWeapon(EW_SBOMBBLAST);
				Explo->Damage = 0;
				Explo->X = 16 + Rand(14) * 16;
				Explo->Y = 16 + Rand(10) * 16;
				
				Explo = Screen->CreateEWeapon(EW_SBOMBBLAST);
				Explo->Damage = 0;
				Explo->X = 16 + Rand(14) * 16;
				Explo->Y = 16 + Rand(10) * 16;
				
			}
			
		}
		
		
	}
	else if(Game->GetCurScreen() == StartScreen && Game->GetCurDMap() == StartDMap){		//Starts the timer
		if(GlobalArray[GlobalEvent] <= 0) GlobalArray[ESC_G_TIME] = Time;
	}
	
}

void KillTimer(int Screen, int DMap){
if(GlobalArray[ESC_G_TIME] > 0){
  if(Game->GetCurDMap() == DMap && Game->GetCurScreen() == Screen) GlobalArray[ESC_G_TIME] = 0;
}
}

Example quest

Set-up instructions:
Configure all the Constants at the top of the script file to your liking.
Put: EscapeSequence( StartScreen, StartDMap, EndScreen, EndDMap, Time, GlobalEvent)
in your global script, replacing each thing with appropriate values. Global event is the number in the global array that it will refer to when checking if you have completed the sequence.
Time is measured in frames here, so, add 60 for every second you want. (conversely, this script would have it be impossible to make an escape longer than ~59 mins)
Start Screen and End Screen are measured in decimal, not hexadecimal, so the screen number ZC gives you will have to be converted (your regular calculate on windows can do this when set to programmer mode)

Concessions: If the player F6's out of this escape that will not reset or remove the timer on it's own, therefore a second script KillTimer is included. Put this in your global script too and call it by a screen and dmap combo that will kill the timer if link is ever on it.

 

While this is probably a good library, I'm not sure how useful that is to a none scripter.


  • ShadowTiger likes this

#9 Sans

Sans

    Hey kid wanna buy hot dogs ?

  • Members
  • Location:Judgement Hall

Posted 12 September 2021 - 07:52 PM

thanks :) i'll try it and make some test rooms. 




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users