Jump to content

Photo

Separate Keys For Lock Blocks


  • Please log in to reply
9 replies to this topic

#1 Gouanaco

Gouanaco

    Death Knight

  • Members
  • Real Name:Max
  • Location:Australia

Posted 24 November 2016 - 09:15 AM

Hello everyone, I have a script request.

 

My original idea was that I wanted a second type of key they could be used on a lockblock.

So that there would be the normal keys aswell as the special keys.

***So that when Link uses the key he will have to choose one spefic path over the other since there will be only a certain number of special keys for the special lockblocks.

 

I initially tried using boss keys but they are universal and are not consumed when used regardless.

 

I have attempted to use the script found in this thread: http://www.purezc.ne...key#entry887045

But to no avail.

 

Rundown:

Need more than 1 type of key

Able to unlock lockblocks (or any combo really)

Can be used across different screens

Special key is consumed on use like normal keys

 

Thank you all for any assistance :)

 

edit: ***


Edited by Gouanaco, 24 November 2016 - 09:18 AM.


#2 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 24 November 2016 - 01:07 PM

This might work without a script, but it will require some very specific screen set ups. For this to work, you'll only be able to have one type, or the other on one screen at a time (so any screen either has a locked door, or lockblock, never both).

Basically what you'll want to do is make a separate d-map that will be used only on the screens where you'll find the special keys, and screens with the lock blocks. Make sure the d-map is set up the same, with music, palette, and all that, and make the level number higher than 0. If your area is already using level specific keys, than give this new d-map an arbitrary above 0 value that won't interfer with other d-maps, and that isn't the same level number as your current map.

When Link goes from a screen to a screen with the special key, or lock block, have it scroll Warp him to your other d-map you set up. Give him a level specific key, and presto, you now have a second set of keys to use but only on those screens.

Use caution with this, as it is mostly untested. Also, it's a good idea to make it so Link can't die on this special d-map, as it might cause continue bugs, or make the game think the whole dungeon is the special map. Be sure to use scroll warps to return Link to the original d-map from any possible way he may leave the screen. Some parts of this might not work based on what the scope of your area is. I'm imagining a standard dungeon.

Hope that helps a little.
  • Gouanaco likes this

#3 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 24 November 2016 - 07:39 PM

Here's the script for you:
 
Special Key Lockblocks

 
This allows using up to four distinct lockblocks per screen that take a single type of 'special key', not one special key each mind, but one type of special key for all custom lockblock types. It merely allows you to have more than one per screen, easily.
 
Special Key Lockblocks test Quest

Edited by ZoriaRPG, 24 November 2016 - 10:50 PM.

  • Gouanaco likes this

#4 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 24 November 2016 - 09:07 PM

Set-up Details

Create eight combos, as follows;


1. Lock block tile, combo type 'none', solid. Note down the combo ID for this one, as you will need it later.
2. Unlocked lock block tile, combo type 'none', no solidity.
3. Same as 1
4. Same as 2
5. Same as 1
6. Same as 2
7. Same as 1
8. Same as 2

These combos must be sequential. See the combo page used in the test quest.

Assign the ID of (1) to the constant 'CMB_LOCKBLOCK2' in the script.

Assign an unlock sound from Quest->Audio->SFX to the constant 'SFX_SPEC_LOCKBLOCK' in the script file. The default is the 'Shutter' sound in the Classic tileset.

Create a new item, with a key tile. Assign its counter ref to CR_SCRIPT1, or if you are using that for something else, pick a different script counter and assign the constant 'CR_LOCKBLOCK' key (in the script) to the value of that counter (see std_constants.zh).

Set it's type to a custom item class type.

Set it's counter 'increase' and 'not above' values' to whatever you want as the cap. I used 99.

Compile the script, and assign the ffc script to a slot. The included item script is not used.

Place the ffc on a screen on which you intend to use the special lockblocks.

Set the ffc combo to combo ID '1', or a combo with a blank tile that is not Combo 0.

Set the script of the ffc to 'SpecialLockBlock'.

Set the ffc flag 'Run on screen init.'

Place custom lockblocks on the screen.

#5 Gouanaco

Gouanaco

    Death Knight

  • Members
  • Real Name:Max
  • Location:Australia

Posted 25 November 2016 - 01:02 AM

Well thank you both, ZoriaRPG and Anthus.

 

 

I shall try the script first and see how that goes, if all else fails for whatever reason ill give Anthus's method a shot.

 

Thanks again :)



#6 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 25 November 2016 - 01:36 AM

Well thank you both, ZoriaRPG and Anthus.
 
 
I shall try the script first and see how that goes, if all else fails for whatever reason ill give Anthus's method a shot.
 
Thanks again :)


