Jump to content


Photo
- - - - -

Advanced Hacking FAQ


Old topic!
Guest, the last post in this thread is over 60 days old. Posting in this thread will be considered a bump, so please make an attempt to be courteous if you go ahead with it.

If the last post is over 6 months old, it may instead be a better idea to start a new topic. If you aren't sure about what to do, feel free to ask a staff member for help, or try to locate a 'general questions'-type thread if it exists in this (sub-)forum.


  • Please log in to reply
48 replies to this topic

#1 02 July 2008 - 04:01 AM

RuneLancer Offline
The Bartender
"All your forum are belong to us!"
Join Date: 18 Jun 2006
Location: LocationMontreal, Canada
Posts: 581
Age: 30
 

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.

Posted Image


#2 02 July 2008 - 08:04 AM

jcys810 Offline
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 15 Oct 2007
Location: LocationNowhere
Posts: 1,921
Age: 20
 

I would like to make it such that each time my Bubbler shoots, one exp is removed, please.

Is that possible?

New MSN: decayedcorpse810@hotmail.com
Posted Image
Call me Impulse or Justin if you are lazy to remember my name


#3 02 July 2008 - 12:34 PM

DoubleThink Offline
Up for a talk?
"Life begins and ends with Nu."
Join Date: 20 Aug 2006
Location: LocationYour inbox
Posts: 2,406
Age: 24
 

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~

I'm an admin c:
 
Quickie Mod Guide Update List (Missing uploads now welcome)

 

Spoiler

 


#4 02 July 2008 - 01:16 PM

RuneLancer Offline
The Bartender
"All your forum are belong to us!"
Join Date: 18 Jun 2006
Location: LocationMontreal, Canada
Posts: 581
Age: 30
 

@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...

|								|
	|	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.

Posted Image


#5 03 July 2008 - 01:54 AM

RuneLancer Offline
The Bartender
"All your forum are belong to us!"
Join Date: 18 Jun 2006
Location: LocationMontreal, Canada
Posts: 581
Age: 30
 

@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. ^^; )

Posted Image


#6 03 July 2008 - 08:17 AM

jcys810 Offline
Justin-chan
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: 15 Oct 2007
Location: LocationNowhere
Posts: 1,921
Age: 20
 

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.

New MSN: decayedcorpse810@hotmail.com
Posted Image
Call me Impulse or Justin if you are lazy to remember my name


#7 03 July 2008 - 10:17 PM

Adolf K. Offline
Ex-Dictator
"Life begins and ends with Nu."
Join Date: 30 Dec 2005
Location: LocationGermany
Posts: 3,185
Age: 125
 

If it is, [ebp+0x0C] is the parameter that contains the amount of ammo to subtract.


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)

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?

(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.

1bsrA6vTkGCBUhn33TkTnyFaTd7x0.png


#8 03 July 2008 - 11:19 PM

RuneLancer Offline
The Bartender
"All your forum are belong to us!"
Join Date: 18 Jun 2006
Location: LocationMontreal, Canada
Posts: 581
Age: 30
 

"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.))

Posted Image


#9 03 July 2008 - 11:31 PM

Adolf K. Offline
Ex-Dictator
"Life begins and ends with Nu."
Join Date: 30 Dec 2005
Location: LocationGermany
Posts: 3,185
Age: 125
 

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?

1bsrA6vTkGCBUhn33TkTnyFaTd7x0.png


#10 03 July 2008 - 11:44 PM

RuneLancer Offline
The Bartender
"All your forum are belong to us!"
Join Date: 18 Jun 2006
Location: LocationMontreal, Canada
Posts: 581
Age: 30
 

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...

eax = 0x00000000
ecx = 0x00499bc8
edx = 0x00000000
We run the following 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...

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

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.

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.

Posted Image




Old topic!
Guest, the last post in this thread is over 60 days old. Posting in this thread will be considered a bump, so please make an attempt to be courteous if you go ahead with it.

If the last post is over 6 months old, it may instead be a better idea to start a new topic. If you aren't sure about what to do, feel free to ask a staff member for help, or try to locate a 'general questions'-type thread if it exists in this (sub-)forum.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users