Hold for Block

danno

Moderator
Staff member
I'd prefer not to use a block button with ajspecial, I'd like to hold attack to perform block, Does anyone know of any mods that already do this or script, I've searched around but couldn't find anything on holding attack to block.
 
danno said:
I'd prefer not to use a block button with ajspecial, I'd like to hold attack to perform block, Does anyone know of any mods that already do this or script, I've searched around but couldn't find anything on holding attack to block.
Hi danno. I have this script in SOR2X, I'm not using the default ajspecial block.

Here is the block animation:
Code:
anim freespecial2 #BLOCK
	loop	0
	delay	12
	offset	62 126
	bbox 	50 61 22 68
	@cmd block 1
	frame	data/chars/axel/block00.gif
	@cmd keyLoop "attack3" 0
	@cmd block 0
	frame	data/chars/axel/block00.gif

Here is the @cmd block script to apply blocking properties to the animation. Flag "1" to activate blocking status and flag "0" to deactivate:
Code:
void block(int flag)
{//Turns blocking status
	void self = getlocalvar("self");

	if(flag == 1){ //BLOCKING STATUS ON
		changeentityproperty(self, "aiflag", "blocking", 1);
		changeentityproperty(self, "takeaction", "common_block");
	}else{ //BLOCKING STATUS OFF
		changeentityproperty(self, "aiflag", "blocking", 0);
	}
}

Here is the keyLoop script:
Code:
void keyLoop(void key, int frame)
{//Loops defined frame if defined key is held
	void self 	= getlocalvar("self");
	int iPIndex = getentityproperty(self,"playerindex");

	if(playerkeys(iPIndex, 0, key)){
		updateframe(self, frame);
	}
}

In resume, if the defined key is held (in this example is attack 3), it will loop the frame "0" until the button is released. You need to define the same key that will be used to activate the corresponding freespecial animation in character header, like this:
com  a3 freespecial2 #BLOCK
 
danno said:
Thanks Kratus, I just tried it but it interrupts attack 1,  so attack 1 animation doesn't play and it goes straight to block.

I suggest to use the custom block animation in a freespecial using the default engine input configuration in char header. Also, you can use any other button if have some conflicts. Let me see the animation code, maybe I can help you better.
 
Code:
com a    freespecial12 #block

and

Code:
anim  freespecial12
	loop	0
	delay	20
	offset	37 102
	bbox	26 42 22 60
        @cmd block 1
	frame  Data/chars/ninja/dj44.gif
	@cmd keyLoop "attack" 0
	@cmd block 0
	frame  Data/chars/ninja/dj33.gif

This is how I have it set up. I'll also send you what I am working on so you can see.



 
danno said:
Code:
com a    freespecial12 #block

and

Code:
anim  freespecial12
	loop	0
	delay	20
	offset	37 102
	bbox	26 42 22 60
        @cmd block 1
	frame  Data/chars/ninja/dj44.gif
	@cmd keyLoop "attack" 0
	@cmd block 0
	frame  Data/chars/ninja/dj33.gif

This is how I have it set up. I'll also send you what I am working on so you can see.

Yeah, now I can see the problem. Need to change the "a" to any other attack button, like a2 (attack2) or a3 (attack 3), otherwise it will conflict with the attack1 animation. Here is an example:
Code:
com a3    freespecial12 #block
 
danno said:
That's the problem Kratus, I just wanted to use attack button for block, didn't want to add another button.

In this case I suggest to use attackboth animation instead of add a new button for a freespecial.
So, you can activate it by pressing "attack + jump" and then holding attack button to maintain the block animation, like this:
Code:
anim  attackboth
	loop	0
	delay	20
	offset	37 102
	bbox	26 42 22 60
	@cmd block 1
	frame  Data/chars/ninja/dj44.gif
	@cmd keyLoop "attack" 0
	@cmd block 0
	frame  Data/chars/ninja/dj33.gif
 
Use key script on a1 press have it move into block maybe with a small delay to check if your still holding a1 and have your default attack happen when you release a1 but you can't use atchain with this method.
 
Kratus and danno,

msmalik681 is right, you guys are on the right track, you just need to insert a check into the looping script that prevents it from taking the block action until either a certain amount of time passes or the attack animation is at a given frame.

Just think of Shinobi 3, where holding attack assumes a block position, but only after the initial attack animation completes. You might not want to make players wait that long in your game, but I'd at least delay a block initiating until ~halfway through the attack animation.

DC
 
Damon Caskey  Funny you should mention Shinobi because that's exactly what I am trying to achieve, would be simpler to just use another button but I'd like to use Shinobi style because of its flow factor

