Fallout 2 mod Help with hooking ondeath so some critters drop meat

banjo_oz

First time out of the vault
I've been trying to make a mod that checks a critter's PID when it dies (I may change it to art type for simplicity though) and if it is of a certain type, adds some jerky to its corpse's inventory.

I'm really stuck trying to write the script, though. I presumed a global script that hooks into ondeath would be the best way, since it would avoid having to edit every critter's scripts. However, my code doesn't seem to work as I kill a Giant Ant in the temple trial at the start... and it still has no inventory (as normal) after death.

Here is my script. If anyone can help and tell me what I've done wrong, I'd appreciate it. I am sure it's a stupid obvious mistake!

/*

Drop meat on critter death if an edible animal

*/

/* Include Files */
#define SCRIPT_REALNAME "gl_drop_meat"
#include "../headers/define.h"
#include "../headers/command.h"

/* Defines */
procedure start;
procedure check_meat_drop;

#define critter_ant (obj_pid(critter) == PID_GIANT_ANT)
#define critter_rat (obj_pid(critter) == PID_RAT or obj_pid(critter) == PID_MUTATED_RAT or obj_pid(critter) == PID_VORPAL_RAT)
#define critter_pigrat (obj_pid(critter) == PID_PIG_RAT or obj_pid(critter) == PID_TOUGH_PIG_RAT or obj_pid(critter) == PID_MUTATED_PIG_RAT)
#define critter_molerat (obj_pid(critter) == PID_MOLE_RAT or obj_pid(critter) == PID_GREATER_MOLE_RAT or obj_pid(critter) == PID_MUTATED_MOLE_RAT)

variable meat;

/* Script Procedures */
procedure start begin
if (game_loaded) then begin
register_hook_proc(HOOK_ONDEATH, check_meat_drop);
end
end

procedure check_meat_drop begin
variable critter := get_sfall_arg;

if (critter_ant) then begin
meat := create_object(PID_MEAT_JERKY,0,0);
add_mult_objs_to_inven(critter,meat,1);
end
else if (critter_rat) then begin
meat := create_object(PID_MEAT_JERKY,0,0);
add_mult_objs_to_inven(critter,meat,1);
end
else if (critter_pigrat) then begin
meat := create_object(PID_MEAT_JERKY,0,0);
add_mult_objs_to_inven(critter,meat,2);
end
else if (critter_molerat) then begin
meat := create_object(PID_MEAT_JERKY,0,0);
add_mult_objs_to_inven(critter,meat,4);
end
end

EDIT: previously the script was crashing the game on load until I noticed I had an error in my create_obj lines... fixed that, but now it seems to load fine. It just doesn't do anything!
 
Last edited:
Being able to loot critters is a proto flag that needs to be set. This either needs to be done in the .pro file directly, or you can overwrite it via Sfall. See the ettu gecko script as an example.

Also, yeah, you should probably check for art FID and not the protos if the stuff is supposed to drop for all of them.
 
Last edited:
Being able to loot critters is a proto flag that needs to be set. This either needs to be done in the .pro file directly, or you can overwrite it via Sfall. See the ettu gecko script as an example.

Also, yeah, you should probably check for art FID and not the protos if the stuff is supposed to drop for all of them.

Makes sense! I was actually thinking during my last test that "maybe the hand/loot option is coded for each critter" without even thinking about checking geckos! Thanks!

I'd rather do it from the same script than edit a bunch of protos, so after examining the ettu gecko script, I added:
#include "../sfall/define_extra.h"

...and added:

set_proto_data(obj_pid(critter), PROTO_CR_FLAGS, get_proto_data(obj_pid(critter), PROTO_CR_FLAGS) bwand bwnot(CFLG_NOSTEAL));

... for each correct critter type and it worked, at least for giant ants! Thanks!

