[SOLVED] Enabling random attacks for enemies

Hello there, fellow developers!

My project has a "move set" system for enemies; Each enemy features 5-6 different attacks, but I want each one to only enable 2-3 of them.

My initial idea was to store which attacks were enabled in entityvars and, when the entity performed a disabled attack, a animchange function would stop them from doing so.

My problem is that the enemies are guided by all their attack ranges, so a attack that has a long range and is disable would "stunlock" the enemy.

Taking a look at the manual, I've noticed the {disable} parameter on the energycost animation header. Using energycost 0 0 1 disables the attack properly, but is there any method to ENABLE the attack back?
 
just use their names as argument in script and redirect attacks to the ones theyre meant to use.
Thats what i would do, you can do animationchange from disallowed attack to allowed attack on first frame.
better yet, use idle frame on 1st frame of every aattack, so switch wont be noticeable but it shouldnt be anyway cause that works fast

Code:
@script
    void self = getlocalvar("self");
    char Name = getentityproperty(self,"name");
   if( Name == "cockroach"){
changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
    }
@end_script
 
That's the point, you are disabling a attack when it's already triggered, so a character with a disabled long range attack would stunlock itself, trying to perform such attack but regressing ot it's idle animation.

That's why I'm trying to disable all moves beforehand, and use some script to reactivate them.
 
Not sure what you mean by stunlock by regressing, it rarely happens when you messup aiflags and get entity to pain animor idle without changing flags, try performattack instead of anim cange.
You can change it to fake walk or whatever, doesnt need to be attack, then wait for bettter solution while using this workaround.
You want shortcut but to be honest, you should of do multiple copies of enemies with different attacks disabled instead of trying to fix something and cram all attacks into one entity.I do that sometimes but Im pretty sure disabling attacks is not accessible to script so you have to use anim switching.
energycost drains enemies health they dont have mp bar, imo its a headache and script is a better solution, just figure out what exactly you want enemy to do when canceling attack into other animation.

If you mean that range keeps enemy doing the same attack spamming over and over and canceling it to idle, then make him walk back a bit, or something else that would moeve him, add target for him out of the range , whatever so hes not at the same spot all the time.I had that issue happen, IMO that should been taken care of at the engine sourcecode level not by scripting.
But maybe decreasing aggression when canceling would make him just walk instead of attacking again.
 
Paulo HP Bender

Using energycost 0 0 1 disables the attack properly, but is there any method to ENABLE the attack back?

Code:
int disable = getentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"));

if("Desired_Condition_is_Reached"){
	changeentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"), 0);
}
 
Kratus said:
Paulo HP Bender

Using energycost 0 0 1 disables the attack properly, but is there any method to ENABLE the attack back?

Code:
int disable = getentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"));

if("Desired_Condition_is_Reached"){
	changeentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"), 0);
}

You
Are
A
Life
SAVER!

Thanks a LOT, my friend!
 
Paulo HP Bender said:
Kratus said:
Paulo HP Bender

Using energycost 0 0 1 disables the attack properly, but is there any method to ENABLE the attack back?

Code:
int disable = getentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"));

if("Desired_Condition_is_Reached"){
	changeentityproperty(self, "energycost", "disable", openborconstant("ANI_DESIRED_ANIMATION"), 0);
}

You
Are
A
Life
SAVER!

Thanks a LOT, my friend!
:)
I'm using it on SOR2X to enable/disable some "energycost" properties in the extra menu.
 
Paulo HP Bender said:
Taking a look at the manual, I've noticed the {disable} parameter on the energycost animation header. Using energycost 0 0 1 disables the attack properly

