Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
#595896 24/11/16 02:10 PM
Joined: Sep 2015
A
addict
OP Offline
addict
A
Joined: Sep 2015
Worked on additions to my auto-save char script today and noticed a problem with Timers in Combat I already suspected to exist earlier (related to my 'StandStill' mod that sets reaction priorities in combat, using a timer), but I never tested.

Now, timers (always speaking of local timers in char scripts) work fine in peace but in combat they bug out. While 30 seconds in peace are exactly 30 seconds, they seem to pass faster (or get cut or the timer gets ended before its time) when characters start/end(?) turn in combat. As long as one player is in active turn time passes as usual. When he ends turn and other characters start/end turn something happens, but I didn't find a rule for the effect on time (my time based auto-saves, 30 seconds interval, documented the breaking time continuum, and I shuddered).

For testing purposes I scripted a permanent timer for each main player character that plays an effect on the character every 15 seconds. I started the timers at different times, so the characters played their effect asynchronously.
Out of combat this worked fine. But when combat started and characters began to start and end turns, the 15 seconds rule got skipped and they played their effects in shorter intervals (random seeming but probably somehow related to start/end turn points). And after a while they started to play their effect synchronously (without regarding the 15 seconds rule) and never stopped staying in line. - It seems as if the timers were suddenly ended (not stopped) at the same time (so the characters played their effects at the same time), but I didn't find a rule for when this is supposed to happen.
Then I tested with a permanent timer that plays an effect every 100 seconds. After a longer while of starting and ending turns the timer was ended before 100 seconds were over, but significantly earlier than a 300 seconds timer I used after that.

I've no idea who's to be consulted here: a programmer, a physicist, or a doctor.

At least I can say: I hope you are aware of that and it gets/is already fixed, at least for D:OS 2. I also remind of the DelayReaction problematic in combat that delays reaction for the whole combat and not for the given time, what causes some unreasonable behaviour of enemies in combat.


My mods for DOS 1 EE: FasterAnimations - QuietDay - Samaritan
Joined: Jun 2013
old hand
Offline
old hand
Joined: Jun 2013
For your auto save script, are you saving even during combat? I'd probably try and write the script so that it pauses the timer on combat start which is what I do with the Osiris timers I use in Dunamis.

Joined: Sep 2015
A
addict
OP Offline
addict
A
Joined: Sep 2015
Yeah, would be better to stop it in combat. Maybe I add an auto-save when fights end, so the pause is not too long.


My mods for DOS 1 EE: FasterAnimations - QuietDay - Samaritan
Joined: Sep 2015
A
addict
OP Offline
addict
A
Joined: Sep 2015
Updated the file. I offer the code here, though Osiris is the better option for certain purposes; the advantage of this char script is its compatibility with save games, other mods (or easy to patch in) and the option to name the save files (Osiris only seems to allow to use the actual auto-save function):

Code
INIT
EXTERN INT:%UsedSave = 0
EXTERN INT:%UsedCombatSave = 0

EVENTS

EVENT SaveTimer
VARS
	CHARACTER:_Player = Player1_dac1443f-a866-4ab3-b240-e705c0b20ec5
ON
	OnInit()
	OnCombatEnded()
ACTIONS
	IF "c1"
		IsEqual(__Me,_Player)		
	THEN
		StartTimer("AutoSaveTime",600,-1) //600 seconds (10 min.)
	ENDIF

EVENT SaveTheGame
VARS
	CHARACTER:_Player = Player1_dac1443f-a866-4ab3-b240-e705c0b20ec5
	INT:_int
ON
	OnTimer("AutoSaveTime")
	OnFunction("GameAutoSave")
ACTIONS
	IF "!c1&!c2&!c3"
		CharacterInCreation(__Me, _)
		GameIsSaving()
		GlobalGetEvent("ModAutoSaved")
	THEN
		IF "c1&c2"
			GetVar(_int,_Player,"UsedSave")
			IsEqual(_int,0)
		THEN
			SaveGame("ModAutoSave1") //name of save1
			SetVar(_Player,"UsedSave",INT:1)
		ELIF "c1"
			IsEqual(_int,1)
		THEN
			SaveGame("ModAutoSave2") //name of save2
			SetVar(_Player,"UsedSave",INT:2)
		ELIF "c1"
			IsEqual(_int,2)
		THEN
			SaveGame("ModAutoSave3") //name of save3
			SetVar(_Player,"UsedSave",INT:3)
		ELIF "c1"
			IsEqual(_int,3)
		THEN
			SaveGame("ModAutoSave4") //name of save4
			SetVar(_Player,"UsedSave",INT:0)
		ENDIF
		GlobalSetEvent("ModAutoSaved")
		StartTimer("RemoveSaveBlock",10,0)
	ENDIF
	
/*EVENT CombatEndSaveTimer
ON
	OnCombatEnded()
ACTIONS
	StartTimer("SaveCombatEnd",3,0)*/
	
EVENT CombatEndSave
ON
	OnTimer("SaveCombatEnd")
ACTIONS
	CallFunction("GameAutoSave")
	
EVENT ReEnableAutoSave
ON
	OnTimer("RemoveSaveBlock")
ACTIONS
	GlobalClearEvent("ModAutoSaved")
	GlobalClearEvent("ModCombatAutoSaved")
	
EVENT AutoSaveCombat
VARS
	CHARACTER:_Player = Player1_dac1443f-a866-4ab3-b240-e705c0b20ec5
	INT:_int
ON
	OnCombatStarted()
ACTIONS
	IF "c1"
		IsEqual(__Me,_Player)
	THEN
		StopTimer("AutoSaveTime")
	ENDIF
	/*IF "!c1"
		GlobalGetEvent("ModCombatAutoSaved")
	THEN
		IF "c1&c2"
			GetVar(_int,_Player,"UsedCombatSave")
			IsEqual(_int,0)
		THEN
			SaveGame("ModCombatStart1")			//name of combat save file 1
			SetVar(_Player,"UsedCombatSave",INT:1)
		ELSE
			SaveGame("ModCombatStart2")			//name of combat save file 2
			SetVar(_Player,"UsedCombatSave",INT:0)
		ENDIF
		GlobalSetEvent("ModCombatAutoSaved")
		StartTimer("RemoveSaveBlock",10,0)
	ENDIF*/

Saves on combat started and ended can easily be enabled.

Some notes on it:

Due to the timer problem in combat I stop the auto-save timer when combat starts, as Sniper suggested, and restart it when it ends. - Only Player1 triggers these timed auto-saves.

I've added 4 save slots and save the number of the next slot to use after each save. I use extern variables (only set and checked on Player1) to make sure that both players have information on which save file is next (this implies that loading a save will also reload the file order, in most cases it's not the oldest save file that gets used next time; there's no way to avoid that).
I need both Players for saving OnCombatStarted and OnCombatEnded, in case one of the players doesn't get involved in combat. To prevent both players from saving on these events I block saving on these events for 10 seconds after one character saved (the combat timer bug shouldn't be a problem here). Player1 and 2 don't enter combat at the exact same time, so there's always one character first to trigger the save.

Saving OnCombatEnded causes a little bug: the character's weapon remains unsheathed when loading the save and can't be unsheathed by pressing TAB (attacking a random target, item, ground or character) solves the issue. To avoid that I trigger the save 3 seconds after combat.


My mods for DOS 1 EE: FasterAnimations - QuietDay - Samaritan

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5