Just use the example quest as your guide... Right-click one of the four lockblock combos, view its combo page, and the set-up should be self-evident.

I added this to the script database, with one minor improvement: It also works with ordinary keys, as an option. Setting up multiple lock-blocks per screen is rather painful, so the ffc script may be a good option for the general userbase.

Edited by ZoriaRPG, 25 November 2016 - 01:40 AM.


#7 Gouanaco

Gouanaco

    Death Knight

  • Members
  • Real Name:Max
  • Location:Australia

Posted 25 November 2016 - 08:32 AM

Just use the example quest as your guide... Right-click one of the four lockblock combos, view its combo page, and the set-up should be self-evident.

I added this to the script database, with one minor improvement: It also works with ordinary keys, as an option. Setting up multiple lock-blocks per screen is rather painful, so the ffc script may be a good option for the general userbase.

Just tried it out but when I compile is says that on line 952 CR_KEYS is undeclared.

I tried 

 

int CR_KEYS;

and

int CR_LKEYS;

 

which allowed it to compile however the script doesnt seem to work in game.


Edited by Gouanaco, 25 November 2016 - 10:19 AM.


#8 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 25 November 2016 - 10:53 AM

Just tried it out but when I compile is says that on line 952 CR_KEYS is undeclared.
I tried 
 
int CR_KEYS;
and
int CR_LKEYS;
 
which allowed it to compile however the script doesnt seem to work in game.


Did you forget to import std.zh?

Here is a slight update, that you may also find in the database:
 
////////////////////////////
/// Scripted Lock Blocks ///
/// v0.3 - 25-Nov-2016   ///
/// By: ZoriaRPG         ///
////////////////////////////

//Main Settings

const int USE_CUSTOM_KEYS = 1; //If se to '1', the script will require a custom key type, tied to
			//a script counter, configured below. 

//User Settings
const int CBM_LOCKBLOCK2 = 888; //The combo used by the special lockblock. 

const int TIMER_WALK_UNLOCK = 50; //The number of frames that Link must push against the lockblock to open it.
const int CR_LOCKBLOCKKEY = 7; //Script 1
const int SFX_SPEC_LOCKBLOCK = 9; //The sound to play when unlocking a lockblock.
const int CR_MAX_LOCKBLOCKKEY = 32; //The maximum number of special keys that Link may have. Used only with the item script.

const int SCREEN_D_SPECIALLOCKBLOCK = 7;

//In the event that you want to know how to script a key, too. 
item script SpecialLockBlockKey{
	void run(){
		if ( Game->MCounter[CR_LOCKBLOCKKEY] < CR_MAX_LOCKBLOCKKEY ) Game->MCounter[CR_LOCKBLOCKKEY] = CR_MAX_LOCKBLOCKKEY;
		Game->Counter[CR_LOCKBLOCKKEY]++;
	}
}


//Flags for up to four lock blocks.
const int SPC_LOCK_1 = 0001b;
const int SPC_LOCK_2 = 0010b;
const int SPC_LOCK_3 = 0100b;
const int SPC_LOCK_4 = 1000b;

