Curly AI ASM

Feb 28, 2015 at 10:25 PM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
Have all, or any, of Curly AI's (the follower) related ASM addresses been found? If so, where are they?
Also, has anyone figured out making her shoot non-Labyrinth enemies by changing the ASM?
I'm looking to make a mod where you fight alongside her for most of the game, so of course that would entail a wide range of enemies and the need to lower her attack and give her some health so it's not super easy to beat.

Thanks, any help or advice is appreciated.
 
Feb 28, 2015 at 10:28 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
Feb 28, 2015 at 11:30 PM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
F_Deity_Link said:
Also, has anyone figured out making her shoot non-Labyrinth enemies by changing the ASM?
This has been said before, but I'll say it again anyways:

How Curly detects which enemies to target is based on code that is in the AI of the enemies, not the AI of Curly herself. That is, every enemy that she can shoot at runs a small piece of code to tell her where they are. So to make her shoot at any non-Labyrinth enemy, you would have to edit the AI of the enemy you wanted her to be able to target, not her AI.
 
Mar 1, 2015 at 12:30 AM
World's #1 Laharl Kinnie
"All your forum are belong to us!"
Join Date: Sep 22, 2012
Location: Hell
Posts: 611
Pronouns: She/It
GIRakaCHEEZER said:
This has been said before, but I'll say it again anyways:

How Curly detects which enemies to target is based on code that is in the AI of the enemies, not the AI of Curly herself. That is, every enemy that she can shoot at runs a small piece of code to tell her where they are. So to make her shoot at any non-Labyrinth enemy, you would have to edit the AI of the enemy you wanted her to be able to target, not her AI.
I presume it may be a simple flag that can be edited on the fly. If so, it should be simple to use an npc.tbl editor to edit a certian flag to allow Curly's Ai to detect it... Heh, Imagine Curly going berserk because of a horizontal/vertical trigger.
 
Mar 1, 2015 at 12:37 AM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
QuoteHax said:
I presume it may be a simple flag that can be edited on the fly. If so, it should be simple to use an npc.tbl editor to edit a certian flag to allow Curly's Ai to detect it... Heh, Imagine Curly going berserk because of a horizontal/vertical trigger.
So I can probably just use the npc.tbl editor in CE after I find out what the flag is?
And what's the hor/ver trigger got to do with this? - I'm probably missing something big here :p

Thanks @noxid for the link and GIRakaCHEEZER for the info
 
Mar 1, 2015 at 12:51 AM
Senior Member
"This is the greatest handgun ever made! You have to ask yourself, do I feel lucky?"
Join Date: Oct 22, 2014
Location: Xyrinfe multiverse
Posts: 100
Age: 28
Pronouns: she/her
F_Deity_Link said:
So I can probably just use the npc.tbl editor in CE after I find out what the flag is?
It would require ASM hacking, unfortunately. The NPCs that Curly does attack has the "Show Damage" and "Shootable" flags, which most NPCs have anyway...
 
Mar 1, 2015 at 12:52 AM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
Kim Tyranto said:
It would require ASM hacking, unfortunately. The NPCs that Curly does attack has the "Show Damage" and "Shootable" flags, which most NPCs have anyway...
Oh, okay. Figures. :P
I was going to learn the ASM stuff anyways.
 
Mar 1, 2015 at 12:53 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
QuoteHax said:
I presume it may be a simple flag that can be edited on the fly. If so, it should be simple to use an npc.tbl editor to edit a certian flag to allow Curly's Ai to detect it... Heh, Imagine Curly going berserk because of a horizontal/vertical trigger.
it's not
 
Mar 1, 2015 at 12:58 AM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
QuoteHax said:
I presume it may be a simple flag that can be edited on the fly. If so, it should be simple to use an npc.tbl editor to edit a certian flag to allow Curly's Ai to detect it... Heh, Imagine Curly going berserk because of a horizontal/vertical trigger.
It would be a neat premade hack, though, if possible, in BL; like a checkbox for "Allow Curly AI to attack non-Labyrinth enemies, etc."
Oh well, ASM is good anyways. :P
 