I've tried setting that command on an enemy's freespecial but enemy can perform the attack normally  :-[ .
Is there something else I'm missing to disable that freespecial?
 
Bloodbane

Bloodbane said:
Paulo HP Bender said:
Taking a look at the manual, I've noticed the {disable} parameter on the energycost animation header. Using energycost 0 0 1 disables the attack properly

I've tried setting that command on an enemy's freespecial but enemy can perform the attack normally  :-[ .
Is there something else I'm missing to disable that freespecial?

Hmm, curiously it didn't work for me too in the first test. After taking a look in the source code, I discovered that for some reason the "disable" function works with negative numbers, differently of what the manual says.

Code:
if(!(energycost.disable == type													// Disabled by type?
                || (energycost.disable == -1)											    // Disabled for all?
                || (energycost.disable == -2 && (type & (TYPE_ENEMY  | TYPE_NPC)))		    // Disabled for all AI?
                || (energycost.disable == -3 && (type & (TYPE_PLAYER | TYPE_NPC)))	        // Disabled for players & NPCs?
                || (energycost.disable == -4 && (type & (TYPE_PLAYER | TYPE_ENEMY)))))     // Disabled for all AI?
        {

energycost {int} {mponly} {disable}
~Can be used in player's SPECIAL, SPECIAL2, and FREESPECIAL(#) animations.
~{mponly} controls where this attack drains it's energycost from. It works exactly same with 'mponly' command
below.
~{disable} controls entities which can't use animation in which this command is declared. Useful to use same
weapon models for players, NPCs and enemies with special abilities limitation.
0 = None (default). Every entity can use this animation
1 = All entities
2 = Enemies and NPCs
3 = Players and NPCs
4 = Players and Enemies
~When the attack is performed, (int) will be subtracted from one of the player's stats. Which one depends on
several factors:
~If the player has enough MP to use the attack, it comes from their MP.
~If they don't have enough MP, but have enough HP to make up the difference and the attack is not set to
'mponly', their MP will be drained and the anything left will be taken from HP.
~If the player has 'mponly' set to 2 or simply don't have an MP bar, this will always come from the player's health.
~This command also work with enemies. Since enemies don't have MP, this command will only drain health.
~If the user does not have more than {int} life remaining, they can't perform the attack. If they have a CANT
animation, they will play that instead.
~Defaults to 6 for SPECIAL and 0 for anything else.

In the second test I used negative numbers and now it works correctly.
Thanks for showing us that  :)
 
Thanks for the info Kratus  ;D

For some reason, setting disable parameter with script doesn't work. However, I used it in inverse like this: use energycost to disable enemy's attack then use script to enable it. That works well  8)

BTW while I'm here, what is subproperty name to control value of energycost?
 
For some reason, setting disable parameter with script doesn't work
I did some tests and the scripted method only worked with negative numbers too. Surprisingly it worked even if the animation doesn't have the "energycost" function in the header.
It gives me a lot of cool ideas :)

BTW while I'm here, what is subproperty name to control value of energycost?
You can change the value by using the subproperty "cost", like this:

Code:
changeentityproperty(self,"energycost", "cost", openborconstant("Desired_Animation"), "Desired_Value");
 
I have discovered a rather troublesome failure on my approach;
When one enemy entity unlocks a freespecial, all other enemy entities with the same model ALSO get these freespecials unlocked. Sooner or later, all entities using this same model will have all their freespecials unlocked. Any suggestions on how to better design this "move set" system?

EDIT:
After a whole afternoon of frustrating tests, I've come into conclusion that there's a bug on teh engine; trying to use changeentityproperty to change the energycost and/or disable on a move changes the MODEL property. I'll post the issue on GitHub, along with as much material as possible.
 
Paulo HP Bender said:
I have discovered a rather troublesome failure on my approach;
When one enemy entity unlocks a freespecial, all other enemy entities with the same model ALSO get these freespecials unlocked. Sooner or later, all entities using this same model will have all their freespecials unlocked. Any suggestions on how to better design this "move set" system?

EDIT:
After a whole afternoon of frustrating tests, I've come into conclusion that there's a bug on teh engine; trying to use changeentityproperty to change the energycost and/or disable on a move changes the MODEL property. I'll post the issue on GitHub, along with as much material as possible.

Paulo HP Bender

I can confirm that, I commented on it in a post some time ago. Some entity properties are "shared" between the same models, but curiously this "sharing" happens only when you get some values with script functions, the internal engine functions works correctly and will treat every entity separately.

Also happens with players too. For example, if you want to get the property "animhits" from player 1, it will also detect it for player 2 too if both are using the same character. I'm working to detect, isolate and discover a solution for that.
 
Back
Top Bottom