However, I changed it to use art FIDs instead of PIDs and it no longer works. :(
 
Last edited:
What exactly happens? You don't get the hand icon to open the loot interface?

By the way, you only have to run the code once at the end of your stuff. No need to duplicated that into every single else-if (same for the create_object if it will always be meat jerky).
 
What exactly happens? You don't get the hand icon to open the loot interface?

By the way, you only have to run the code once at the end of your stuff. No need to duplicated that into every single else-if (same for the create_object if it will always be meat jerky).
When using art FID I get no hand icon to open the loot interface. When I use PIDs, it works fine.

This is my alternate FID code:

#define critter_ant (obj_art_fid(critter) == FID_MAANTT)
#define critter_rat (obj_art_fid(critter) == FID_MASRAT)
#define critter_pigrat (obj_art_fid(critter) == FID_MAMURT)
#define critter_molerat (obj_art_fid(critter) == FID_MAMRAT)

I wondered if it was because I was using the RPU mod as well, so I also tried on a fresh F2 vanilla install (with just F2, latest Sfall and HR patch, no other mods) but the hand doesn't appear on that version either using the same code.

Am I getting the FIDs wrong? Do they need offsets of some kind?
 
When using art FID I get no hand icon to open the loot interface. When I use PIDs, it works fine.

Then you are checking the wrong art FID. :p
Check if the ID defines in artfid.h are the same in these mods. They need to line up with the used critters.lst file.

You could print the critter FID via custom debug message:
Code:
display_msg("my fid is: " + self_fid);
I think self_fid is a custom macro for ettu. It's obj_art_fid(self_obj).

Then check if the number behind your defines is the same. If it's not, you have wrong artfid defines.
 
Then you are checking the wrong art FID. :p
Check if the ID defines in artfid.h are the same in these mods. They need to line up with the used critters.lst file.

You could print the critter FID via custom debug message:
Code:
display_msg("my fid is: " + self_fid);
I think self_fid is a custom macro for ettu. It's obj_art_fid(self_obj).

Then check if the number behind your defines is the same. If it's not, you have wrong artfid defines.
Thanks for the help!

I added "display_msg("My fid is: " + obj_art_fid(critter) + ".");" to my script so it runs when an ant is killed and drops meat.

Using that debug message with a giant ant in the first temple room displays "My fid is 19005537."

(note: using "display_msg("My fid is: " + obj_art_fid(self_obj) + ".");" says "My fid is 137527625." but I assume this is very incorrect, as my hook script needs the critter not "itself" and I had to use "obj_pid(critter)" elsewhere for the correct PID results)

From reading artfid.h included with the latest RPU, the giant ant should be fid #16777313. In the script editor, hovering over the FID in "(obj_art_fid(critter) == FID_MAANTT)" shows a popup confirming this. But the game itself says otherwise! So... why the difference? And how do I fix it?

You also mention the critters.lst. Presumably the one in critters\art? How would I it to find FIDs I need?

There is *no* listing for the giant ant (MAANTT) fid define in the vanilla (or patch 1.02d) artfid.h files, which confuses me more.
 
Of course self_obj doesn't work like that in the hook script. You have to exchange that with the correct target pointer.

If your header file doesn't line up with that, you are using the wrong script sources. I don't have latest RPU stuff here, so I can't check.
/Edit: Based on the latest RPU files, FID_MAANTT is 16777313.
/Edit2: I think the old script files from the mapper release don't have this stuff in. The RPU has added the missing entries.

PS: You could also read out the proto data for kill_type information and go based on that. E.g. critter_kill_type(WHO) and then checking for KILL_TYPE_giant_ant_kills etc.. See define.h file for this stuff. This way the hook script could be compatible even with mods that have a different proto or art fid list.
 
Last edited:
Of course self_obj doesn't work like that in the hook script. You have to exchange that with the correct target pointer.

Art FID is the line number in critters.lst + 16777207. If your header file doesn't line up with that, you are using the wrong script sources. What sources are you using and what mod are you doing this for?
So I was right using "display_msg("My fid is: " + obj_art_fid(critter) + ".");" to find the fid the game is using? I thought that was how to do after your help earlier, but glad for the confirmation.

I am running Sfall RPU v2.3.3.v18, with script sources from https://github.com/BGforgeNet/Fallout2_Restoration_Project. Sfall headers are from the sfall_modderspack_4.2.9.
 
Seems to be right then. No idea why the numbers don't match up. Art FIDs always start with 16... If your ant returns 19, something is wrong. Did you use the critter pointer or PID to get to that?
 
I used the critter pointer. I'm attaching my working mod and not-working script source so you can see.

In the broken script, only the ant uses FID, the rest use PIDs. When I change the ant to use PID, it works fine (see commented out code).

I first thought I was doing the whole pointer bit - "(critter)" - wrong until I got it working just fine with obj_pid(critter) and obj_name(critter) returning the right values. obj_art_fid(critter) gives the wrong (19...) values.

Works:
(obj_pid(critter) == PID_GIANT_ANT or obj_pid(critter) == PID_TOUGH_GIANT_ANT)

Doesn't work:
(obj_art_fid(critter) == FID_MAANTT)

I really appreciate the help, regardless.
 
Ok, checking the FID via HOOK_DESCRIPTIONOBJ will return the correct number. So it seems that the critter FID changes on death (dead body on the ground).

That means, you either have to check by PID, or you just use a different hook. I tested it with HOOK_DEATHANIM2, which runs before the critter is actually dead, and it worked fine.
 
Last edited:
Ok, checking the FID via HOOK_DESCRIPTIONOBJ will return the correct number. So it seems that the critter FID changes on death (dead body on the ground).

That means, you either have to check by PID, or you just use a different hook. I tested it with HOOK_DEATHANIM2, which runs before the critter is actually dead, and it worked fine.
Thanks SO much! I was going nuts trying to figure out why the FID was wrong. That makes sense. Will look at changing to HOOK_DEATHANIM2 probably before releasing the mod.

Again, thanks for your help and time. Really appreciate it.
 
Back
Top