Only one lockblock??
#16
Posted 21 January 2010 - 07:45 PM
That's me using bit-wise operators so I can store a lot more information in that one integer.
Do you understand how a number can be expressed in binary?
#17
Posted 21 January 2010 - 07:49 PM
And if you add something, it's like:
10011
01010 +
=
11001 (or is it 00110... I'm not sure)
Though, I'm still not sure what that line is doing.
#18
Posted 21 January 2010 - 08:01 PM
01010+ (10)
=
11101 (29)
I'm afraid.
Anyway, so you can express an integer as a string of bits, our ZScript variables hold 18.
This means that you can (with the right operations), use them like an array of booleans (which is what I'm doing).
The bitwise operators are &, |, ^, ~, << and >>.
AND, OR, XOR, NOT, Left Shift and Right Shift.
&, | and ~ work the same was as &&, || and ! do with boolean operators except they compare each bit together in the two integers, ^ is like checking for 'A != B', and << and >> move the bits along the variable by the amount specified on the right.
Saffith's explanation of them here is better than any I'm about to write now, so go and have a look at that =)
#19
Posted 21 January 2010 - 08:12 PM
[¯] = Lockblock
[¯] = Triggered Lockblock
-------------------------------
[¯][¯][¯][¯]
[¯][¯][¯][¯]
[¯][¯][¯][¯]
[¯][]][]][]]
-------------------------------
If you lay them out like that on your combo page, the player will be able to trigger the lockblock placed down from the top row first, then the one in the second row, then the one in the third row, and then the one in the fourth row. I just tested it out, and it works just fine.
Of course, if you don't trigger them in the right order, it breaks the effect. You have to know what the combo page looks like and how lockblock combos work. All the Lockblock combos on the screen, no matter if they're different combos, will be triggered at once.
... I'll bet this has been mentioned in this thread already.
Yeah, it has been. At least I posted a diagram.
*Is somewhat helpful*
#20
Posted 21 January 2010 - 08:14 PM
#21
Posted 21 January 2010 - 08:24 PM
I have a feeling that when you start on the next version that you'll be using a more independent class system, and then make combos the objects themselves. It'll probably be more efficient and cleaner that way, but at this point i know I'm dreaming.
#22
Posted 21 January 2010 - 08:27 PM
It wouldn't be hard to change it to work like you say, but that'd break all previous quests so no-one's about to do it.
Yeah, that'd be how I would want to make a future version of ZQuest at least. It's only a dream at the moment though, as you say.
I've spent the last few hours re-scripting a few different combotypes with ffcs which should allow us all a lot more freedom when it comes to lockblocks and chests and the like though, so hopefully everyone'll find them useful.
#23
Posted 21 January 2010 - 08:35 PM
... complicated. Though, I seem to get it a bit more now (no pun intended ^^' )
Though I still don't understand this line:
Under what circumstances would it be false? What is that while checking for, anyhow?
If d was 0 and perm was 0, then:
//but what if d was 1?
1 & 1 == 1 //false
I'm confused. Wouldn't you want it to be true, even if d was 1? And if d was 7, for that matter.
I have a feeling that when you start on the next version that you'll be using a more independent class system, and then make combos the objects themselves. It'll probably be more efficient and cleaner that way, but at this point i know I'm dreaming.
Heh, I wouldn't be surprised if the devs took a 20 year reprieve from ZQ updating once 2.5 is released! ^^'
Edited by AgentLym, 21 January 2010 - 08:36 PM.
#24
Posted 21 January 2010 - 08:43 PM
00000001 //Here is 1 expressed as an 8 bit integer, or '1 << 0'
00000010 //This is '1 << 1'
00000100 //This is '1<< 2'
10000000 //And this is '1 << 7'
So as you can see, 'perm' works out which bit of the string we want to use as our boolean.
Then we use & to check whether that bit has been set or not.
Let's say perm is 4, and the integer we're checking against looks like this already:
010110100
We're only interested in whether the 5th bit is 1 or not, so we use '&(1<<4)', and we get this calculation
000010000&
=
000010000
And it's not equal to 0, so the bit were checking for's been set.
'<<' finds the bit we want to compare, '|=' sets that bit that we want, and '&' checks it.
#25
Posted 21 January 2010 - 09:18 PM
void run(int pushtime, int sfx, int perm, int d){ //setup
if(pushtime == 0) pushtime = 10;
int loc = ComboAt(this->X,this->Y);
int pushclk = 0;
while((Screen->D[d] & (1<<perm)) == 0){ //checks to see if the specified bit along Screen->D[d] is already used or not
if(PushingCombo(loc) && CheckKeys()) pushclk++; //if it isn't, then run this part of the script
else pushclk = 0;
Waitframe();
if(pushclk == pushtime) Unlock(sfx,perm,d);
}
Screen->ComboD[loc]++;
}
void Unlock(int sfx, int perm, int d){
if(sfx == 0) Game->PlaySound(SFX_SHUTTER);
else if(sfx > 0) Game->PlaySound(sfx);
Screen->D[d] |= (1<<perm); //this sets... wait, how does this work? <--------------------
if(Game->LKeys[Game->GetCurLevel()] > 0) Game->LKeys[Game->GetCurLevel()]--;
else Game->Counter[CR_KEYS]--;
}
bool CheckKeys(){
return Game->Counter[CR_KEYS] > 0 || Game->LKeys[Game->GetCurLevel()] > 0;
}
bool PushingCombo(int loc){
int y = ComboY(loc); int x = ComboX(loc);
return (Link->Dir == DIR_UP && Link->InputUp && Link->Y == y+8 && Abs(Link->X-x) < 8)
|| (Link->Dir == DIR_DOWN && Link->InputDown && Link->Y == y-16 && Abs(Link->X-x) < 8)
|| (Link->Dir == DIR_LEFT && Link->InputLeft && Link->X == x+16 && Abs(Link->Y-y) < 8)
|| (Link->Dir == DIR_RIGHT && Link->InputRight && Link->X == x-16 && Abs(Link->Y-y) < 8);
}
}
ffc script Copycat{
void run(int perm, int d){
while((Screen->D[d] & (1<<perm)) == 0) Waitframe();
Screen->ComboD[ComboAt(this->X,this->Y)]++;
}
}
Edited by AgentLym, 21 January 2010 - 09:22 PM.
#26
Posted 21 January 2010 - 09:45 PM
You can technically get multiple Lock Blocks on the screen at the same time, but you can only trigger them in a set order. It's done via combo page layout.
[¯] = Lockblock
[¯] = Triggered Lockblock
-------------------------------
[¯][¯][¯][¯]
[¯][¯][¯][¯]
[¯][¯][¯][¯]
[¯][]][]][]]
-------------------------------
If you lay them out like that on your combo page, the player will be able to trigger the lockblock placed down from the top row first, then the one in the second row, then the one in the third row, and then the one in the fourth row. I just tested it out, and it works just fine.
Of course, if you don't trigger them in the right order, it breaks the effect. You have to know what the combo page looks like and how lockblock combos work. All the Lockblock combos on the screen, no matter if they're different combos, will be triggered at once.
... I'll bet this has been mentioned in this thread already.
Yeah, it has been. At least I posted a diagram.
*Is somewhat helpful*
You can only have 2 lockblocks through this method, however, because anything beyond that will reset upon entry into the room. If I remember correctly, not even perm. triggers solve this. Oh well... a man can dream.
#27
Posted 21 January 2010 - 09:50 PM
Btw, Joe, is it okay if I release it? (or did you want to ) I'm sure it'll come in mighty handy!
#28
Posted 21 January 2010 - 09:50 PM
Oh yeah, forgot about that. >.< It's why I tend to resort to making the tile warps instead, warping to identical screens. THAT way, they stay.
Of course, if you're having four lockblocks on the same screen where any can be triggered at any time, is that really good dungeon design? (much less screen design... sheesh.) Sure, it depends on what you want, but think of other methods too, to bypass any technical limitations barring you.
#29
Posted 21 January 2010 - 09:54 PM
I'm just not a big fan of duplicate dungeons (or overworlds, for that matter). Plus, I've always been prone to leaving out one little step or something, and it screws the whole thing up!
And, I just wanted to feel helpful. ^^
Edited by AgentLym, 21 January 2010 - 09:55 PM.
#30
Posted 22 January 2010 - 07:41 AM
void run(int pushtime, int sfx, int perm, int d){
if(pushtime == 0) pushtime = 10; //Set default value for pushtime, so it doesn't have to be set every time you use the script
int loc = ComboAt(this->X,this->Y); //This saves calculating ComboAt everytime we want to use it
int pushclk = 0;
while((Screen->D[d] & (1<<perm)) == 0){ //checks to see if the specified bit along Screen->D[d] is already used or not
//If it isn't, the block hasn't been unlocked. If it is, we don't want to unlock it again
if(PushingCombo(loc) && CheckKeys()) pushclk++; //If Link is pressing against the combo, and he has the right keys increment the 'pushclk', which counts how many frames he's been pressing against it for
else pushclk = 0; //If he stops pressing, don't allow the lockblok to unlock
Waitframe(); //duh
if(pushclk == pushtime) Unlock(sfx,perm,d); //If pushclk reaches pushtime, the block needs to be unlocked
}
Screen->ComboD[loc]++; //This changes the block's graphic
}
void Unlock(int sfx, int perm, int d){
if(sfx == 0) Game->PlaySound(SFX_SHUTTER); //If the sound effect is zero, use the default sound
else if(sfx > 0) Game->PlaySound(sfx); //Else use any sound the player wants
Screen->D[d] |= (1<<perm); //I'll explain this further down
if(Game->LKeys[Game->GetCurLevel()] > 0) Game->LKeys[Game->GetCurLevel()]--; //If Link has any level keys, use those instead of normal keys
else Game->Counter[CR_KEYS]--; //Otherwise take away a normal key
}
bool CheckKeys(){
return Game->Counter[CR_KEYS] > 0 || Game->LKeys[Game->GetCurLevel()] > 0; //Check for the different key types. I just realised I need to also allow for boss-key lockblocks
}
bool PushingCombo(int loc){
int y = ComboY(loc); int x = ComboX(loc); //Slightly quicker with variables
return (Link->Dir == DIR_UP && Link->InputUp && Link->Y == y+8 && Abs(Link->X-x) < 8) //If Link's pushing against the block from the bottom
|| (Link->Dir == DIR_DOWN && Link->InputDown && Link->Y == y-16 && Abs(Link->X-x) < 8) //Top
|| (Link->Dir == DIR_LEFT && Link->InputLeft && Link->X == x+16 && Abs(Link->Y-y) < 8) //Right
|| (Link->Dir == DIR_RIGHT && Link->InputRight && Link->X == x-16 && Abs(Link->Y-y) < 8); //Left
}
}
ffc script Copycat{
void run(int perm, int d){
while((Screen->D[d] & (1<<perm)) == 0) Waitframe();
Screen->ComboD[ComboAt(this->X,this->Y)]++;
}
}
Right,
Screen->D[d] == 10010100
10010100
00100000|
=
10110100
case 2:
Screen->D[d] == 10110100
10110100
00100000|
=
10110100
As you can see, if we OR a single bit agaisnt a bit string, it sets that bit to '1' regardles of what it was in the original bit string. So basically we're setting that one to true.
Yes, if you're using an interior map so you can't use the Door Combo Sets, and you want to have more than one locked door. You might even want 4 locked doors on a single screen, if you enter from a stairway or something.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users