ffc script SpecialLockBlock{
	void run(int block){
		int cmb;
		int timer = TIMER_WALK_UNLOCK;
		if ( Screen->D[SCREEN_D_SPECIALLOCKBLOCK] ) {
			for ( int q = 0; q < 176; q++ ) {
				if ( LockBlockFlag(SPC_LOCK_1) && Screen->ComboD[q] == CBM_LOCKBLOCK2 ) Screen->ComboD[q]++;
				if ( LockBlockFlag(SPC_LOCK_2) && Screen->ComboD[q] == CBM_LOCKBLOCK2 + 2 ) Screen->ComboD[q]++;
				if ( LockBlockFlag(SPC_LOCK_3) && Screen->ComboD[q] == CBM_LOCKBLOCK2 + 4 ) Screen->ComboD[q]++;
				if ( LockBlockFlag(SPC_LOCK_4) && Screen->ComboD[q] == CBM_LOCKBLOCK2 + 6 ) Screen->ComboD[q]++;
			}			
		}
		while ( true ) {
			
			if ( 
				( !USE_CUSTOM_KEYS && ( Game->Counter[CR_KEYS] || Game->LKeys[Game->GetCurLevel()] ) ) ||
				( USE_CUSTOM_KEYS && Game->Counter[CR_LOCKBLOCKKEY] ) ) 
			{
				if ( Link->Dir == DIR_UP ){
					cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),1) ];
					
					if ( cmb == CBM_LOCKBLOCK2 || cmb == CBM_LOCKBLOCK2 +2 || cmb == CBM_LOCKBLOCK2 + 4 || cmb == CBM_LOCKBLOCK2 +6 ) {
						if ( timer && Link->InputUp ) timer--;
						if ( timer <= 0 ) { 
							if ( USE_CUSTOM_KEYS ) Game->Counter[CR_LOCKBLOCKKEY]--; 
							if ( !USE_CUSTOM_KEYS ) {
								if ( Game->LKeys[Game->GetCurLevel()] ) Game->LKeys[Game->GetCurLevel()]--;
								else Game->Counter[CR_KEYS]--;
							}
							if ( SFX_SPEC_LOCKBLOCK ) Game->PlaySound(SFX_SPEC_LOCKBLOCK); 
							Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),1) ]++; 
							if ( cmb == CBM_LOCKBLOCK2 ) {
								LockBlockFlag(SPC_LOCK_1,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 2 ) {
								LockBlockFlag(SPC_LOCK_2,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 4 ) {
								LockBlockFlag(SPC_LOCK_3,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 6 ) {
								LockBlockFlag(SPC_LOCK_4,true);
							}
							timer = TIMER_WALK_UNLOCK; 
							Link->InputUp = false; 
						}
					}
					else timer = TIMER_WALK_UNLOCK;
				}
				else if ( Link->Dir == DIR_DOWN ){
					cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),5) ];
					
					if ( cmb == CBM_LOCKBLOCK2 || cmb == CBM_LOCKBLOCK2 +2 || cmb == CBM_LOCKBLOCK2 + 4 || cmb == CBM_LOCKBLOCK2 +6 ) {
						if ( timer > 0 && Link->InputDown ) timer--;
						if ( timer <= 0 ) { 
							if ( USE_CUSTOM_KEYS ) Game->Counter[CR_LOCKBLOCKKEY]--; 
							if ( !USE_CUSTOM_KEYS ) {
								if ( Game->LKeys[Game->GetCurLevel()] ) Game->LKeys[Game->GetCurLevel()]--;
								else Game->Counter[CR_KEYS]--;
							}
							if ( SFX_SPEC_LOCKBLOCK ) Game->PlaySound(SFX_SPEC_LOCKBLOCK); 
							Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),5) ]++; 
							if ( cmb == CBM_LOCKBLOCK2 ) {
								LockBlockFlag(SPC_LOCK_1,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 2 ) {
								LockBlockFlag(SPC_LOCK_2,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 4 ) {
								LockBlockFlag(SPC_LOCK_3,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 6 ) {
								LockBlockFlag(SPC_LOCK_4,true);
							}
							timer = TIMER_WALK_UNLOCK; 
							Link->InputDown = false; 
						}
					}
					else timer = TIMER_WALK_UNLOCK;
				}
				else if ( Link->Dir == DIR_LEFT ) {
					cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),7) ];
					if ( cmb == CBM_LOCKBLOCK2 || cmb == CBM_LOCKBLOCK2 +2 || cmb == CBM_LOCKBLOCK2 + 4 || cmb == CBM_LOCKBLOCK2 +6 ) {
						if ( timer > 0 && Link->InputLeft ) timer--;
						if ( timer <= 0 ) { 
							if ( USE_CUSTOM_KEYS ) Game->Counter[CR_LOCKBLOCKKEY]--; 
							if ( !USE_CUSTOM_KEYS ) {
								if ( Game->LKeys[Game->GetCurLevel()] ) Game->LKeys[Game->GetCurLevel()]--;
								else Game->Counter[CR_KEYS]--;
							}
							if ( SFX_SPEC_LOCKBLOCK ) Game->PlaySound(SFX_SPEC_LOCKBLOCK); 
							Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),7) ]++; 
							if ( cmb == CBM_LOCKBLOCK2 ) {
								LockBlockFlag(SPC_LOCK_1,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 2 ) {
								LockBlockFlag(SPC_LOCK_2,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 4 ) {
								LockBlockFlag(SPC_LOCK_3,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 6 ) {
								LockBlockFlag(SPC_LOCK_4,true);
							}
							timer = TIMER_WALK_UNLOCK; 
							Link->InputLeft = false; 
						}
					}
					else timer = TIMER_WALK_UNLOCK;
				}
				else if ( Link->Dir == DIR_RIGHT ) {
					cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),3)];
					if ( cmb == CBM_LOCKBLOCK2 || cmb == CBM_LOCKBLOCK2 +2 || cmb == CBM_LOCKBLOCK2 + 4 || cmb == CBM_LOCKBLOCK2 +6 ) {
						if ( timer > 0 && Link->InputRight ) timer--;
						if ( timer <= 0 ) { 
							if ( USE_CUSTOM_KEYS ) Game->Counter[CR_LOCKBLOCKKEY]--; 
							if ( !USE_CUSTOM_KEYS ) {
								if ( Game->LKeys[Game->GetCurLevel()] ) Game->LKeys[Game->GetCurLevel()]--;
								else Game->Counter[CR_KEYS]--;
							}
							if ( SFX_SPEC_LOCKBLOCK ) Game->PlaySound(SFX_SPEC_LOCKBLOCK); 
							Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),3) ]++; 
							if ( cmb == CBM_LOCKBLOCK2 ) {
								LockBlockFlag(SPC_LOCK_1,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 2 ) {
								LockBlockFlag(SPC_LOCK_2,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 4 ) {
								LockBlockFlag(SPC_LOCK_3,true);
							}
							if ( cmb == CBM_LOCKBLOCK2 + 6 ) {
								LockBlockFlag(SPC_LOCK_4,true);
							}
							timer = TIMER_WALK_UNLOCK; 
							Link->InputRight = false; 
						}
					}
					else timer = TIMER_WALK_UNLOCK;
					
				}
				
			}
			else timer = TIMER_WALK_UNLOCK;
			Waitframe();
		}
	}

	void LockBlockFlag(int flag, bool state){
		if(state) Screen->D[SCREEN_D_SPECIALLOCKBLOCK] |= flag;
		else Screen->D[SCREEN_D_SPECIALLOCKBLOCK] &= ~flag;
	}

	bool LockBlockFlag(int flag){
		return (Screen->D[SCREEN_D_SPECIALLOCKBLOCK]&flag) != 0;
	}

	//Constants for AdjacentCombo()

	//const int CMB_UPLEFT    = 0;
	//const int CMB_UP        = 1;
	//const int CMB_UPRIGHT   = 2;
	//const int CMB_RIGHT     = 3;
	//const int CMB_DOWNRIGHT = 4;
	//const int CMB_DOWN      = 5;
	//const int CMB_DOWNLEFT  = 6;
	//const int CMB_LEFT      = 7;
	//const int CMB_LEFTUP    = 0; //Not 8, as those are dir + shield

	//Returns the Nuth combo index of a combo based on a central point, and a direction.
	//For example, combo 22 + COMBO_UPRIGHT returns '7', 
	//as combo 7 is to the upper-right of combo 22.
	int ___AdjacentCombo(int cmb, int dir){
	    int combooffsets[13]={-0x11,-0x10,-0x0F,1,0x11,0x10,0x0F,-1,-0x10};
	    if ( cmb % 16 == 0 ) combooffsets[9] = 1;
	    if ( (cmb & 15) == 1 ) combooffsets[10] = 1; 
	    if ( cmb < 0x10 ) combooffsets[11] = 1; //if it's the top row
	    if ( cmb > 0xAF ) combooffsets[12] = 1; //if it's on the bottom row
	    if ( combooffsets[9] && ( dir == 7 || dir == 1 || dir == 4 || dir == 0 ) ) return 0; //if the left columb
	    if ( combooffsets[10] && ( dir == 3 || dir == 2 || dir == 4 ) ) return 0; //if the right column
	    if ( combooffsets[11] && ( dir == 2 || dir == 2 || dir == 1 ) ) return 0; //if the top row
	    if ( combooffsets[12] && ( dir == 5 || dir == 4 || dir == 6 ) ) return 0; //if the bottom row
	    else if ( cmb >= 0 && cmb <= 176 ) return cmb + combooffsets[dir];
	    else return -1;
	}
}


