Advanced Hacking FAQ

Jul 2, 2008 at 5:01 AM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
Alright, I mentionned this in another thread, so here it is. I'm creating this thread to answer questions about how to do some non-Sue's-Workshop-doable changes to Cave Story. Want to do something for your hack but don't know how to do it? Post it here and we'll see what we can do about it.

Couple of "rules" though...

1- Not sure which commands let you move Quote? Don't know how to create a vertical trigger? Can't find the entity for some enemy? Well, don't ask it here. This thread is for things that require the use of a hex-editor, and potentially some basic assembly know-how. Not the sort of stuff you can work out for yourself by messing around in Sue's Workshop. Figure that out on your own, it'll probably just take you five minutes of messing around. :o

2- If I had free time, I'd invest it in finishing my hack, not somebody else's for them. I say that I "would" because I don't actually have a whole lot of free time on my hands. So yeah - I'm not doing your work for you. Please don't ask me to write some assembly code for you or ask me a question for something you know you can't pull off. Saves us both some time. ;)

3- I will not teach you how to write assembly. That crap takes time. You won't learn in just a few hours, especially if you don't have (real) programming experience. To this I say, Google is your best asset. Besides, let's try to keep it more Cave Story and less general purpose.

So, don't ask me how to implant a "level up" system or multiple characters if you've never touched assembly before. :p

So... ask away.
 
Jul 2, 2008 at 9:04 AM
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Oct 15, 2007
Location: Nowhere
Posts: 1920
Age: 31
I would like to make it such that each time my Bubbler shoots, one exp is removed, please.

Is that possible?
 
Jul 2, 2008 at 1:34 PM
Bonds that separate us
Forum Administrator
"Life begins and ends with Nu."
Join Date: Aug 20, 2006
Location:
Posts: 2857
Age: 34
Pronouns: he/him
Hmm...
Well there is something I'd like to see fixed personally, and that is that Curly is only coded to shoot at Labyrinth enemies and the Core, which makes the use of another fighting character in a mod very limited. Depending on how it's coded, I'd like to know if it's possible to make her shoot at different enemies or possibly just all of them.
Thanx~
 
Jul 2, 2008 at 2:16 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
@jcys810:
What you want is the following when the player attempts to shoot.

- Get the current weapon (00499C68)'s ID (the structure is stored at 00499BC8, is indexed by 00499C68, and the ID is offset 0x00 bytes into that)
- Compare to bubbler
- If equal, decrement energy (again in the 00499BC8 structure; offset 0x0C bytes into the structure)
- Continue with the rest of the code

You'd put that in the ammo reduction code, right after the test for ammo passes, I believe. Didn't try it, but that should work. That code can be found at 0x00001FA0 in exe, I believe, and looks a little like this...

Code:
	|								|
	|	Remove Ammo						|
	|	08_Ammo				Ammo Amount.		|
	|								|
	401fa0::remove_ammo
	{
		//	If we have 0 max ammo, succeed and exit.
		//	This would generally mean the weapon doesn't use ammo, so it's pointless to continue.
401fa0		if(WeaponData[SelectedWeaponID].MaxAmmo	== 0)
		{
401fb4		eax = 1
401fb6		return
		}

		//	If we have 0 ammo, fail and exit.
		//	There's no removing ammo if the weapon is already empty.
401fbb		if(WeaponData[SelectedWeaponID].Ammo == 0)
		{
401fcd			eax = 0
401fcf			return
		}

		//	Subtract the ammo from the current weapon.
		//	Ammo cannot drop under 0.
401fd1		WeaponData[SelectedWeaponID].Ammo = WeaponData[SelectedWeaponID].Ammo - 08_Ammo
401ff2		if(WeaponData[SelectedWeaponID].Ammo < 0)
402004			WeaponData[SelectedWeaponID].Ammo = 0

		//	Exit.		
402016		eax = 1
40201c		return
	}


