sfall-team / sfall

sfall - Engine modifications for Fallout 2
https://sfall-team.github.io/sfall/
GNU General Public License v3.0
342 stars 40 forks source link

OBJ_DATA_WHO_HIT_ME value changes from 0 to -1 when map is entered again #514

Closed blackpaulillyria closed 6 months ago

blackpaulillyria commented 6 months ago

I've discovered an unusual issue that is preventing me from using critter_add_trait(self_obj,TRAIT_OBJECT,OBJECT_TEAM_NUM, TEAM_ID) after I've visited the map again. This gets logged in debug.log as Error: CombatData found with invalid who_hit_me!

After some further debugging, I've discovered that OBJ_DATA_WHO_HIT_ME is 0 when I enter a map for the first time. When I exit it, and return back the value changes to -1. This then causes a script error when I try to change the critter's Team ID.

How to replicate:

1) Add this code to a critter's map_enter_p_proc: display_msg("OBJ_DATA_WHO_HIT_ME: " + get_object_data(self_obj, OBJ_DATA_WHO_HIT_ME));

2) Enter the map and exit it without starting combat

3) Enter the same map again and confirm that the value changed

NovaRain commented 6 months ago

The whotHitMe/whoHitMeCid is set on exiting the map (saving map objects): https://github.com/alexbatalov/fallout2-re/blob/main/src/game/object.c#L706

Tons of critter in the game have their teams set in map_enter_p_proc: https://github.com/bgforgenet/Fallout2_Unofficial_Patch/blob/master/scripts_src/klamath/kcbob.ssl#L138 But I don't see the error even when I try to change his team like this:

display_msg(obj_name(critter) + " curr team: " + get_team(critter) + ", whoHitMe: " + get_object_data(critter, OBJ_DATA_WHO_HIT_ME));
display_msg("Try to change team to Modoc.");
set_team(critter, TEAM_MODOC);
display_msg(obj_name(critter) + " new team: " + get_team(critter) + ", whoHitMe: " + get_object_data(critter, OBJ_DATA_WHO_HIT_ME));

Print in debug.log:

OBJ_DATA_WHO_HIT_ME: -1 (I added the log line to his script as your post)
...
Whiskey Bob curr team: 43, whoHitMe: 0
Try to change team to Modoc.
Whiskey Bob new team: 28, whoHitMe: 0
blackpaulillyria commented 6 months ago

Hi, thanks for helping me debug this.

I don't even have any code triggering on map exit so I can safely rule that one out. Basically after I re-enter a map, every NPC has their whoHitMe set to -1. This isn't a problem for me until I try to change their team. There are still a couple of other tests I can do:

1) Try out this behavior on other maps 2) Updating to the latest sfall 3) Disabling global scripts

I do have a simple workaround by setting whoHitMe to 0 but I'd use that as a last resort. Will post an update with my findings

NovaRain commented 6 months ago

I do have a simple workaround by setting whoHitMe to 0 but I'd use that as a last resort. Will post an update with my findings

From the invoked combatai_switch_team engine function, when you see the error log, the critter's team number should be already changed and its whoHitMe is set to 0 (NULL). https://github.com/alexbatalov/fallout2-re/blob/main/src/game/combatai.c#L3022

blackpaulillyria commented 6 months ago

From the invoked combatai_switch_team engine function, when you see the error log, the critter's team number should be already changed and its whoHitMe is set to 0 (NULL). https://github.com/alexbatalov/fallout2-re/blob/main/src/game/combatai.c#L3022

Thanks for your help! I've used the workaround nonetheless just to stop spamming the debug.log, makes it easier to see any other issues :) Also, I've no idea if that return -1 will have a knock-off effect somewhere else in the code.

So far I've ruled out that different maps or removal of global scripts make a difference. I'll test the sfall update soon and see how that works out!

NovaRain commented 6 months ago

OK, I manage to trigger the log by adding another team setting (switching) like this:

// kcbob.ssl
procedure map_enter_p_proc begin
   Only_Once:=0;
   set_self_team(TEAM_KLAMATH);
   set_self_ai(AI_TOUGH_CITIZEN);

   set_self_team(TEAM_MODOC);
end

When the game loads a saved map (i.e. not entering for the first time), it runs a map_fix_critter_combat_data() which loops through all critters on the map to change whoHitMe to 0. It seems to me your critter script setup is trying to switch team every time on map enter, because if the team num is the same as critter's current team, critter_add_trait won't actually call combatai_switch_team thus you shouldn't see the log.

blackpaulillyria commented 6 months ago

Hi, thanks for figuring this out. Mystery solved! And sorry for the late reply, I never got the email notification about your earlier reply!