Mar 1, 2015 at 1:55 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
QuoteHax said:
I presume it may be a simple flag that can be edited on the fly. If so, it should be simple to use an npc.tbl editor to edit a certian flag to allow Curly's Ai to detect it... Heh, Imagine Curly going berserk because of a horizontal/vertical trigger.
Did you even read what I said? "...every enemy that she can shoot at runs a small piece of code to tell her where they are." There is no flag to set on the entities, you literally have to rewrite the code for each so that they tell Curly where they are, since this function call is a part of their individual AI functions.

Also, the reason she doesn't attack every enemy is, as you mentioned, she would try to attack non-hostile entities, like H/V triggers and entity 0, and even hearts and exp triangles.
 
Mar 1, 2015 at 2:04 AM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
GIRakaCHEEZER said:
Did you even read what I said? "...every enemy that she can shoot at runs a small piece of code to tell her where they are." There is no flag to set on the entities, you literally have to rewrite the code for each so that they tell Curly where they are, since this function call is a part of their individual AI functions.

Also, the reason she doesn't attack every enemy is, as you mentioned, she would try to attack non-hostile entities, like H/V triggers and entity 0, and even hearts and exp triangles.
Ah, now I see. Any entity at all would make her shoot if it weren't for the location.
When you said where they are, did you mean x,y coordinates as well as if they're specific to the Labyrinth, or just one of those?
If specific to Labyrinth is one of them and if the 'specific to labyrinth return value', so to speak, is the same for all of them, could I edit non-Labyrinth enemies to return the same value and then she should shoot at any enemy entities?
 
Mar 1, 2015 at 2:27 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
F_Deity_Link said:
Ah, now I see. Any entity at all would make her shoot if it weren't for the location.
When you said where they are, did you mean x,y coordinates as well as if they're specific to the Labyrinth, or just one of those?
If specific to Labyrinth is one of them and if the 'specific to labyrinth return value', so to speak, is the same for all of them, could I edit non-Labyrinth enemies to return the same value and then she should shoot at any enemy entities?
Just their X Y location on the map, which is the same for every map.

To edit a non-targeted entity to be targeted, you would have to write in a call to the function that "tells curly where they are" into their AI function, which gets run every frame. This isn't necessarily a hard task to do, but the problem is that putting new code into existing functions means you'll need space to do so.

The other (and perhaps more elegant) way you could do it is write it in as part of the master entityAI loop that runs all entityAIs on the map, and then have it check for a flag there which would run the "tell curly where I am" function. This is probably how pixel should have originally coded it, for easier code reuse.
 
Mar 1, 2015 at 2:40 AM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
What do you mean by the x,y being the same for every map? - some maps are bigger and I would place entities in different spots...

I'll probably go with the first idea, as long as that function is 'global' and writing them in doesn't cause storage issues... -would it cause storage issues?

Or I might do the second if I can find that loop and put a sort of boolean flag in each entity for whether or not it's an enemy.
 
Mar 1, 2015 at 3:28 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
F_Deity_Link said:
What do you mean by the x,y being the same for every map? - some maps are bigger and I would place entities in different spots...
Every entity internally keeps track of their current X and Y position on the map, as it is used in moving the entities around screen, not just for spawning the entities. These values have the same offset/are stored in the same spots in local memory, regardless of which map you are on.

It's like how the player has X and Y coordinates, and how the same spots in memory are used to track the player's current position, even if you change maps.
 
Mar 1, 2015 at 4:14 AM
Amaya
Discord Group Moderator
"What're YOU lookin' at?"
Join Date: Jan 18, 2013
Location: Somewhere quiet with many birds
Posts: 1118
Age: 25
Pronouns: she/her
GIRakaCHEEZER said:
This is probably how pixel should have originally coded it, for easier code reuse.
In fairness, he wasn't exactly planning for the convenience of others...although, I'm guessing what you mean is that making it in the master thingy and setting that flag in the entity would save space overall/be less of a hassle to change?
 