https://www.youtube.com/watch?v=9XQme1DSL0Q

Kratus
couple of issues, while using attackboth more than 1 button needs to be pressed and can sometimes be hit or miss during gameplay, sometimes I'd jump before blocking

msmalik681
this sounds ideal but I don't want to lose atchain

Then I have to figure out how to walk while blocking, duck block and duck walk block, this is why single button press hold is key (no pun intended)  ;D

 
Lemme see if I understood correctly: You want your character to change into "Block" animation if the player is holding the attack button after the end of your character's attack, is this right?
 
Guardians/ Denjin Makai 2 also have block activated by holding attack button after attacking

I was going to suggest something like this:
Code:
anim attack1
	delay	3
	offset	42 127
	bbox	37 15 45 113
	frame	data/chars/maxima/wkick01.gif
        bbox	45 14 41 114
	frame	data/chars/maxima/wkick02.gif
        bbox	51 13 38 115
	frame	data/chars/maxima/wkick03.gif
        delay   9
	attack16 69 62 64 32 9
	frame	data/chars/maxima/wkick04.gif
        delay   3
        attack  0
	frame	data/chars/maxima/wkick05.gif
        bbox	40 17 48 111
	frame	data/chars/maxima/wkick06.gif
        bbox	32 16 46 112
        frame	data/chars/maxima/wkick07.gif
        @cmd    keyint "ANI_BLOCK" 0 "A" 0 0
        frame	data/chars/maxima/wkick07.gif

however the timing might be too close IOW player will have to release attack button as soon after ATTACK1 is performed to prevent going to BLOCK animation after attacking

I don't have other solution ATM
 
danno said:
Yes Paulo just like this
danno
Hmmm, now I understand better and I have two suggestions.

Bloodbane posted a good solution, my first suggestion is the same as his. In SOR2X if you hold block key during riseattack or dodge, the character will go to block animation as soon the previous animation ends. Here is the code, need to be used in chacarter's animation script file:
Code:
void keyAni(void key, void ani)
{//Execute animation if defined key is held
	void self 	= getlocalvar("self");
	int iPIndex = getentityproperty(self,"playerindex");
	
	if(playerkeys(iPIndex, 0, key)){
		executeanimation(self, openborconstant(ani));
	}
}

And here is how it should be used in character's animation. This solution was implemented in kunai throw as a alternative method, but can be used in any animation :
Code:
anim	freespecial2 #standing
	loop    0
	delay	7
	offset	37 102
	bbox	21 43 29 59
	frame	data/chars/ninja/ku1.gif
	frame	data/chars/ninja/ku1.gif
	frame	data/chars/ninja/ku1.gif
	@cmd	shooter2 "kun1" 32 43 0 2.5
	sound   Data/chars/ninja/k.wav
	frame	data/chars/ninja/ku2.gif
	@cmd keyAni "attack2" "ANI_FREESPECIAL12"
	frame	data/chars/ninja/ku2.gif

The second solution is more complex due to "atchain". For example, if you use the first method in the last frame of the "attack1" animation, depending on how fast you press the attack button to perform "atchain", the "attack2" will not be performed and the character will go to block animation.

I tried to develop a solution in character's key script but not worked well because for some reason it needs a second key to trigger the keyscript event. Holding attack button only will not trigger key script event when it use "elapsed_time" for delay counter. It works only if you hold attack and then press any other button after.

Fortunately it worked well in ondraw event, I think is because it runs even if you not press a key. All you need is to create a ondraw.c file, copy all code inside it and call in the character header as a "ondrawscript" event:

Here is an example of how the character header will be:
Code:
ondrawscript    data/chars/ninja/ondraw.c

Here is the code:
Code:
void main()
{//Execute animation if defined key is held according to a defined delay
	void self 	= getlocalvar("self");
	void ani	= getentityproperty(self,"animationID"); //GET CURRENT ANIMATION
	int iPIndex = getentityproperty(self,"playerindex"); //GET PLAYER INDEX
	float time	= openborvariant("elapsed_time"); //GET CURRENT TIME
	float delay = 45; //DELAY NECESSARY TO CHANGE THE ANIMATION
	
	//THIS SCRIPT WILL ONLY WORK IN ATTACK ANIMATIONS ONLY BUT YOU CAN ADD OR REMOVE ANY OTHER ANIMATION HERE
	if(ani == openborconstant("ANI_ATTACK1") || ani == openborconstant("ANI_ATTACK2") || ani == openborconstant("ANI_ATTACK3")){
		if(playerkeys(iPIndex, 0, "attack")){ //ATTACK KEY IS HELD??
			if(getlocalvar("start_time") == NULL()){ //FISRT TIME HOLDING THIS KEY??
				setlocalvar("start_time", time); //SAVE CURRENT TIME
			}
			
			if(time - getlocalvar("start_time") > delay){ //HOLDING ATTACK BUTTON AND DELAY IS REACHED THE LIMIT??
				executeanimation(self, openborconstant("ANI_FREESPECIAL12"), 1); //CHANGE TO BLOCK ANIMATION
				setlocalvar("start_time", NULL()); //RESET DELAY COUNTER
			}
		}else{ //ATTACK KEY IS RELEASED??
			if(getlocalvar("start_time") != NULL()){ //USED TO RUN ONCE
				setlocalvar("start_time", NULL()); //RESET DELAY COUNTER
			}
		}
	}else{ //NO ATTACK ANIMATION??
		if(getlocalvar("start_time") != NULL()){ //USED TO RUN ONCE
			setlocalvar("start_time", NULL()); //RESET DELAY COUNTER
		}
	}
}

