Open i5sue5 opened 3 years ago
Does this happen by the program or are the attitudes reset by script? E.g. is a function like B_InitGuildAttitudes
responsible?
@szapp I remember you have supported me to fix that issue some time ago. You have created extra aivars to fix that issue - I will try to recover that code and paste it here.
Here is the code
/*
* Iterate over all NPCs and set their AI variables according to the attitudes
*/
func void FixAttitudes_Save() {
if (!Hlp_IsValidNpc(hero)) {
return;
};
var int list; list = MEM_World.voblist_npcs;
var zCListSort l;
while(list);
l = _^(list);
list = l.next;
if (l.data) {
var C_Npc slf; slf = _^(l.data);
if (Hlp_IsValidNpc(slf)) && (!Npc_IsPlayer(slf)) {
slf.aivar[AIV_PERMATT] = Npc_GetPermAttitude(slf, hero);
slf.aivar[AIV_TEMPATT] = Npc_GetAttitude(slf, hero);
};
};
end;
// From now on we can restore the attitudes from the AI variables
FixAttitudes_Saved = TRUE;
};
/*
* Iterate over all NPCs and set the attitudes according to their AI variables
*/
func void FixAttitudes_Restore() {
// Do not restore the attitudes if they have not been saved yet
if (!FixAttitudes_Saved) {
return;
};
var int list; list = MEM_World.voblist_npcs;
var zCListSort l;
while(list);
l = _^(list);
list = l.next;
if (l.data) {
var C_Npc slf; slf = _^(l.data);
if (Hlp_IsValidNpc(slf)) && (!Npc_IsPlayer(slf)) {
Npc_SetAttitude(slf, slf.aivar[AIV_PERMATT]);
Npc_SetTempAttitude(slf, slf.aivar[AIV_TEMPATT]);
};
};
end;
};
/*
* Initialization: Call this function from Init_Global
*/
func void FixAttitudes_Init() {
MEM_InitAll();
//Print("Działa fix attitude");
// Restore the attitudes when loading
FixAttitudes_Restore();
// Save the attitudes every frame
FF_ApplyOnce(FixAttitudes_Save);
}; */
@pawbuj1981 Thanks. unfortunately that approach won’t work here, because we cannot use AI variables. You cannot add new AI variables in a script patch. (I think I had also mentioned this before). Here, we want to fix the problem at its origin. The code I had written previously only fixes the symptoms.
@AmProsius are you aware of any mod that has fixed this issue? I haven’t looked at this yet and I wonder whether the bug originates in the scripts or engine.
I know that the Definitive Edition fixed this behavior, but I didn't get the scripts from Issues yet.
I know that the Definitive Edition fixed this behavior, but I didn't get the scripts from Issues yet.
I checked with DecDat, and in DE the attitudes are just reinstated individually for each NPC based on prior set variables.
For each NPC their attitudes are written and read from savegames. However, the individual attitudes of all NPC are overwritten in oCGame::InitNpcAttitudes
through Wld_ExchangeGuildAttitudes
called from B_InitGuildAttitudes
at every loading. Although the attitudes are actually stored in the savegame, they are reset to their defaults every time.
B_InitGuildAttitudes
and B_InitMonsterAttitudes
are essential when entering any world the first time to properly initialize the attitudes of all monsters and humans the first time. Afterwards, the attitudes would actually be maintained by themselves through saving and loading. Nevertheless, the guild attitudes (not the NPC attitudes!) would still have to be set - for any new NPC being spawned later.
The actual issue here is oCGame::InitNpcAttitudes
within Wld_ExchangeGuildAttitudes
: It overwrites the attitudes of all existing NPCs. This is only desired if the human guild attitude table was actually exchanged, i.e. before and after chapter 4, see GIL_ATTITUDES_FMTAKEN
. However, which guild table is loaded is not stored anywhere.
Meddling with the content of Wld_ExchangeGuildAttitudes
or when it is called is not a good idea, because if the human guild attitude table is exchanged in another world, the attitudes need to be updated when finally entering the correct world. Furthermore, a mod might have different circumstances in which the function is called.
The solution to the problem would be to somehow check if the human guild attitude table has in fact changed and only update the attitudes of all NPCs in that case. An easy way might be to compare all current guild attitudes to the entries of the new table. ~But that does not work, because the guild attitudes are initially empty when loading.~ UPDATE: The guild table is actually saved and loaded properly. The only time it is empty (human guilds excluded) is on first creation, i.e. new game.
I can't think of a way to do this yet.
On a related note. This does not explain the friendly/neutral (?) attitudes of skeletons (and other monsters?) when saving and loading, see #238. I don't know if/how exactly this is related.
Describe the bug There are several changes of NPC_Attitudes towards the hero throughout the game. After a reload, the individual NPC_Attitudes are overwritten by the general GIL_Attitudes.
Expected behavior NPCs should keep their individual attitudes.