Mar 1, 2015 at 6:06 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
Polaris said:
In fairness, he wasn't exactly planning for the convenience of others...although, I'm guessing what you mean is that making it in the master thingy and setting that flag in the entity would save space overall/be less of a hassle to change?
It's just sort of bad coding style to have that function call be in every individual entity he needed it in rather than as a flag, more or less. To give an extreme example of how this is a bad thing, imagine if each entity had tile-collision checks hardcoded into their AI, instead of being a generic entity function that's called based on whether or not a flag is set. There'd be a lot of repetitive, unnecessary code.
 
Mar 1, 2015 at 10:20 AM
Senior Member
"This is the greatest handgun ever made! You have to ask yourself, do I feel lucky?"
Join Date: Aug 2, 2014
Location: inactivity.
Posts: 115
duncathan said:
Maybe someone might do the .dll thing to make something like this work?
No need to throw the .DLL thing at it-the global entity loop solution would work.
Although N.I.C.E can do it, you just have to add in the function pointer for the "Tell Curly Where This Entity Is" function, and then simply set the NPC override to call the old function, then the "Tell Curly" function.
Something like this in NPCT: (where NPCNumber is what you want to override)

case NPCNumber:
cs_g_npcfuncs[npc->npcID](npc);//use Cave Story's behavior for that NPC
cs_TellCurlyNPCPosition(npc);//and call the "tell curly where we are" function
break;


Of course, you'd have to add a function to cavestory.h for cs_TellCurlyNPCPosition(adding a function pointer mostly involves copying one of the 2 I've already done, fixing the arguments, and setting the 0x412345 thing to the address.)
But I have no idea what that function's address(or parameter list) is, so you may need to call it differently.
 
Mar 1, 2015 at 11:48 PM
Senior Member
"Huzzah!"
Join Date: Aug 24, 2013
Location: 0xDEADBEEF
Posts: 211
Pronouns: she/her
GIRakaCHEEZER said:
Every entity internally keeps track of their current X and Y position on the map, as it is used in moving the entities around screen, not just for spawning the entities. These values have the same offset/are stored in the same spots in local memory, regardless of which map you are on.

It's like how the player has X and Y coordinates, and how the same spots in memory are used to track the player's current position, even if you change maps.
Oh, fail on my side. I thought you meant that the x,y coords themselves never change, not that you were talking about memory location.

gamemanj said:
No need to throw the .DLL thing at it-the global entity loop solution would work.
Although N.I.C.E can do it, you just have to add in the function pointer for the "Tell Curly Where This Entity Is" function, and then simply set the NPC override to call the old function, then the "Tell Curly" function.
Something like this in NPCT: (where NPCNumber is what you want to override)

case NPCNumber:
cs_g_npcfuncs[npc->npcID](npc);//use Cave Story's behavior for that NPC
cs_TellCurlyNPCPosition(npc);//and call the "tell curly where we are" function
break;


Of course, you'd have to add a function to cavestory.h for cs_TellCurlyNPCPosition(adding a function pointer mostly involves copying one of the 2 I've already done, fixing the arguments, and setting the 0x412345 thing to the address.)
But I have no idea what that function's address(or parameter list) is, so you may need to call it differently.
Thanks for your help, but I think I'll go with the ASM idea of putting in the premade function into the NPC controller and then just doing a flag.

EDIT:

GIRakaCHEEZER said:
Just their X Y location on the map, which is the same for every map.

To edit a non-targeted entity to be targeted, you would have to write in a call to the function that "tells curly where they are" into their AI function, which gets run every frame. This isn't necessarily a hard task to do, but the problem is that putting new code into existing functions means you'll need space to do so.

The other (and perhaps more elegant) way you could do it is write it in as part of the master entityAI loop that runs all entityAIs on the map, and then have it check for a flag there which would run the "tell curly where I am" function. This is probably how pixel should have originally coded it, for easier code reuse.
I could not find the "master entityAI loop" of which you speak. What address does it start at? And if I were to use this, I could just give each enemy an ASM flag to have the master loop check for?


Thanks.
 
Mar 4, 2015 at 3:59 PM
beep boop
Bobomb says: "I need a hug!"
Join Date: Aug 16, 2014
Location: no
Posts: 848
Age: 23
Pronouns: he/him
Check the hex resources. It should be there.
 
Back
Top