@DoubleThink:
I'm on my way to work right now so I don't have time to look into what causes her to do this, but I suspect it's hardcoded into her AI. I THINK it may just be possible to tweak the ID of the enemies she targets. If so, I'll post the offsets where this happens.

Adding extra enemies to the list of what she can target may be possible, but until I can get a decent look at her code I can't say for sure.

The biggest problem here is that Curly can't just shoot at every entity. Nothing sets an enemy NPC apart from, say, a bouncing "energy" triangle or a health capsule. Curly would need a list of what's an enemy and what isn't, which is why she doesn't just shoot at everything that moves as would seem far simpler to code in the first place - it just wouldn't work out. A list of targets is needed.
 
Jul 3, 2008 at 2:54 AM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
@jcys810:
I was in a bit of a hurry this morning and forgot to mention something. By editing the ammo code, you'll ensure you ALWAYS lose EXP when the ammo goes down - even if you haven't fire the gun. This may or may not be what you're looking for. If it is, [ebp+0x0C] is the parameter that contains the amount of ammo to subtract. You could subtract that from the player's currently equipped weapon's experience, or just subtract 1 from it everytime.

Quote's currently-equipped weapon is stored in RAM at 00499C68
This can be used to index into the weapon data array in RAM at 00499BC8 and looks like this...

00499bc8 (+0x00) WeaponData[0x00].ID
00499bcb (+0x04) WeaponData[0x00].ShotID
00499bcc (+0x08) WeaponData[0x00].Level
00499bd0 (+0x0C) WeaponData[0x00].Energy
00499bd4 (+0x10) WeaponData[0x00].MaxAmmo
00499bd8 (+0x14) WeaponData[0x00].Ammo

