#Enemy skills in AI script? + Where are item drops set?

473 messages · Page 1 of 1 (latest)

rose valley
#

So I think I have the general gist of editing their stats, EXP & cash yield, etc. Few things I'd like cleared up before I start mucking about and making real edits, though.

  1. I remember reading in another post from some time ago that the actual skills an enemy will use are controlled by their AI script? Where can I find these scripts? And if that's the case, what does their skill list in unit.tbl do? Is it just for the analysis screen? If you set passives here, will they take effect?

  2. Where are item drops set? I can't seem to find any field related to that in the enemy list and have no idea where else that might be.

sly epoch
#

Enemy AI using scripts is actually something that you can choose to have on or not

#

in ELSAI.tbl if you set the AI ID to a number aside from 0 it uses scripts

#

those scripts being found in "battle\script\enemy"

#

if its 0 then it uses the default ai which does use the skills in unit.tbl

rose valley
#

Does it just select randomly in that case?

sly epoch
#

im unsure if its totally random or if it atleast trys to hit weaknesses

#

but its what 99% of standard enemies in p5 use

rose valley
#

Do passives still work for enemies?

sly epoch
#

should do, some bosses in the vanilla game have them from memory

buoyant marsh
#

The skills used by enemies are controlled by either AI Script or by "simple AI scripts" (because I don't know what to call them), located in second segment of ELSAI. These "simple ai scripts" are in u32 struct below AI ID, and refer to IDs in second segment.
That means that the enemy doesn't actually use any active skills specified in UNIT.TBL. Passives do work though

#

Regarding instructions in second segment of ELSAI, they aren't documented yet (afaik), though sometimes (not always) they have an obvious skill id you can edit.

sly epoch
#

damn i was way off on the default ai stuff

rose valley
#

Could I give an enemy that doesn't have one a full AI script?

buoyant marsh
#

I believe so

rose valley
#

Assuming I have the script on hand, do you know how I'd set a particular enemy to use it?

#

nvm I figured it out

rose valley
#

Alright, I created a custom AI script for Pyro Jack and managed to get it working in game so I'll call that question answered. That still leaves the question of item drops, though. Anybody got an answer for that?

buoyant marsh
#

Did you create a completely new custom script, that didn't exist before, in new file?

#

I wondered if that would work

rose valley
#

Yeah.

#

Right now I'm dissecting AI script 330 (Archangel miniboss) to see if I can figure out what more of these functions do, and for the most part I've maybe sort of got a rough idea of a lot of what's in here, but I'll admit I have no earthly idea what AI_CHK_MYHOJO() does. What is a HOJO?

buoyant marsh
#

No idea. It has plenty of weird functions like that

rose valley
#

Looking at it did allow me to refine that Pyro Jack script some more though, so that's neat I guess.

buoyant marsh
#

Passives do work though

rose valley
#

That's good to know.

#

I'll still update the table so it's accurate for scans I suppose.

#

I wonder if "X Master" and "Auto X" skills work for them. If boosts work idk why they wouldn't?

buoyant marsh
#

I asked that before and chat said yes, but didn't test yet

rose valley
#

Things to keep in mind for when I'm in a design doc. Right now I'm just trying to get a feel for how the system works and what kinds of resources I have to work with with regards to making enemies slightly more intelligent than a box of rocks.

#

idk when enemies have more powerful moves available and just use Attack instead that seems pretty dumb to me.

buoyant marsh
#

They conserve SP

#

Obviously

#

Persona AI 😄

sly epoch
#

i have notes somewhere on it i will try and find them

rose valley
#

Actually does anyone here remember the mechanics of that fight? Because I know he does something like Wait -> Charge -> Cleave most of the time but also does some other weird things like the occasional Vajra Blast?

sly epoch
#

basically if the ai does AI_CHK_MYHOJO(4) it returns 1 if it has accuracy/evasion up or 0 if it dosent and so on for the other ones

rose valley
#

So what is it checking for with a parameter of 0x0100? Because that’s what I’m looking at.

#
if ( AI_CHK_MYHOJO( 0x0100 ) == 0 )
        {
            AI_ACT_SKILL( 360 );
            AI_TAR_RND();
            AI_SET_GUARDORDER( 0 );
            return;
        }
sly epoch
#

pretty sure 0x0100 is just 256

#

as for what that actually checks for i can only assume its checking if it has any buffs?

#

or debuffs

#

doing a quick check now

#

nvm quick check on hold my game is crashing when loading the encounter

buoyant marsh
#

Archangel miniboss doesn't use an AI script though?

rose valley
#

Huh. That’s… odd. It should, right? That fight definitely isn’t using default behavior.

#

Maybe that script's a leftover from OG P5 then? Is that a possibility?

buoyant marsh
#

It is. And the behaviour is in this second segment I mentioned before. After quick look I believe I found where it uses cleave, though not much else

rose valley
#

Yeah that second segment is completely unintelligible to me. I had no idea what I was looking at.

buoyant marsh
#

This is Cleave. This is all I can tell you about his AI 😄

rose valley
#

Well on the upside now that I know custom scripts work I don’t have to touch that shit at all xD

buoyant marsh
#

You can study Reaper's AI. There's a lot, but it's not too complicated

sly epoch
#

i have a writeup somewhere about the basics too

rose valley
#

Huh. Will do.

#

Oh that’d be super helpful if you’re willing to share.

white spruceBOT
#

I've cleaned up and commented the investigation team boy's ai flowscript and turned it into a sort of beginners guide to ai scripting

Jump

[Go to message!](#other-modding message)

BTL_AI0745.txt
sly epoch
#

wrote a while back so i will recheck over it to see if i missed anything

rose valley
#

Oh yeah. Actually there’s something else I forgot to ask about earlier? Do enemies have armor values? I saw a value for their basic attack in the table entry but nothing about armor.

sly epoch
#

not that ive ever seen

#

as far as i know damage differences are just caused by level differences and stats

buoyant marsh
#

No but there's endurance

#

From the wiki

buoyant marsh
sly epoch
#

it has all the normally usable skills in it plus some other less useful stuff

white spruceBOT
#

also if you want to compile it put this in a folder called utils in the same place as it

Jump

[Go to message!](#other-modding message)

ENUMS.flow
sly epoch
#

same usage as past me

rose valley
#

So if you use something like AI_TAR_WEAK and nothing matches the criteria what happens?

#

Does it just fall back on random targeting or something?

sly epoch
#

i believe so

rose valley
#

I feel like I might have to check myself soon because this is quickly evolving from “I want enemies to use different skills and maybe not use Attack if they don’t have to” to “how can I make the enemies systematically murder you as efficiently as possible?”.

sly epoch
#

a difficulty mod that actually changed enemy ai to be super agressive would be pretty interesting

rose valley
#

That’s sort of what I’m aiming for? idk. I just think if all I do is buff stats that’d be kind of lame.

buoyant marsh
sly epoch
#

exciting stuff

rose valley
#

What I’m working on is basically a complete difficulty overhaul that touches on everything related to combat. Just finished updating every already available player persona in the game. Enemies was the next thing on my to-do list.

#

Only problem is as I keep learning how to do more things I keep expanding the scope.

#

lol

rose valley
#

Anyone happen to know the status IDs?

buoyant marsh
#

I imagine it's checked like a bit flag, just like stat buffs

#

As such, the id for 1 specific status should match status ids in SKILL.TBL

#

Might be wrong though

rose valley
#

MUKOU
KYUSYU
HANSYA

So what are these checking for?

buoyant marsh
#

Where did you see them? Maybe you can figure it out by context

rose valley
#

Looking at the reaper script like you suggested.

buoyant marsh
#

Screenshot it or post it, I mean 😄

sly epoch
#

one of them was status effects like frozen or burning but i dont remember which one

rose valley
sly epoch
#

skill 385 is fire break so i would guess its to do with resistance

rose valley
#

AI_TAR_MINE();

I assume this makes it target itself?

sly epoch
#

yea

#

for stuff like healing obvs

rose valley
#

AI_TAR_AI();

I would assume from the name this makes it target another AI but in this context it's using Megidolaon so that can't be right.

sly epoch
#

not encountered that one

#

there is also an AI_TAR_MYAI()

#

it might be for targeting party members who are not on direct commands but that seems super niche

rose valley
#
 else if ( var1 < ( 15 + 20 ) )

Is... there a point to statements like this? This is baffling to me. Why not just have it say

else if (var1 < 35)
sly epoch
#

i think its a compiler thing?

#

it shouldnt have any impact on the final result so i would just have it as 35

rose valley
#

So if the MY prefix indicates a function that checks itself, and EN checks the enemy, does FR check allies?

sly epoch
#

not personally tested but thats always been my assumption

rose valley
#

AI_TAR_HPMIN();
AI_TAR_MPMAX();

Do you know what these do?

sly epoch
#

not tested either but im pretty sure its targetting whoever had the most/least health or sp

rose valley
#
if ( AI_CHK_ENHANSYA( 2 ) == 1 )
            {
                AI_ACT_SKILL( 385 );
                AI_TAR_HANSYA( 2 );
                return;
            }
            else if ( AI_CHK_ENKYUSYU( 2 ) == 1 )
            {
                AI_ACT_SKILL( 385 );
                AI_TAR_KYUSYU( 2 );
                return;
            }
            else if ( AI_CHK_ENMUKOU( 2 ) == 1 )
            {
                AI_ACT_SKILL( 385 );
                AI_TAR_MUKOU( 2 );
                return;
            }

All three of these must have something to do with resists then since they all lead to using Fire Break?

buoyant marsh
#

In theory, yeah

sly epoch
#

i would assume one of them is checking the personas resistances and another is checking for fire wall

#

no clue what the third is though

buoyant marsh
#

Fire wall would be pointless though, fire break doesn't negate fire wall

rose valley
#

Is it maybe checking for different kinds of resists like Drain/Repel/etc?

buoyant marsh
#

would be 4, as it's resist/null/drain/repel? Though this might be it, you can test it

rose valley
#

AI_CHK_MYUSEATTR(int param1);

Hit another one where I can't figure out what it does.

Context:

if ( ( AI_CHK_ENWEAK( 2 ) == 1 ) && ( AI_CHK_MYUSEATTR( 3 ) == 0 ) )
            {
                AI_ACT_SKILL( 12 );
                AI_TAR_WEAK( 2 );
                return;
            }

So it's used in tandem with checking if anyone is weak to Fire before targeting them with Agidyne.

#

Well, at any rate, I'll test those three out a bit later and see if I can get idea of what they might be doing. Will post results afterward.

buoyant marsh
#

Would anyone happen to know what AI_SET_FRID_MAXSERIAL is? I assume it's amount of turns in a row but idk

rose valley
#

I was wondering about that as well.

#

I might as well at it to the list of things to test when I get around to that later.

#

I'm still wondering about MYUSEATTR. Breaking that down into something that somewhat resembles english I'd suppose it's My Use Attr? I have no idea what that might be referring to though.

buoyant marsh
#

Same

sly epoch
#

if your not already i reccomend using zmenu's script logger

#

i just have a basic ai script that checks a bunch of stuff then i look at the log to see the returns

rose valley
#

Where would I get that from/how would I install it? I remember I had a bunch of trouble getting any kind of mod menu to work before eventually finding a link to a r2 packaged version of the Amelius mod menu on here somewhere.

buoyant marsh
#

@sly epoch would you happen to know if you can pass arguments to custom functions?

sly epoch
#

indeed you can lemme pull up an example

#

this is an example of both in and out

#

will try and check but i think in variables are seperated by a comma

#

yep

buoyant marsh
#

Yeah

#

Thank you

sly epoch
#

no probs im always happy to answer questions especially on flowscript

buoyant marsh
#

Don't think TAR_WEAK works, or at least it doesn't always works, as enemies tend to target either the weak team member, or joker

rose valley
#

Huh.

#

Is there a function that returns the current flat SP value?

buoyant marsh
#

I don't think enemies use SP?

sly epoch
#

there is one for party members but not seen one for enemies before

rose valley
#

I've been bootlegging it with AI_CHK_MYMP() but that requires a lot more work and knowing what percent of their total SP they need for certain skills.

rose valley
#

If they run out their skills will just fizzle.

sly epoch
#

yea as far as i can see the only way would be to math it with the MYMP percent and what they max is

#

that would also require a for loop checking MYMP until it finds what its at

buoyant marsh
rose valley
#
void AI_MAIN()
{
    int var0;
    var0 = RND( 100 );
    
    if ( var0 < 25 )
    {
        if ( AI_CHK_MYMP( 21 ) == 0 )
        {
            AI_ACT_SKILL( 13 );
            AI_TAR_RND();
        }
        
        else if ( AI_CHK_MYMP( 9 ) == 0 )
        {
            AI_ACT_SKILL( 10 );
            AI_TAR_RND();
        }

        else
        {
            AI_ACT_ATTACK();
            AI_TAR_RND();
        }    
        return;
    }
    else 
    {
        if ( AI_CHK_MYMP( 9 ) == 0 )
        {
            AI_ACT_SKILL( 10 );
            AI_TAR_RND();
        }
        
        else
        {
        AI_ACT_ATTACK();    
        AI_TAR_RND();
        }
        return;
    }

}

I wrote this for Pyro Jack but there's gotta be a better way to do this, right?

sly epoch
#

im pretty sure its percent based

rose valley
#

Yeah. It checks to see if their MP is at or below that percent.

sly epoch
#

so AI_CHK_MP(21) is checking if its either above or below 21% though i forget which way round it is

rose valley
#

It's below.

sly epoch
#

dont see much wrong with that way of doing it

#

pretty sure its how vanilla game enemies do it

rose valley
#

It works I was just hoping for a way to do it that didn't require me to math out what percent of their max SP each skill costs.

#

vanilla enemies don't do it at all. They'll still try and use skills even with no SP they just won't fire.

#

Which is the reason I wrote this to begin with.

sly epoch
#

oh yea i just meant from looking through boss scripts thats about how it usually looks

rose valley
#

Ah.

#

Well then I guess it's the hard way then.

buoyant marsh
rose valley
#

Possibly?

buoyant marsh
#

Well yes. I didn't check

sly epoch
#

ok i think i have the maths right?

#

`int SP = 200;
int SkillCost = 8;

AI_CHK_MYMP(SP/100*SkillCost);`

rose valley
#

By "enemy's affinity" what exactly are you referring to?

sly epoch
#

if you have SP as whatever the enemies max SP is then you just need to put in Skillcost as whatever amount of sp your skill needs is

#

and it should have the right percent to check

rose valley
#

Y'know I hadn't considered creating new variables to do the work for me.

#

Can you tell I haven't programmed in years?

sly epoch
#

doing maths like this is fun

#

though be warned

#

there is no way of rounding as far as i can tell

rose valley
#

It's an Int right? So it truncates.

#

I think.

sly epoch
#

yea

buoyant marsh
sly epoch
#

but there is no proper rounding up/down

rose valley
#

But it's already checking if the enemy is weak to fire so that can't be it, no?

buoyant marsh
#

Oh, when I say "enemy", I mean the enemy that AI script controls. So self basically

rose valley
#

Ah.

#

For some reason I was approaching this from a relative PoV.

buoyant marsh
#

So I just checked, attack master (and, I presume, other auto passives) doesn't work

rose valley
#

Unfortunate. I would've loved being able to troll people with that.

buoyant marsh
#

Can you define constants or only local variables in functions/use enums?

sly epoch
#

pretty sure constants have to be global

buoyant marsh
#

Yeah, I meant global constants

sly epoch
#

wait nevermind they dont actually have to be global

#

this compiles

rose valley
#

Do either of you know what bit flag 11550 is used for? This is the second time I'm seeing it used in an AI script.

sly epoch
#

no clue

buoyant marsh
#

Nope

rose valley
sly epoch
#

that would be a good thing to know

rose valley
#

PUTS( "1more" );

So what does this do? Is this just a text print?

sly epoch
#

yea put and puts are prints but they either do completely nothing on or have nowhere to actually see their output

buoyant marsh
#

Iirc there was a debug feature but it was cut

#

Before the release that is

rose valley
#

So do you know how AI_GET_LOCAL_PARAM and AI_SET_LOCAL_PARAM are used?

#

I'm seeing those a lot.

buoyant marsh
#

Well.. they set and get a local variable

#

That variable is saved between the turns

rose valley
#

I'm more referring to the arguments they take.

buoyant marsh
#

AI_GET_LOCAL_PARAM(int paramId)
AI_SET_LOCAL_PARAM(int paramId, int value)

sly epoch
#

basically just some memory for the ai

#

there is also AI_GET_GLOBAL and AI_SET_GLOBAL which work the same way but are shared among ai

rose valley
#

Oh, I think I see.

#

So the first argument identifies a local variable, and the second feeds it a value, basically?

sly epoch
#

yea

rose valley
#

Makes a lot more sense now.

sly epoch
#

(1, 2) would be set local variable 1 to the number 2

#

then using get on 1 would return the number 2

rose valley
#

Do they always start at 0?

sly epoch
#

pretty sure yea

#

they dont do anything unless you use them though so you can always set it to whatever you want on the first turn

rose valley
#

Trying to decipher Anubis's AI right now. I think out of all enemies, he's the one I want to fix the most. What they did to my boi in Royal is a travesty.

#

AI_ACT_WAIT3( 477 );

I'm assuming this is his special wait where he changes the scale balance?

sly epoch
#

most likely

#

never even noticed there was another wait function

rose valley
#

I figured he might have one since no other enemy has that specific mechanic.

buoyant marsh
#

Do you know what AI_GET_FIRST_ACTION is? It's checked for not being equal 2 in reaper's script.
Also, do any of you know what determines how many times enemy acts per turn?

rose valley
#

AI_SET_FRID_MAXSERIAL(enemy ID, number of turns)

#

Go nuts and create your ultimate enemy with 5 press turns.

sly epoch
#

gotta recreate smt3 mot

rose valley
#

Can you use any Persona model to create an enemy? Will that work?

sly epoch
#

animations might be in a different order but i can quickly check

buoyant marsh
#

Yeah, AI_SET_FRID_MAXSERIAL increases number of turns

#

But, only to one enemy

#

So, if you have several enemies of the same type.. it applies only to 1

rose valley
#

Because I 100% want to replace Siegfried with a Nocturne inspired Lucifer boss.

buoyant marsh
rose valley
#

Uh... no clue. Everything I know about this topic I learned in the last... how old is this thread? Ten hours or so.

sly epoch
#

they only have an idle and casting anims

#

you could got from enemy to persona but not the other way around without making the animations yourself

rose valley
#

AI_SET_FRID_MAXSERIAL(int param1, int param2);
AI_GET_FRID_MAXSERIAL(int param1);
AI_SET_ENID_MAXSERIAL(int param1, int param2);
AI_GET_ENID_MAXSERIAL(int param1);

buoyant marsh
#

But they all don't seem to fit

rose valley
#

So you could potentially use FR ID to set it rather then ENID?

buoyant marsh
#

It's either about friend or enemy

sly epoch
#

there is an ENID_CURRENTSERIAL aswell but how would you check the enemies current turn if its their turn not yours?

rose valley
#

Fuck me I'm tired and my brain isn't working.

buoyant marsh
sly epoch
#

the problem is when would you run it if its someone elses turn

rose valley
#

My guess is it was never intended to be used for enemies which would appear in groups so they never made a function for it.

buoyant marsh
#

That's probably it, yeah

#

Pretty sad

#

...and perhaps time to bother DC

rose valley
#

DC?

buoyant marsh
#

DeathChaos

rose valley
#

idk who that is I'm relatively new here.

rose valley
rose valley
#
 if ( AI_GET_ENID_CURRENTSERIAL( 22 ) == 0 )
        {
            
            if ( ( ( var1 == 1 ) || ( var1 == 5 ) ) || ( var1 == 9 ) )
            {
                var1 = ( var1 + 1 );
            }
            else if ( var1 == 11 )
            {
                var1 = 0;
            }

        }
sly epoch
#

that would make alot more sense

rose valley
#

My question is does it count up or down?

sly epoch
#

i would assume its what consecutive turn its on

#

0 being its normal turn and 1 being the first additional turn

rose valley
#

So it begins on turn 0, then 1, 2, etc?

sly epoch
#

but its worth testing making assumptions is risky with atlus' weird naming conventions

rose valley
#

I'm surprised so much of this is even in english.

buoyant marsh
#

Do any of you definitely know status ids for AI_CHK_ENBAD?
I know example script from Cornflakes had Status.Frozen "kept for posterity" but is there a working version? 😄

sly epoch
#

oh man i think i had it figured out kinda at one point but its totally gone

#

its most likely something to do with status effects but i must of been wrong somehow to remove it

rose valley
#

It's definitely checking for status effects I have no idea what else BAD could even be referring to unless the devs were just on something when they named these.

#

This is the order it appears in in the unit.tbl affinities list so we could assume its in this order until proven otherwise?

buoyant marsh
#

Like I theorised before it's probably bitflag checking but figuring it out going to be painful

rose valley
#

But wait

#

ignore me

#

I'm tired.

#

And I get sooooo stupid when I'm tired.

sly epoch
#

just went to an old version of the enums before i deleted the line for frozen

#

it was apparently AI_CHK_MYBAD( 2 )

buoyant marsh
#

I believe this line is correct, it does check for frozen from what I found

rose valley
#

AI_CHK_MYBAD(int param1);

Yeah it takes an Int as an argument.

buoyant marsh
#

Doesn't help much with figuring it out though 😄

sly epoch
#

huh wonder why i deleted it

#

i guess its just kinda ugly in the enums aside the other ones

rose valley
buoyant marsh
#

Hmm, AI_CHK_MYBAD(0x0800) checks for brainwash

sly epoch
#

2048

buoyant marsh
#

Soo if we imagine effect lists as flag enum, brainwash will be.. 4096, not 2048

#

ugh

#

..unless they committed cardinal sin and set 0 to some effect?

#

or more likely, the first bit in effect list 0 is just unused

rose valley
#

Well if 2 is frozen

#

then would it not be reasonable to expect that 1 is burn and 3 is shock?

buoyant marsh
#

Not really, I take it away, 2 is probably not frozen 😄

rose valley
#

rip

sly epoch
#

reason for deletion found

rose valley
#

And? Don't keep us in suspense.

sly epoch
#

oh i just mean it was probably deleted because its not frozen

rose valley
#

Oh.

#

lol

buoyant marsh
#

But you know, there's a lot of AI_CHK_ENBAD( 0x0200 ) I found.
And depending how you count, it can berserk, unknown or lust.. probably not any of them in other words, so idk

rose valley
#

Oh boy.

#

Seriously though this information has to be SOMEWHERE, right?

buoyant marsh
#

In the exe

rose valley
#

fun

buoyant marsh
#

I think I'll just test

rose valley
#

You said 0x800 was Brainwash?

buoyant marsh
#

I believe so

sly epoch
#

setup and ai that spam checks every number between 0 and 2049

#

should be able to make some progress with that

#

they are just burning

#

tried both shock and brainwash but because they lose their turn i get nothing

rose valley
#

Maybe try Dizzy?

#

They can still move with that.

sly epoch
#

so 1 is burning 8 is dizzy and 64 is forgetfulness

#

making progress i guess

rose valley
#

Could you maybe use FRBAD to check for the ones which restrict movement?

sly epoch
#

yea i guess i could just put 2 of them in the fight

#

it just takes the enemy id right?

rose valley
#

Not sure. Went out to pick up lunch.

#

So can’t check.

sly epoch
#

i will give it a shot and find out

rose valley
#

CHK_FRBAD only seems to take a single argument.

#

Which would be the status ID.

#

No enemy ID required.

buoyant marsh
#

Sooo, I learned from my testing that, brainwash is 2048

#

And desperation is.. 4096!

#

That means it goes from the end of effect list 3, and onward

#

And that 2 is indeed freeze

rose valley
#

Although AI_CHK_FRIDBAD (x, y) also exists, which you can use to check a specific ally.

buoyant marsh
#

WHY ATLUS

sly epoch
#

thats the exact result i just got from brute forcing it

rose valley
#
Burn = 1
Freeze = 2
Dizzy = 8
Forget = 64
Brainwash = 2048
Desperation = 4096

So these are our current results, then?

buoyant marsh
#
enum Effect {
    Burn = 1,
    Freeze = 2,
    Shock = 4,
    Dizzy = 8,
    Confuse = 16,
    Fear = 32,
    Forget = 64,
    Hunger = 128,
    Sleep = 256,
    Rage = 512,
    Despair = 1024,
    Brainwash = 2048
}
#

Basically yeah

sly epoch
#

last line still needs a comma at the end and didnt you mention desperation being 4096

#

aside from that i believe mystery solved gang

rose valley
#

Hell yeah.

buoyant marsh
#

Also yeah, I didn't include desperation (not to confuse it with despair)

rose valley
#

Time to

#

make the first palace impossible.

#

lfg

sly epoch
#

pretty sure it needs one to compile but i might be wrong

#

huh maybe not

#

i guess it just allows for either

rose valley
#

Wait so does enums actually do something?

sly epoch
#

lets you write things like AI_ACT_SKILL( Skills.Bufu ); instead of AI_ACT_SKILLS ( 20 );

rose valley
#

Huh.

sly epoch
#

its just for convenience in writing and readability

rose valley
#

Is there a function/value that checks for ANY bad status, rather than a specific one?

sly epoch
#

there is most likely a number that will always return 1 no matter what status they have but i dont know what it would be off the top of my head

buoyant marsh
#

1 | 2 | 4 | ...

sly epoch
#

that also works

#

base p5 final boss script has loads of checks for AI_CHK_FRIDBAD( 240, 0x00080000 )

#

but i checked 524288 and it didnt become 1 from burning so its not anything

#

chance its a decompiling error too ive seen something similar before

rose valley
#
void AI_MAIN()
{
    int var0;
    int SP;
    var0 = RND( 100 );
    if ( var0 < 20 )
    {
        if ( AI_CHK_MYMP( 21 ) == 0 )
        {
            AI_ACT_SKILL( 13 );
            AI_TAR_RND();
        }
        
        else if ( AI_CHK_MYMP( 9 ) == 0 )
        {
            AI_ACT_SKILL( 10 );
            AI_TAR_RND();
        }

        else
        {
            AI_ACT_ATTACK();
            AI_TAR_RND();
        }    
        return;
    }
    
    else if (var0 < 40)
    {
        if (AI_CHK_ENBAD(8) == 0)
        {
            if ( AI_CHK_MYMP(SP/100*3) == 0)
            {
                AI_ACT_SKILL( 80 );
                AI_TAR_NOTBAD(8);
            }
        }    
        
        else if (AI_CHK_MYMP(SP/100*4) == 0)
        {
            AI_ACT_SKILL( 10 );
            AI_TAR_RND();
        }
        
        else
        {
            AI_ACT_ATTACK();
            AI_TAR_RND();
        }
    }
    else 
    {
        if ( AI_CHK_MYMP( 9 ) == 0 )
        {
            AI_ACT_SKILL( 10 );
            AI_TAR_RND();
        }
        
        else
        {
        AI_ACT_ATTACK();    
        AI_TAR_RND();
        }
        return;
    }

}

Updated that earlier Pyro Jack script. Now if the random number is between 20 and 39 he should check to see if someone on your side is Dizzy and then use Dazzler if not, other wise use Agi or Attack if not enough SP. Does it look right to you guys?

sly epoch
#

as far as i can see you arnt setting SP to anything do its just doing 0/100

rose valley
#

Yeah I noticed that and fixed it after I posted this.

#

forgot to add a return too.

sly epoch
#

for AI_CHK_MYMP(SP/100*4) the 4 is the exact amount of sp needed

#

so this would be checking if they have less than 4

#

not sure if that was the intent though

rose valley
#

Dazzler only needs 3.

sly epoch
#

huh

#

i think that was the only other thing then

rose valley
#

I wonder... The condition in it's current state checks to see if anyone on the player side is not Dizzy. How would I write the condition so that it becomes true if at least one person is not Dizzy.

sly epoch
#

just change the 0 to a 1

rose valley
#

Wouldn't that just make it so that it is ONLY true if nobody is Dizzy?

sly epoch
#

oh right

#

I guess you would have to use AI_CHK_ENIDBAD

#

wait no i was right i think

#

AI_CHK_ENBAD(8) will return 1 if it sees anyone is dizzy i believe

#

AI_CHK_NOTENBAD(8) would return 1 if it sees anyone who is not dizzy

rose valley
#

But it will never return 1 because nobody will ever be dizzy because the condition to cast the dizzy spell is someone already being dizzy.

buoyant marsh
rose valley
#
AI_CHK_NOTENBAD(8)

This is what I was looking for I think?

sly epoch
#

IF(AI_CHKNOTENBAD(8))
{
cast dazzler
}
else
{
do other stuff
}

#

that would cast dazzler if anyone on the party is not dizzy

#

and if not does other stuff

rose valley
sly epoch
#

though bear in mind if someone was immune to dizzy the ai would get stuck in a loop constantly trying to cast dazzler

rose valley
#

Well in that case, they'd cast Dazzler, it'd fail, and then next turn they might do something else.

#

They're only meant to try and cast Dazzler 20% of the time.

sly epoch
#

oh thats fine then

#

another note

#

im pretty sure in this case the ai will do nothing which crashes from memory

rose valley
#

in which case?

#

Oh I see what you mean now.

#

If the SP check fails.

#

It will do nothing.

#

Well I guess if it doesn't have enough for Dazzler it doesn't have enough for anything else either so it should just attack.

#

Maybe this is a little overboard for a level 2 enemy.

#

lol

sly epoch
#

if anything its practice

rose valley
#
AI_TAR_NOTHANSYA
AI_TAR_NOTKYUSYU
AI_TAR_NOTMUKOU
AI_TAR_NOTWEAK

I really need to find out what these do.

#

These must be resistance checks I think.

sly epoch
#

well atleast notweak is self explanatory

rose valley
#

The fact that it's only four is what makes it confusing.

#

Since there are five resistance types.

sly epoch
#

there is also HOUMA and versions of the other ones with _ST at the end

rose valley
#

HOUMA? I don't see that one.

#

Ah there it is.

#

That could be the missing fifth resistance then?

#

Can you think of an effective way to test these and find out what they do?

sly epoch
#

only way would be to brute force them

#

but that would be annoying

rose valley
#

By brute force, how do you mean?

sly epoch
#

having the enemy check all of them constantly and just try a bunch of stuff on the enemy until you notice a change

rose valley
#

That sounds aggravating and yet doable if you design the right lab environment.

#

I’ll take a crack at it tomorrow.

sly epoch
#

good luck

empty spoke
#

Enemy skills in AI script? + Where are item drops set?

rose valley
#

Alright, I ran the test.

#

I figured out what they mean.

#
void AI_MAIN()
{
    int var0;
    int SP;
    var0 = RND( 100 );
    SP = 48;
    
    if (AI_CHK_ENHANSYA(2) == 1)
    {
        AI_ACT_SKILL( 20 );
        AI_TAR_RND();
        return;
    }    
    
    else if (AI_CHK_ENKYUSYU(2) == 1)
    {
        AI_ACT_SKILL( 30 );
        AI_TAR_RND();
        return;
    }
    
    else if (AI_CHK_ENMUKOU(2) == 1)
    {
        AI_ACT_SKILL( 40 );
        AI_TAR_RND();
        return;
    }
    
    else
    {
        AI_ACT_ATTACK();
        AI_TAR_RND();
        return;
    }

}

Ran this test code.

#

Then swapped my Persona to one with an appropriate level of fire resist each turn and recorded results.

#

Neutral - Attack
Resist - Attack
Null - Zio
Drain - Garu
Repel - Bufu

#

So then:
HANSYA = Repel
KYUSYU - Drain
Null = Mukou

#

There is no CHK for HOUMA so it must be something entirely unrelated.

#

AI_CHK_ENRESIST
AI_CHK_ENMUKOU
AI_CHK_ENKYUSYU
AI_CHK_ENHANSYA
AI_CHK_WEAK

Are our affinity checks, then.

#

They each take a single integer argument which represents the element ID to check for.

surreal condor
rose valley
#

Y'know I've never done that fight but if that's a recarm check then you might be right.

surreal condor
#

I also see this check in some scripts:

else if ( AI_CHK_ENBAD( 16777215 ) == 1 )
{
    ai0236_technical();
    return;
}

this is in shido's script (BTL_AI236)

#

I don't know what it checks for though

rose valley
#

That

#

looks like something I wouldn't want to touch with a ten foot pole.

#

If it's calling a function like that and then returning it's probably some funky hardcoded shit.

#

Tbh with how heavily scripted the boss fights are I've been hesitant to try experimenting with their AI.

#

I'm almost positive I'd break something.

surreal condor
#

I'm experimenting with maxserials right now. I'm searching for a function that gets current enemy's ID

#

to no luck yet

rose valley
#

I did take a look at Kamoshida's briefly and sort of was able to follow it.

surreal condor
#

AI_GET_MY_ID() looked promising but returned gibberish

rose valley
#

Huh.

#

Why are you looking for that, btw?

#

Like what are you trying to do?

surreal condor
#

I want to set the number of turns for each enemy depending on their level, something like this

void check_lv() 
{
    int myid = AI_GET_MY_ID();
    if ( AI_CHK_MYLV_O( 60 ) == 1 ) 
    {        
        AI_SET_FRID_MAXSERIAL( myid , 3 );
        AI_FIRE_LV4();
        AI_FIRE_LV4();
        AI_FIRE_LV4();
        return;
    }
    else if ( AI_CHK_MYLV_O( 40 ) == 1 )
    {
        AI_SET_FRID_MAXSERIAL( myid, 2 );
        AI_FIRE_LV3();
        AI_FIRE_LV3();
        return;
    }
    else if ( AI_CHK_MYLV_O( 20 ) == 1 )
    {
        AI_SET_FRID_MAXSERIAL( myid, 1 );
        AI_FIRE_LV2();
        return;
    }
    else 
    {
        AI_SET_FRID_MAXSERIAL( myid, 1 );
        AI_FIRE_LV1();
        return;
    }
}
rose valley
#

Actually I suppose I could understand if you wanted to reuse the same script for multiple enemies, but otherwise you know what your ID is.

surreal condor
#

yeah I don't want to write a script for each enemy 😅

rose valley
#

That's what I'm doing.

#

lol

#

Admittedly haven't made much progress since my PC broke like three days after I first started writing them but I've got like half of Kamoshida's Palace done at least?

surreal condor
#

my real problem isn't making a script for each enemy though, I can live with it if I must

#

I don't know what the enemy's level will be in advance, since I'm working on a better randomizer mod

#

one that scales levels, randomizes affinities, passives, stats etc instead of just changing encounter tables

rose valley
#

Ah, I see the problem now.

surreal condor
#

I ran into a wall with scripts though, I had made a script that chose from a randomized move from every existing move, but alas it crashes the game very consistently and I don't get why

#

so I resorted to assigning random "classes" to random enemies

rose valley
#

You're going to run into another issue with this where if you get two of the same enemy in an encounter only one will have the increased serial.

surreal condor
#

oh

rose valley
#

As far as I know that's the big issue with increasing max serial.

surreal condor
#

this sounds like spaghetti coding from atlus

rose valley
#

Well Atlus probably never intended to have two of them same enemy with increased serial count in the same encounter.

#

Since this is usually only found on stuff like bosses/glowing shadows/minibosses.

surreal condor
#

glowing shadows coding is also a mystery, sometimes it has like 4 turns, other times just 1

rose valley
#

I just mean the stronger enemies with the red aura.

#

Disaster Shadows (the exploding ones) are, from what I understand, a hardcoded mess.

#

They're actually the exact same enemies as their normal variants, it's just that the game will sometimes turn specific enemy IDs into the exploding variety.

surreal condor
#

everything is hardcoded oooooooooooooooooooooooooooooooh
I am also trying to understand what defines if an enemy is "talkable to". If I try to negotiate to a miniboss it won't let me, but if I put that miniboss in a random encounter it becomes possible to do it

#

also with bosses

#

might be a flag in encount.tbl somewhere, I don't know which one yet

#

also what makes enemies crittable etc

rose valley
#

I was looking for that as well when my PC offed itself.

#

lmk if you find anything

#

It's almost certainly an encounter flag but idk which one.

surreal condor
#

will do

rose valley
#

Miniboss encounters generally have a ton of them set.

#

I'm also trying to figure out what turns off All Out Attacks during the Shadow Okumura boss fight.

surreal condor
rose valley
#

That

surreal condor
#

like maruki's early fights

rose valley
#

actually sounds like it might be the answer.

#

AAnd if it is