[PSX/PC] General editor - Hades Workshop (0.50b)

  • Thread starter Thread starter Tirlititi
  • Start date Start date
Status
Not open for further replies.
@Tirlitit: on the topic of Enemy AI editing: this may seem like a dumb question, but is there a way to make it so that Zorn and Thorn don't immediately lose their charged magic after every single attack? I'm looking for ways to make this battle at least a little bit harder, but simply boosting the power of their spells won't really be sufficient considering that it's so easy to prevent them from using them in the first place. I was thinking of maybe making it so that you'd need 2-3 attacks on a charged clown to cancel their spell instead of just one. But my efforts so far didn't really accomplish anything. Thanks in advance for any help.
 
It's is possible to do that without a lot of changes.

Zorn and Thorn both have a flag stating whether there spell is available or not. It's "VAR_GlobUInt8_28" of Zorn (or "zornpoweron" if you imported the LocalVariables.hws, which is recommended for AI modding), and it's "VAR_GlobUInt8_29" for Thorn (or "thornpoweron").

When their spell becomes available, that flag is set to 1, and when it's not available anymore, it's set back to 0. What you need to do is turn those variables into counters instead of flags: you set it to 3, for instance, and you decrease it at each attack, canceling the spell only if it reaches 0.
CounterEx becomes like this:
Code: [Select]
Code:
Function Zorn_CounterEx    if ( GetAttacker == SV_FunctionEnemy ) {        if ( GetAttackId == 7 ) {            set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1        }        return    }    if ( GetAttacker == thorn ) {        if ( ( GetAttackId == 13 ) || ( GetAttackId == 14 ) ) {            set zorn[PREVENT_ATTACK] =$ 1            set thorn[PREVENT_ATTACK] =$ 1            set SV_FunctionEnemy[ATB] =$ 0            set zornpoweron = 3                                         // HERE: setup the number of attacks required to cancel the spell        }        return    }    if ( #( SV_FunctionEnemy[HP] <$ hp ) ) {        set hp = FirstOf(SV_FunctionEnemy[HP])        if ( ( GetAttackCommandId == 18 ) || ( ( GetAttackCommandId == 27 ) && ( GetAttackId == 122 ) ) ) {            return        }    } else {        set hp = FirstOf(SV_FunctionEnemy[HP])        return    }    if ( zornpoweron ) {        set zornpoweron--                                         // HERE: decrease the counter instead of directly set it to 0        if ( zornpoweron==0 ) {            BattleDialog( 24 )        }    }    set SV_FunctionEnemy[STAND_ANIMATION] =$ 0    set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1    return
And in the counter:
Code: [Select]
Code:
    case +2:        if ( zornpoweron ) {            set zornpoweron--            if ( zornpoweron==0 ) {                BattleDialog( 24 )                set SV_FunctionEnemy[STAND_ANIMATION] =$ 0                set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1            }        } else {            set SV_FunctionEnemy[STAND_ANIMATION] =$ 0            set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1        }        return    case +3:        if ( zornpoweron ) {            set zornpoweron--            if ( zornpoweron==0 ) {                BattleDialog( 24 )                set SV_FunctionEnemy[STAND_ANIMATION] =$ 0                set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1            }        } else {            set SV_FunctionEnemy[STAND_ANIMATION] =$ 0            set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1        }        if ( ( !zornpoweron ) && ( !thornpoweron ) ) {            set #( SV_Target = thorn )            Attack( 6 )            set waitingpowerthorn = 1        }
And you do the same for Thorn. They have a symmetric script.
 
Yay, I've just tried it out and it works like a charm! Thanks a ton! Now it's finally possible to make the Zorn and Thorn battle more challenging. After a bit of testing I can say that when you need 3 hits on a clown it's still possible to knock them out of the charged state, but you need to be real quick, and they will get off their attacks quite frequently now.
 
hey Tirlititi whats max value of a variable in a script like ur HP life counter. how many "lives" can a boss have lol
 
It depends on the type of the variable actually.
Code: [Select]
Code:
UInt8 -> contains a value between 0 and 255UInt16 -> contains a value between 0 and 65535UInt24 -> contains a value between 0 and 16777215Int8 -> contains a value between -128 and 127Int16 -> contains a value between -32768 and 32767Int24 -> contains a value between -8388608 and 8388607Bool -> contains 0 or 1
The more the max value is, the more the variable takes of memory in the RAM. The following infos are important when you declare variables or use new variables in the script:
 - A variable of type "Int8" or "UInt8" takes only 1 byte of RAM, meaning that you can use both VAR_LocUInt8_0 and VAR_LocUInt8_1 without problem, for instance.
 - A variable of type "Int16" or "UInt16" takes 2 bytes of RAM, so if you use one, you can't use a variable that directly follows its numbering and is of the same type: you can use both VAR_LocUInt16_0 and VAR_LocSometype_2, but not VAR_LocUInt16_0 and VAR_LocSometype_1.
 - A variable of type "24" takes 3 bytes of RAM, so you need to let a gap of 2 in the numbering of variables that you use.
 - A variable of type "Bool" is special: it takes only 1 bit = 1/8 byte and has a special numbering. The number specifies the bit position in the RAM, not the byte position like the ones above. So VAR_LocBool_8 corresponds to the first bit of the second byte, meaning that you can't use both VAR_LocBool_8 and VAR_LocInt8_1 at the same time. More generally, you can't use AR_LocBool_N and VAR_LocSometype_[N/8] at the same time without conflict.
 
Tirlititi, another question regarding enemy AI, mainly about certain symbols used: what exactly is the difference between:

"if ( GetRandom % 2 ) {"     and     "if ( GetRandom & 2 ) {"

I've always assumed they're pretty much the same ( a 1 in 2 chance), or how does the difference between the "%" and the "&" affect propability? Like for example in the Tantarian ATB function, it contains a switch that goes like this:

            switch 2 ( GetRandom % 4 ) from 0 {
            case +0:
                set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
                Attack( Edge )
                break
            case +1:
                set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
                Attack( Doom )
                break
            default:
                set #( SV_Target = SV_PlayerTeam )
                Attack( Paper Storm )
                break

Now the Random Number selected is a 1:4 chance, however the switch only has 2 possibilites (0 and 1), so half of the time the default attack is used instead of the switch (meaning that Tantarian has a 25% chance of using Edge, a 25% chance of using Doom, and a 50% chance of using Paperstorm, right?). Now If I were to increase the GetRandom to % 5 or % 10 or such, it would increase the chances for selecting Paperstorm and lower the chances for the other two attacks, correct? Just to make sure I'm reading things correctly.

And the other question: some enemies (Trance Kuja in this case) use HP-related conditions like this:

    if ( ( FirstOf(SV_FunctionEnemy[HP]) - 10000 ) < ( ( FirstOf(SV_FunctionEnemy[MAX_HP]) - 10000 ) >> 1 ) ) {

I'm unsure of how to read this, what's the meaning of the ">>1" at the end? All I can say from observation is that Trance-Kuja never counterattacks when his HP are near max, but does so quite frequently when his HP drop below a certain point (about half his max HP, roughly).
 
% is the modulus operator, it gives the remainer of the euclidean division. You nailed it right (all your assumptions about Tantarian's AI are correct).
& and >> are bitwise operators, in the sense that they have a meaning on the bits rather than numbers.
https://en.wikipedia.org/wiki/Bitwise_operations_in_C

What you need to remember most of the time, it's that "GetRandom % 2" and "GetRandom & 2" are indeed equivalent, but it's not the case anymore with larger numbers.
"(GetRandom % N)==0" is a 1/N chance to occur.
"GetRandom % N" is a (N-1)/N chance to occur.
"GetRandom & 1", "GetRandom & 2", "GetRandom & 4" are all 1/2 chances to occur.
"GetRandom & 3" is a 3/4 chance to occur (it's the independant probability of having either "GetRandom & 1" or "GetRandom & 2").

For >>, you can see it as divisions.
"A >> 1" is the same as A/2,
"A >> 2" is the same as A/4,
"A >> 3" is the same as A/8,
etc...
The result is always truncated (5 >> 1 = 5/2 = 2 for instance). There exists only integral numbers in FF9.

For Kuja's AI, it indeed connects the counter-attack only if Kuja's HP are below half of his Max HP without counting the extra 10 000 HP (so it's half of his in-game visible Max HP, not the number that appears in the datas).
 
Last edited:
Thanks for the quick reply, it starts to make more sense now. So "GetRandom & 3" is basically like "GetRandom & 1" and "GetRandom & 2" in succession, resulting in 75% chance total (two 50% chances).

And for example, "GetRandom & 7" would then be like "GetRandom & 1" plus "GetRandom & 2" plus "GetRandom & 4", resulting in 3 x 50% chances = 87,5% final chance, right?

I'm gonna read that wikipedia page thoroughly sometime, I guess it'll be really helpful to non-programmers like me.
 
Thanks for the quick reply, it starts to make more sense now. So "GetRandom & 3" is basically like "GetRandom & 1" and "GetRandom & 2" in succession, resulting in 75% chance total (two 50% chances).

And for example, "GetRandom & 7" would then be like "GetRandom & 1" plus "GetRandom & 2" plus "GetRandom & 4", resulting in 3 x 50% chances = 87,5% final chance, right?

I'm gonna read that wikipedia page thoroughly sometime, I guess it'll be really helpful to non-programmers like me.
You look like you pretty much understand how things work here.
Unfortunately people just think everyone is supposed to know this stuff.
thanks for reminding me how much i suck at math.
 
If he replies I highly doubt you'll understand anything so why asking?
Are you that eager to get slammed with mathematics?
 
I'm not playing with you no more. don't f*ucking talk to me anymore.

*talkin' about "ain't attackin my illness". get yo lyin' ass outta here!
 
Stop that now.

I had no reason to post anything, as there was nothing new concerning the tool and no new question (unless I'm blind).
Covarr had to act once already, that's not so you pick up the fight 5 minutes after. So dclem, stop being rude against people giving of their free time for the others, you included. And Fraggoso, there is no need for you to come to inflame the conversation.

If you have a problem with me, do it by PM. And if I don't answer in the following 24h, don't take it as an insult.

EDIT: Here we go... Thank you Covarr.
 
Last edited:
My no drama warning wasn't just for the other thread. Both of you get a vacation. In the mean time, I suggest you reread the rules, particularly the "Don't be a d*ck" rule. ~Covarr
 
hey Tirlititi i saw a video of someone showing off ultima doing multiple rounds of 9999s im wandering how can i do this LOL
 
did it bug in the video?
my guess would be to edit it's spell sequencing, adding numerous effect points. (damage/figure)
boom.

then again, it is a special move, with 0 power so...


Does anyone know how to work enemy AI's? no manual, no nothing. i really just want to get this over with.
 
Last edited:
also im really stuck on this bug. ozma works perfectly fine on disc 4 but same battle and scripts on disc 3 cause ozma not to appear in battle at all....
 
did you change the script at all? alternating the script got's to have something to do with it.
I know there's two Ozma enemies. (One for friendly battle completed and one not???)
 
@resinate: About Ultima doing multiple rounds of 9999, it is as dclem said. The guy added damage points and figure points in Ultima's spell sequencing. He also turned it into a magical attack (hence why it deals damage while it is normally not a damage-dealing spell).
However, his video works only because the damage are enough to end the battle. Usually, spell animations state when they are over, so the battle resumes after them and it can go to the next awaiting attack. That's not the case with Ultima and it's like it never ends. However, since the enemies are all dead after it in this case, there's no need to go to the next attack and the battle ends on a victory.
I don't know any way to use Ultima's spell animations properly in battle. According to my tests, it's not something that can be fixed with the current version of HW (we need to go deeper to the spell animation's structure).

About Ozma, that's strange... Can you show me the script that launches the battle? You're not talking about the non-modded way to fight Ozma, right? Cause it is perfectly possible to fight it on disc 3 in the normal game and without bug.

@dclem: The best way to learn for now is to import the "LocalVariables.hws" and try to understand some parts of the default scripts.
There are also descriptions of how the battle variables/functions work in the "Function List" panel. Here are some of the most useful ones:
Code: [Select]
Code:
Function -> Attack and AttackSpecialFunction -> RunBattleCodeFunction -> BattleDialogVariable -> SV_EnemyTeam, SV_PlayerTeam, SV_FunctionEnemy and SV_TargetVariable -> GetAttacker, GetTarget, IsAttacking, GetAttackId, GetAttackElement, etc...Variable -> GetBattleStateVar Code -> RandomInTeamVar Code -> [DATA_ACCESS]
 
Status
Not open for further replies.
Back
Top