So you want to offset yourself by 0x0C bytes from the base weapon data offset to work with the energy/experience. (0x00499BC8 + 0x0C = 0x00499BD0. The currently-equipped weapon from 00499C68 is actually a pointer into this structure, so you'd do something like...

mov eax, [00499C68] ; get the weapon Quote is using
mov ecx, [eax + 00499BC8] ; get the appropriate weapon object
mov eax, [ecx + 0C] ; go fetch the weapon's energy
... ; do whatever you want to it here
mov [ecx + 0C], eax ; write it back

If you really want this to occure specifically when you just fire your weapon, and not specifically when the ammo goes down, you can have a look at the weapon-firing algorithm. I don't have the offset but I can track it down for you if you want it. This would ensure that an event reducing your ammo to 0 (for instance) wouldn't also reduce your weapon's experience to 0.

@DoubleThink:
I had a chance to poke through Curly's code earlier today (ID 180 I think?) While it's still unsorted assembly code in my dump, I can almost guarantee you that's not where her targets are handled. I think some other bit of code does that, because I couldn't find anything that looked like that at all in there.

In other words, I don't have your answer yet. But this mini-project has my interest, so hang in there. :rolleyes: It'd be great if I could just stumble on a simple lookup table that could be tweaked with a plain old hex editor.

(By the way, I'm aware that I may be a bit vague or that I may post things a bit more complex than what's expected. Feel free to probe me for more details or to ask for a simpler explanation; I'm not sure how comfortable you guys are with this sort of thing or if any of it is making any sense. ^^; )
 
Jul 3, 2008 at 9:17 AM
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Oct 15, 2007
Location: Nowhere
Posts: 1920
Age: 31
If you really want this to occure specifically when you just fire your weapon, and not specifically when the ammo goes down, you can have a look at the weapon-firing algorithm. I don't have the offset but I can track it down for you if you want it. This would ensure that an event reducing your ammo to 0 (for instance) wouldn't also reduce your weapon's experience to 0.
Yes, I would really want it. Please. Sorry for wasting your time on typing out so much text. D:

my Bubbler edit is supposed to be like, shoot once, minus one exp.
 
Jul 3, 2008 at 11:17 PM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: No homie
RuneLancer said:
If it is, [ebp+0x0C] is the parameter that contains the amount of ammo to subtract.

RuneLancer said:
This can be used to index into the weapon data array in RAM at 00499BC8 and looks like this...

00499bc8
(+0x00) WeaponData[0x00].ID
00499bcb (+0x04) WeaponData[0x00].ShotID
00499bcc (+0x08) WeaponData[0x00].Level
00499bd0 (+0x0C) WeaponData[0x00].Energy
00499bd4 (+0x10) WeaponData[0x00].MaxAmmo
00499bd8 (+0x14) WeaponData[0x00].Ammo

Basepointer points to the weapon data array? (00499BC8)

RuneLancer said:
mov eax, [00499C68] ; get the weapon Quote is using
mov ecx, [eax + 00499BC8] ; get the appropriate weapon object
mov eax, [ecx + 0C] ; go fetch the weapon's energy
... ; do whatever you want to it here
mov [ecx + 0C], eax ; write it back

Uh, I don't get this.
Why does it add the offset of the currently equiped weapon to the weapon arrays offset?

RuneLancer said:
(By the way, I'm aware that I may be a bit vague or that I may post things a bit more complex than what's expected. Feel free to probe me for more details or to ask for a simpler explanation; I'm not sure how comfortable you guys are with this sort of thing or if any of it is making any sense. ^^; )

Well I like it, because I get assembly a bit better now.
And I can understand the code itself, but sometimes not it's function.
I can learn best per example.
 
Jul 4, 2008 at 12:19 AM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
"If it is, [ebp+0x0C] is the parameter that contains the amount of ammo to subtract."

That's a typo. I meant +0x08. :rolleyes: It's pushed onto the stack when the function is called, so it's the first parameter (well, third actually; you PUSH ebp onto the stack, and before that there's the return address from where the subroutine was called, so +8 bytes into the stack.)

Uh, I don't get this.
Why does it add the offset of the currently equiped weapon to the weapon arrays offset?
The offset points into the weapon array, not at a specific weapon object. So you add its offset to the weapon array's offset to get the right element. (Ex, if the pointer is 0x0100 and the array starts at 0x4500, we'd get what's at 0x4600 (0x0100 bytes into the array.))
 
Jul 4, 2008 at 12:31 AM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: No homie
RuneLancer said:
The offset points into the weapon array, not at a specific weapon object. So you add its offset to the weapon array's offset to get the right element. (Ex, if the pointer is 0x0100 and the array starts at 0x4500, we'd get what's at 0x4600 (0x0100 bytes into the array.))

Oh... I feel kinda stupid now.
Means it doesn't add the offset number itself, it adds the content?
 
Jul 4, 2008 at 12:44 AM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
What you're describing is a pointer. :rolleyes:

In assembly, you have different ways of using values. Let's suppose we have the following in our registers...

Code:
eax = 0x00000000
ecx = 0x00499bc8
edx = 0x00000000
We run the following code...

Code:
mov eax, ecx ; copies the value contained in ecx into eax.
mov edx, 0xFF ; copies the value 0xFF into edx.
add ecx, 0x10 ; adds the value 0x10 to ecx.
The registers look like this now...

Code:
eax = 0x00499bc8
ecx = 0x00499bd8
edx = 0x000000FF
However, suppose we now do this...

Code:
mov eax, [ecx] ; note the brackets, they basically mean "whatever is in RAM at ... " ("whatever is in RAM at ecx" in this case)
eax now contains whatever's in RAM at 0x00499bd8 (the number that was stored in ecx) instead of containing the actual value "0x00499bd8" itself.

Code:
mov eax, [0049E6CC] ; this is the offset pointing to Quote's current health
And now eax contains Quote's current health (and not the number 0x0049E6CC, as would have been the case without the brackets.)

If that makes complete sense to you, congrats. Pointers are the biggest challenge people face when they learn low-level languages.
 
Jul 4, 2008 at 1:03 AM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: No homie
RuneLancer said:
If that makes complete sense to you, congrats. Pointers are the biggest challenge people face when they learn low-level languages.

Yes it makes, thank you.
 
Jul 4, 2008 at 6:13 AM
Senior Member
"Huzzah!"
Join Date: Jul 4, 2008
Location: South Australia
Posts: 217
Age: 29
jcys810 said:
Yes, I would really want it. Please. Sorry for wasting your time on typing out so much text. D:

my Bubbler edit is supposed to be like, shoot once, minus one exp.
\

it would be good if u could make your own wepons
 
Jul 4, 2008 at 3:03 PM
Luls
"Bleep, Bloop, Bleep, Bloop"
Join Date: Oct 6, 2007
Location: I dunnos
Posts: 1584
Well... I don't know a single thing about Assembly but I do know how to use the Hex Editor.

Is there a way to make a weapon that shoots bullets that damage the monster the bullet hits multiple times?

Also, is it possible to make this (if at all) using only a Hex Editor? (I highly doubt it but ._. )
 
Jul 4, 2008 at 10:54 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
Anything that requires changing the way the game engine works will require the use of assembly.

The weapon property table contains a parameter I've labelled "number of hits" in my notes - this is how many collisions the weapon can survive before it dissipates.

Code:
0x0048F048 Weapon Property Table (0x2C bytes per entry)

0x0048F0F8 is the shooting star, lv 1. This would be a good place to start testing things. The second byte is the "number of hits" (I'll let you figure out the rest; byte 9 is also the weapon's properties flag, which you may want to play with.)

After you create a weapon that can take multiple hits before vanishing, your next challenge is finding a way to make the hit register multiple times. This is where you'll probably hit a snag, as the only way I can think of doing this (unless there's an NPC flag somewhere I've overlooked) would be to tweak the enemy damage code so they don't slip into "temporary invulnerability" mode after your weapon hits them.

Barring that, you can at least have your weapon hit multiple targets (once each though...)
 
Jul 5, 2008 at 12:29 PM
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Oct 15, 2007
Location: Nowhere
Posts: 1920
Age: 31
I, like Metalogz, have not touched Assembly.

So I figure I can't do the "exp decrease with every shot" thing, huh.
 
Jul 5, 2008 at 1:50 PM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: No homie
Learn assembly it isn't that hard.
Atleast for hacking Weapons and NPC's.
I can teach it to you.
 
Jul 5, 2008 at 2:49 PM
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Oct 15, 2007
Location: Nowhere
Posts: 1920
Age: 31
Hm. I think I'll take you up on that some day. When I'm less busy.
 
Jul 6, 2008 at 8:17 AM
Luls
"Bleep, Bloop, Bleep, Bloop"
Join Date: Oct 6, 2007
Location: I dunnos
Posts: 1584
RuneLancer said:
Anything that requires changing the way the game engine works will require the use of assembly.

The weapon property table contains a parameter I've labelled "number of hits" in my notes - this is how many collisions the weapon can survive before it dissipates.

Code:
0x0048F048 Weapon Property Table (0x2C bytes per entry)

0x0048F0F8 is the shooting star, lv 1. This would be a good place to start testing things. The second byte is the "number of hits" (I'll let you figure out the rest; byte 9 is also the weapon's properties flag, which you may want to play with.)

After you create a weapon that can take multiple hits before vanishing, your next challenge is finding a way to make the hit register multiple times. This is where you'll probably hit a snag, as the only way I can think of doing this (unless there's an NPC flag somewhere I've overlooked) would be to tweak the enemy damage code so they don't slip into "temporary invulnerability" mode after your weapon hits them.

Barring that, you can at least have your weapon hit multiple targets (once each though...)

Oh well, that's enough though.

Thanks! ^^"
 
Aug 15, 2008 at 2:21 PM
graters gonna grate
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jul 2, 2008
Location: &
Posts: 1886
Age: 32
Pronouns: he/him
I'd like to make it so that enemies never leave behind missile ammo when they die, regardless of whether or not the player has a missile launcher
 
Back
Top