Stop map travel; Remove messages on item use

fuzzi

It Wandered In From the Wastes
Hi I have two questions:

1: How to ged rid of "That does nothing" message where using one object to on another
2: Is any way how to stop players travel on map in certain moment using scripts?
 
Topic edited for clarity.

Also, in the future plase make separate threads on separate and distinct issues like these.
 
I don't think you can stop map travel. However, the "That does nothing" message should be in some .msg file and can probably be edited to say "You are a banana" or nothing. The game may still scroll a line in the message window.
 
Yeah, but that isn what I need actually. If you repair generator in vault 15 using some tool you also dont get "That does nothing" message and no .msg edit needed. It must exist some call to disable it in scripts.
 
I need some script which is executed while player is traveling on the world map.
 
The only script which is always active in the game is the dude obj's script. I doubt it is active in the worldmap mode, but you could give it a shot, nothing to loose...
 
As far as I know, and provided we're talking Fallout 2 here, the only event that forces you to the worldmap (bar the encounters) is the special sequence with Frank Horrigan, which always happens on the same date.

The forced encounter is hardcoded in the executable, and can't be replicated, AFAIK. However, it can be changed into something else.

You could try using that - just replace the said "forced encounter" with what you like.
 
Hello, i had a look into fallout 2 executable and i have located the forced encounter with frank horrigan.