Oh, I see... You used the one from the database, not the thread, and I pasted the wrong script file when I made the entry.

I just updated it, but the code above is 'final', and you should use that.

If you have any other problems, just use the script that I originally posted in the thread. That script does exactly what you requested, so you don't have a reason to worry about Level Keys.

Edited by ZoriaRPG, 25 November 2016 - 11:12 AM.


#9 Gouanaco

Gouanaco

    Death Knight

  • Members
  • Real Name:Max
  • Location:Australia

Posted 25 November 2016 - 01:02 PM

Thanks ZoriaRPG, I complied that new fandangled script of yours and after fiddling with a few things I have got it working.

I appreciate your help and I am sure your database entry will be of much use to the community.



#10 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 26 November 2016 - 07:20 AM

Thanks ZoriaRPG, I complied that new fandangled script of yours and after fiddling with a few things I have got it working.
I appreciate your help and I am sure your database entry will be of much use to the community.


Ace! It's good to hear that you have it working.

One thing that I suggest, is that you lower the timer constant. I set it to 45 or 50 frames, but it should probably be around 20 to 25 if you want to mimic normal lockblock 'push against to open' timing. I never toyed with it to adjust it to replicate the system, as I didn't feel like sending the time with frame-advance to count the exact duration, when I had so many other things that I was already doing.

I might make an 'open lockblock with button press' update to it eventually, but for now, it's good-enough.

Edited by ZoriaRPG, 26 November 2016 - 07:20 AM.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users