Don't forget to use it together with @cmd keyLoop scripts and @cmd block, that I sent to you. You need to add all keys you want to hold and maintain the block animation:
Code:
anim  freespecial12
	loop	0
	delay	20
	offset	37 102
	bbox	26 42 22 60
	@cmd block 1
	frame  Data/chars/ninja/dj44.gif
	@cmd keyLoop "attack2" 0
	@cmd keyLoop "attack" 0
	@cmd block 0
	frame  Data/chars/ninja/dj33.gif
I hope it works. From this point, you can adapt the scripts to work in other animations.
 
On phone atm, but I can offer some tips on key script, since it's always the best way to work with key commands:

1. You can't detect "holding" the key that triggered a key script, because there's really no such thing. Long story. You can only check the hold status of another key. This would seem to be a problem except that....

2. Remember that keyscrpit events also activate when you RELEASE the key. This is how you create key controlled loops (and how the pros do it too). IOW, you don't continuously monitor holding of a key, you just start the animation or whatever, and configure it to continue until a release event is detected. Then you stop it.

That also makes life simpler when you start to work on the next step (movement while blocking).

3. Unrelated, but key IDs are set up so you can use bit wise logic on them. I can explain further if you need. This is really helpful when you want to detect key combinations because it can make your scripts a lot less messy and complex.

DC
 
Damon Caskey
I'm gonna run some more tests with what Kratus and Bloodbane have suggested, I would prefer keyscript because I'll need to switch between several animations  while holding attack, block walking to duck block walking for example.
 
Damon Caskey said:
On phone atm, but I can offer some tips on key script, since it's always the best way to work with key commands:

1. You can't detect "holding" the key that triggered a key script, because there's really no such thing. Long story. You can only check the hold status of another key. This would seem to be a problem except that....

2. Remember that keyscrpit events also activate when you RELEASE the key. This is how you create key controlled loops (and how the pros do it too). IOW, you don't continuously monitor holding of a key, you just start the animation or whatever, and configure it to continue until a release event is detected. Then you stop it.

That also makes life simpler when you start to work on the next step (movement while blocking).

3. Unrelated, but key IDs are set up so you can use bit wise logic on them. I can explain further if you need. This is really helpful when you want to detect key combinations because it can make your scripts a lot less messy and complex.

DC

Damon Caskey
Nice, is good to know that. It's explain why the animation changes when I press a second key while another is held, because in fact the engine is not detecting the held key anymore, but will detect the new key event. I'm particulary interested in this case because want to explore more this "hold button" feature.

I understand and agree to the fact that is better to use all keyscripts in the same file, the maximum as possible. However, I'm using a lot of keyscripts in SOR2X specially in menus and I have to say that unfortunately they can't do all tasks alone. Sometimes I need to broke the script in two or more parts and apply in other events like updated.c, ondraw, animation, etc...

An example is the "arcade lock" feature that I added in the last version. Half of the script is on keyall.c that detects the when the screenshot button is held and save a variable. The other half is on updated.c, that will detect the saved varibale and check the necessary time to activate the function, drawing all info on the screen.

One more detail, I need to detect when the key is released using "else" to reset the variable and "simulate" a "held/release" button detection feature:
Code:
if(playerkeys(player, 0, "screenshot")){ //SCREENSHOT KEY IS PRESSED AND HELD?
	setglobalvar("lockCountdown", 1); //INDICATES THAT THE SCREENSHOT KEY IS HELD
}else{
	setglobalvar("lockCountdown", 0); //INDICATES THAT THE SCREENSHOT KEY IS RELEASED, RESET COUNTDOWN
}

Is good to know more details of the keyscripts, thanks DC!
 
Back
Top Bottom