I believe I have successfully streamlined the ICT workaround and in the process removed the need for a 'stupid passback' line
to quote Kulyok "watch my hands closely"
Example will be in regards to using an ICT from Tutu Finch in BG:ToTSC
First we need to establish whether or not Finch can talk. Best thing to do is let Finch tell us this, so we add a few blocks to her override script file
IF
StateCheck("sufinch",CD_STATE_NOTVALID)
InParty("sufinch")
Global("abFinchCanTalk","GLOBAL",1)
THEN
RESPONSE #100
SetGlobal("abFinchCanTalk","GLOBAL",0)
Continue()
END
IF
!InParty("sufinch")
Global("abFinchCanTalk","GLOBAL",1)
THEN
RESPONSE #100
SetGlobal("abFinchCanTalk","GLOBAL",0)
Continue()
END
IF
InParty("sufinch")
Detect("sufinch")
!StateCheck("sufinch",CD_STATE_NOTVALID)
Global("abFinchCanTalk","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("abFinchCanTalk","GLOBAL",1)
Continue()
END
Since variables are value 0 if never set what this does is if Finch never joined the party the variable "abFinchCanTalk" will automatically be = 0 and so when Finch joins we change that value to = 1. So after she has joined, if she leaves the party it gets reset to 0 and if she becomes unable to talk it also gets set to 0.
If you think about it, whenever this value is 0 there is no need to check and see if she is actually present via Detect(), See() or Exists(). She only needs to be there for her interjection to work. She can be there outside of the party, or in an unable to talk state, her interjection will still not be triggered.
Enter the workhorse. This is a function which will insert one triple file workaround ICT at a time. You can launch the function & define the variables directly in the TP2 or use an external TPH, your call
DEFINE_ACTION_FUNCTION ~ab_BG_Interject~ BEGIN
ACTION_IF (FILE_EXISTS_IN_GAME ~%ab_dialog%.dlg~) THEN BEGIN
<<<<<<<< dump.d
BEGIN ab_dump
IF ~~ 0 SAY ~%ab_tempDialogText%~ IF ~~ THEN EXIT END
>>>>>>>>
<<<<<<<< replace.d
REPLACE ab_dump IF ~~ THEN 0 SAY ~%ab_tempDialogText%~ COPY_TRANS %ab_dialog% %ab_statenum% END END
ADD_TRANS_TRIGGER %ab_dialog% %ab_statenum% ~%ab_canTalkVarAt0%~
>>>>>>>>
<<<<<<<< interjections.d
EXTEND_BOTTOM %ab_dialog% %ab_statenum%
IF ~%ab_pos_trigger% %ab_interjectVarAt0%~ EXTERN %ab_npc_dialog% ab_newstate
END
CHAIN %ab_npc_dialog% ab_newstate
%ab_interject%
END
COPY_TRANS ab_dump 0
>>>>>>>>
COMPILE dump.d EVALUATE_BUFFER
COMPILE replace.d EVALUATE_BUFFER
COMPILE interjections.d EVALUATE_BUFFER
END
END
Here is an example of launching the function & defining the variable
INCLUDE ~finch/lib/ab_BG_Interject.tph~
//since weidu doesn't like multiple sets of ~ & " together need to assign certain global variables outside of the LAF definitions
OUTER_SPRINT ab_interjectVarAt1 ~Global("abFinchTalkedAlatos","GLOBAL",1)~
LAUNCH_ACTION_FUNCTION ~ab_BG_Interject~
INT_VAR
ab_statenum = 0 //---------------------------------------------------- state number of the state that is being interjected into
STR_VAR
ab_tempDialogText = Finch //------------------------------------------ use npc's name so don't make another strref for crap
ab_dialog = ALATOS //------------------------------------------------- file name of dialog to be interjected into
ab_interjectVarAt0 = ~Global("abFinchTalkedAlatos","GLOBAL",0)~ //---- global variable to indicate the interjection has not happened
ab_canTalkVarAt0 = ~Global("abFinchCanTalk","GLOBAL",0)~ //---------- npc cannot interject set via npc's script
ab_pos_trigger = ~InParty("sufinch")
Detect("sufinch")
!StateCheck("sufinch",CD_STATE_NOTVALID)~ //--------- positive checks by npc being spoken to to make sure that joined npc is present
ab_npc_dialog = SUFINCHJ //------------------------------------------- file name of dialog file used by joined npc
ab_interject = EVALUATE_BUFFER "@813 DO ~Set%ab_interjectVarAt1%~" //- list of text & actions that make up the chain part of the interjection
END
You only need to INCLUDE the definition once. It could be in the ALWAYS section of the TP2 or as I did it via an external tph
The resultant output of the state in question from the decompiled alatos.dlg after installation:
IF WEIGHT #0 ~NumTimesTalkedTo(0)
~ THEN BEGIN 0 // from:
SAY #2783 /* ~Welcome my little friends! Please relax, and keep your weapons at your sides. No need for hostility.~ */
IF ~ Global("abFinchCanTalk","GLOBAL",0)
~ THEN DO ~SetGlobal("TalkedToThief","GLOBAL",1)
SetGlobal("TalkedToAlatos","GLOBAL",1)
~ GOTO 1
IF ~ InParty("sufinch")
Detect("sufinch")
!StateCheck("sufinch",CD_STATE_NOTVALID)
Global("abFinchTalkedAlatos","GLOBAL",0)
~ THEN EXTERN ~SUFINCHJ~ 68
END
As you can see, If Finch said she couldn't talk OR she never joined the party then the original transition occurs. IF she is in the party she will do her bit. Note I could have used the can talk variable at value 1 along with the Detect() check. However, I wanted the talking NPC to check for themselves since due to needing to use Continue() on the blocks in Finch's override script there could be a possible delay in the proper variable being set. Therefore the NPC checks for themselves at the moment of need.
Feel free to nitpick it apart.
I even checked it out by adding in a fake interjection for a fake npc name Fred. Everything looked good in that, if both Fred & Finch had their talk variable at 0 the original state would fire. If Fred's state was at 0 and Finch was present and able to talk Finch would do hers. If Fred was present & able to talk he would do his. Only concern I see (and would be true even outside of the function) if both Fred & Finch are there. Only first one installed gets to say their banter....
Perhaps it is a good thing... idk.