It's pretty easy to remove it but you can also change its date and the map you land to. I think it wouldn't be too hard to add other encounters of this kind however, it would require to inject some code in the exe (wouldn't be too hard for someone who knows how to do it).

So, here are the informations for patching the forced encounter:

to remove it, you have to force a conditional jump at the virtual address 0x4C06D8:
the byte at the offset 0xB0AD8 must be replaced by the value 0xEB (the origina value is 0x75) - didn't check this but it should be fine

To change the date, the byte at the offset 0xB0AE8 is the number of days that have past from the beginning of the game before the encounter happens. note: it can't be more than 255 if you just patch.

To change the map, you have to change the map id at two locations: the offsets 0xB0B0E and 0xB0B17.

I hope it helps, i haven't seen yet any infos on this issue.
 
Well technically it can be done, it's not very hard for someone who knows what he's doing, however, at the place where the program checks for this there's no room for some code to do that so, the new check should be located somewhere else. Even if it's basic code injection, it's not as trivial as patching a byte.
Moreover, the GVARs used would have to be hardcoded into the exe, I'm don't think it's really better than patching a byte.
If the date of the encounter isn't after 255 days after the beginning of the game, i think it's better to just patch the byte concerned.

Try to explain what you want to do, everything is possible when it comes to hack the exe (but sometimes it's just too much work), however, I don't see any way to force an encounter using scripts.
 
Ok, so you need to do this via scripting.

What you have to know about the frank horrigan forced encounter is that it happens only when you have an encounter. It's the first encounter you will meet after a certain date.
So, if you want to have a forced encounter at a precise date, horrigan's forced encounter is not the good way to do it.

To configure the date via gvars, it might be done with only one gvar (game ticks) or three (day, month, year), if necessary, one more gvar might be use to configure the map loaded.

However, what we're talking about here is adding a "new functionality" into the game, it's something that will need "heavy" patching - not just a few bytes...

Some more details would help me to have a better idea of what needs to be done and how it could be done.
 
There was written some solution which wasn't exactly what we need. So we posted new thread to refresh theme and maybe get some fresh suggestions. And whoa, it happened. And if you read it properly you can even discover that asked question isn't the same. We dont need only forced encounter but dynamic system of players map travel control based on scripts.
 
fuzzi said:
Is any way how to stop players travel on map in certain moment using scripts?

I fail to observe how is that not a question on "forcing an encounter", because that's the only thing that stops you at the map, except from actually reaching your destination.

Have you even seen the thread mentioned and if so, what barred you from posting in it? Hello, I'm powerful, but I can't read your damn minds.

Now, could you please stop bickering and get back to the issue at hand, wise eye?
 
Well, i've got something done. You can get the patch here: http://www.megaupload.com/?d=F4H9LHAE

It's experimental stuff, but I managed to get some script executed while travelling on the map. Of course, there's limitations (I don't think you can use map functions for example) it would be nice if you could try it and tell what works, what doesn't and noticing if there's bugs.

You can't load a map from the script, however, I added a functionnality that allows to load a map via a gvar. When no maps needs to be loaded, this var value's must be -1, else it is the number of the map that needs to be loaded.
By default this gvar is the gvar number 695 (it's the one I used to test) but it can be changed: there's two locations that must be changed: the 4 bytes integers at the offsets 0xb0ac2 and 0xb0ad6.

What is executed while travelling on the worldmap is the procedure drop_p_proc from obj_dude (I don't think you can drop the dude so it should be pretty safe) so you have to implement it in obj_dude.ssl if you want to execute it on the worldmap.

The injected code replaces the forced encounter of frank horrigan so, no more frank horrigan with the patch (i had a hard time optimising my code be small enough to fit in... even if in the end, i had to do some redirection :( ).

Well, I hope someone will take the time to test this, even if no one finds this useful, I still had fun diving in fallout's code to do this and I learnt some stuff about the internals of the game.

If someone is interested, I can explain more or less what I did technically.
 
Hey great work on exe ravachol :). Its something i wanted to do some time ago but failed.

If someone is interested, I can explain more or less what I did technically.
Give it here man. ;)

BTW what disassembler you use? IDA?
 
Thank you, so, what have I done to get this working: I injected some code in the function that is called to get random encounters. I pasted this code over the code that checks for the frank horrigan encounter. The code I pasted do the following:

- get a script identifier for obj_dude
- executes the script
- get the gvar's value
- if it's -1, do what the prog usually does
- else do what's needed to load the map

The function that executes the script checks if you're on a map, so I also had to crack this.
In the encounter function, there's two jumps to the code I replaced, to return true, I had to redirect them.

Now, the code (not very easy to understand I know) that I injected:

Code:
; asmsyntax=fasm

format binary

use32

; functions called
exec_script_proc=0x4a4810
get_gvar=0x443c68
set_gvar=0x443c98
scr_set_dude_script=0x4a4f90

; locations used
bye=0x4c0bd4
;continue=0

; variable accessed
obj_dude_ptr=0x6610b8
mapposX=0x672e0c
mapposY=0x672e10

; constants
drop_proc=5
gvar_encounter=695

org 0x4C06AA

call scr_set_dude_script	; inits obj_dude's script

mov edx, drop_proc
mov eax, [obj_dude_ptr]
mov eax, [eax+0x78]	; gets obj_dude's script id
call exec_script_proc	; executes obj_dude's script function drop_p_proc

mov eax, gvar_encounter
call get_gvar

inc eax			; check if gvar_encounter is set
jz continue

mov ebx, eax
dec ebx

cdq
dec edx
mov ecx, edx

mov eax, gvar_encounter
call set_gvar		; set the gvar_encounter to -1

lea eax, [0x672e4c]
;mov dword [0x672e4c], ecx
mov dword [eax], ecx	; must be -1

;add ecx, 2
inc ecx
inc ecx
;mov dword [0x672e04], ecx
mov dword [eax-0x48], ecx	; must be 1

;cmp dword [0x672e64], ecx
cmp dword [eax+0x18], ecx	; does the player have the car?

jnz @f
;mov edx, 0x672e68
lea edx, [eax+0x1C]
call 0x4c59a4

@@:

mov eax, ebx
call 0x482b34		; loads the map

;xor eax, eax
inc eax
jmp 0x4c0624		; the end

continue:

lea ebx, [esp+0xac]	; if gvar_encounter not set, do what the prog is supposed to do
mov edx, [mapposY]
mov eax, [mapposX]
call 0x4c3f00
mov edi, [esp+0xac]
inc edi

jnz bye

; taille max 129 octets

What is at the address where I jump when I'm done is some code to return true, I didn't have enough room to fit a far jump at this place...

To be able to do that, I had to do some "quick and dirty" reverse engineering: finding what might be useful and how it seems to work without looking too deep into the code.

Now, here are the instructions for patching the exe:

0xb0aaa: the code I pasted (assembled with fasm)
0x94c26: EB
0xb0fa1: EB 24
0xb0f0f: B4 00 00 00
0xb0a24: 40 81 c4 c0 00 00 00 5d 5f 5e 5a 59 5b c3

Well, this was the first shot for having scripts on the map, I think I might be able to remove the gvar and use load_map instead, it would be a cleaner hack. I have some clues on how to do it, i'll try it when i'll have some time.

BTW what disassembler you use? IDA?

Yep, IDA, it's hard to imagine some reverse engineering without this wonderful disassembler ;)

If there's any questions, i'll try to answer them.
 
Back
Top