Alright Jastey
I've something that I'm happy with for BG plus I found a few other things that needed corrected etc. Here are the BG files. You may wish to use this as the base for the Tutu/BGT versions instead. Since BG2 variants can handle the ContainerEnable you don't need the talk initiation stuff for Prism on those versions but you do need some of the other corrections etc...
tph/tp2 code//ISSUES-OublekEmeraldBountyExploitTWEAK.tph
PRINT ~Processing ISSUES-OublekEmeraldBountyExploitTWEAK.tph~
SILENT
// ----------------------------------------------------------------------------
//BEGIN @7 //~Optional: Oublek & Prism - No Exploit & Multiple Ways to Solve Quest~
//first container
COPY_EXISTING ~ar5400.are~ override
LAUNCH_PATCH_FUNCTION ~fj_are_structure~
INT_VAR fj_loc_x = 641
fj_loc_y = 2713
fj_type = 6
fj_lock_diff = 30
// fj_flags to the bitwise container flags (bit0=locked, bit3=trap resets, bit5=disabled);
fj_flags = 0b00000001
// fj_flags = 0b00100001 //for tutu & bgt (i hope)
fj_trap_detect = 100
fj_trap_remove_diff = 100
fj_trap_active = 1 //to whether the container is trapped (0=no, 1=yes);
fj_trap_status = 0 // to whether the trap is detected (0=no, 1=yes);
fj_trap_loc_x = 641
fj_trap_loc_y = 2713
fj_box_left = 564
fj_box_top = 2552
fj_box_right = 590
fj_box_bottom = 2563
fj_vertex_0 = (564 + (2559 << 16))
fj_vertex_1 = (578 + (2552 << 16))
fj_vertex_2 = (590 + (2556 << 16))
fj_vertex_3 = (586 + (2561 << 16))
fj_vertex_4 = (580 + (2563 << 16))
fj_vertex_5 = (570 + (2562 << 16))
// fj_lockpick_strref to the lockpick string reference (default -1);
STR_VAR fj_structure_type = ~container~
fj_name = ~A6StatueRightEye~
fj_trap_script = ~abitrp~
// fj_trap_script to the trap’s script;
// fj_key_resref to the filename of the container’s key;
END
LAUNCH_PATCH_FUNCTION ~fj_are_structure~
INT_VAR fj_charge0 = 1
fj_con_itm_idx = SHORT_AT 0x74 - 1
STR_VAR fj_name = ~abgfEyeR~
fj_structure_type = ~itm~
END
BUT_ONLY
//second container
COPY_EXISTING ~ar5400.are~ override
LAUNCH_PATCH_FUNCTION ~fj_are_structure~
INT_VAR fj_loc_x = 641
fj_loc_y = 2713
fj_type = 6
fj_lock_diff = 70
// fj_flags to the bitwise container flags (bit0=locked, bit3=trap resets, bit5=disabled);
fj_flags = 0b00000001
// fj_flags = 0b00100001 //for tutu & bgt (i hope)
fj_trap_detect = 100
fj_trap_remove_diff = 100
fj_trap_active = 1 //to whether the container is trapped (0=no, 1=yes);
fj_trap_status = 0 // to whether the trap is detected (0=no, 1=yes);
fj_trap_loc_x = 641
fj_trap_loc_y = 2713
fj_box_left = 614
fj_box_top = 2541
fj_box_right = 638
fj_box_bottom = 2555
fj_vertex_0 = (638 + (2544 << 16))
fj_vertex_1 = (635 + (2550 << 16))
fj_vertex_2 = (627 + (2554 << 16))
fj_vertex_3 = (614 + (2555 << 16))
fj_vertex_4 = (626 + (2543 << 16))
fj_vertex_5 = (635 + (2541 << 16))
// fj_lockpick_strref to the lockpick string reference (default -1);
STR_VAR fj_structure_type = ~container~
fj_name = ~A6StatueLeftEye~
fj_trap_script = ~abitrp~
// fj_trap_script to the trap’s script;
// fj_key_resref to the filename of the container’s key;
END
LAUNCH_PATCH_FUNCTION ~fj_are_structure~
INT_VAR fj_charge0 = 1
fj_con_itm_idx = SHORT_AT 0x74 - 1
STR_VAR fj_name = ~abgfEyeL~
fj_structure_type = ~itm~
END
BUT_ONLY
//create left eye emerald
COPY_EXISTING ~misc43.itm~ ~override/abgfEyeL.itm~
SAY UNIDENTIFIED_DESC ~An emerald is a brilliant green beryl, cleaved along straight box like lines, with rectangular cutting in the finished gem. Emeralds are often connected with health, and so are used ornamentally for such a purpose. This emerald is marked with a small 'L'. It had been stolen by Prism for his use in a statue of his lady love, Ellesime. It is surmised that this gem was intended to be used as the left eye. Whether or not it was used in the statue, there is a bounty for returning it to the proper authorities.~
SAY IDENTIFIED_DESC ~An emerald is a brilliant green beryl, cleaved along straight box like lines, with rectangular cutting in the finished gem. Emeralds are often connected with health, and so are used ornamentally for such a purpose. This emerald is marked with a small 'L'. It had been stolen by Prism for his use in a statue of his lady love, Ellesime. It is surmised that this gem was intended to be used as the left eye. Whether or not it was used in the statue, there is a bounty for returning it to the proper authorities.~
BUT_ONLY_IF_IT_CHANGES
//create right eye emerald
COPY_EXISTING ~misc43.itm~ ~override/abgfEyeR.itm~
SAY UNIDENTIFIED_DESC ~An emerald is a brilliant green beryl, cleaved along straight box like lines, with rectangular cutting in the finished gem. Emeralds are often connected with health, and so are used ornamentally for such a purpose. This emerald is marked with a small 'R'. It had been stolen by Prism for his use in a statue of his lady love, Ellesime. It is surmised that this gem was intended to be used as the right eye. Whether or not it was used in the statue, there is a bounty for returning it to the proper authorities.~
SAY IDENTIFIED_DESC ~An emerald is a brilliant green beryl, cleaved along straight box like lines, with rectangular cutting in the finished gem. Emeralds are often connected with health, and so are used ornamentally for such a purpose. This emerald is marked with a small 'R'. It had been stolen by Prism for his use in a statue of his lady love, Ellesime. It is surmised that this gem was intended to be used as the right eye. Whether or not it was used in the statue, there is a bounty for returning it to the proper authorities.~
BUT_ONLY_IF_IT_CHANGES
//change the emeralds that prism carries
COPY_EXISTING ~prism.cre~ ~override~
REMOVE_CRE_ITEM ~misc43~
REPLACE_CRE_ITEM ~abgfEyeL~ #1 #0 #0 ~identified~ ~qitem1~
REPLACE_CRE_ITEM ~abgfEyeR~ #1 #0 #0 ~identified~ ~qitem2~
READ_ASCII 0x0248 ~overridescript~
PATCH_IF (FILE_EXISTS_IN_GAME ~%overridescript%~) BEGIN
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%overridescript%.bcs~ ~bgfixpack/files/oublek/abgfprsm.baf~ //add our stuff -- creates new if doesn't exist
END
END ELSE BEGIN
WRITE_EVALUATED_ASCII 0x0248 ~abgfprsm~
READ_ASCII 0x0248 ~overridescript~
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%overridescript%.bcs~ ~bgfixpack/files/oublek/abgfprsm.baf~ //add our stuff -- creates new if doesn't exist
END
END
BUT_ONLY_IF_IT_CHANGES
//compile the dialog changes to oublek and prism
COMPILE ~bgfixpack/files/oublek/oublek.d~ EVALUATE_BUFFER
COMPILE ~bgfixpack/files/oublek/abitrp.baf~ EVALUATE_BUFFER
//check existance of area script and add rep penalty for taking gems from statue
/*
COPY_EXISTING ~ar5400.are~ ~override~
READ_ASCII 0x94 ~script~
PATCH_IF (FILE_EXISTS_IN_GAME ~%script%~) BEGIN
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%script%.bcs~ ~bgfixpack/files/oublek/ar5400.baf~ //add our stuff -- creates new if doesn't exist
END
END ELSE BEGIN
WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
READ_ASCII 0x94 ~script~
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%script%.bcs~ ~bgfixpack/files/oublek/ar5400.baf~ //add our stuff -- creates new if doesn't exist
END
END
BUT_ONLY_IF_IT_CHANGES
*/
//check existance of area script and add global sets to complete quest
COPY_EXISTING ~ar4800.are~ ~override~
READ_ASCII 0x94 ~script~
PATCH_IF (FILE_EXISTS_IN_GAME ~%script%~) BEGIN
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%script%.bcs~ ~bgfixpack/files/oublek/ar4800.baf~ //add our stuff -- creates new if doesn't exist
END
END ELSE BEGIN
WRITE_EVALUATED_ASCII 0x94 ~%SOURCE_RES%~
READ_ASCII 0x94 ~script~
INNER_ACTION BEGIN
EXTEND_BOTTOM ~%script%.bcs~ ~bgfixpack/files/oublek/ar4800.baf~ //add our stuff -- creates new if doesn't exist
END
END
BUT_ONLY_IF_IT_CHANGES
Prism's initiation scriptIF
See([PC])
!Range(LastSeenBy,1)
Global("abgf_PrismTalk","LOCALS",1)
THEN
RESPONSE #100
ClearActions(Myself)
MoveToPoint([641.2713])
SetGlobal("abgf_PrismTalk","LOCALS",0)
END
IF
See([PC])
Range(LastSeenBy,1)
!StateCheck(LastSeenBy,STATE_INVISIBLE)
!StateCheck(LastSeenBy,STATE_IMPROVEDINVISIBILITY)
NumTimesTalkedTo(0)
THEN
RESPONSE #100
SetGlobal("abgf_PrismTalk","LOCALS",1)
Wait(3)
Dialogue([PC])
END
IF
Dead("Greywolf")
See([PC])
Range(LastSeenBy,1)
THEN
RESPONSE #100
SetGlobal("abgf_PrismTalk","LOCALS",1)
Dialogue([PC])
END
the dialog changes (some more things were adjusted/corrected in here)//OublekBounty1 is for brage
//OublekBounty2 is for prism
//the oublekbounty globals will prevent any exploits by dropping a second item and trying to get the full reward again
ADD_TRANS_TRIGGER ~oublek~ 9 ~Global("OublekBounty1","GLOBAL",0)~ DO 0 UNLESS ~Global("OublekBounty1","GLOBAL",0)~
ADD_TRANS_TRIGGER ~oublek~ 9 ~Global("OublekBounty2","GLOBAL",0)~ DO 1 UNLESS ~Global("OublekBounty2","GLOBAL",0)~
ADD_TRANS_TRIGGER ~oublek~ 9 ~Global("OublekBounty1","GLOBAL",0) Global("OublekBounty2","GLOBAL",0)~ DO 4 UNLESS ~Global("OublekBounty2","GLOBAL",0)~
ADD_TRANS_TRIGGER ~oublek~ 10 ~Global("OublekBounty1","GLOBAL",0)~ DO 1 5 UNLESS ~Global("OublekBounty1","GLOBAL",0)~
ADD_TRANS_TRIGGER ~oublek~ 10 ~Global("OublekBounty2","GLOBAL",0)~ DO 9 5 UNLESS ~Global("OublekBounty2","GLOBAL",0)~
//changing from one item to two ensures that players can not take advantage of dropping one item and trying to get the full reward twice
REPLACE_TRANS_TRIGGER oublek BEGIN 9 END BEGIN 1 END ~PartyHasItem("MISC43")~ ~PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR")~
REPLACE_TRANS_TRIGGER oublek BEGIN 9 END BEGIN 4 END ~!PartyHasItem("MISC43")~ ~!PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR")~
REPLACE_TRANS_TRIGGER oublek BEGIN 10 END BEGIN 9 END ~PartyHasItem("MISC43")~ ~PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR")~
REPLACE_TRANS_TRIGGER oublek BEGIN 10 END BEGIN 5 END ~!PartyHasItem("MISC43")~ ~!PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR")~
REPLACE_TRANS_ACTION oublek BEGIN 14 END BEGIN 0 END ~TakePartyItem("MISC43")~ ~TakePartyItem("abgfEyeL") TakePartyItem("abgfEyeR")~
REPLACE_TRANS_ACTION oublek BEGIN 4 END BEGIN 0 END ~TakePartyItem("MISC43")~ ~~
REPLACE_TRANS_ACTION oublek BEGIN 4 END BEGIN 0 END ~GivePartyGold(300)~ ~GivePartyGold(300) TakePartyItem("abgfEyeL") TakePartyItem("abgfEyeR")~
//adding new states that give half the reward when only one item gets turned in
APPEND oublek
IF ~~ THEN BEGIN abLeftEye
SAY ~One of the Emeralds! That will be a 150 gold bounty for you. Be sure to bring the other if you should find it.~//this is custom text
IF ~~ THEN DO ~AddexperienceParty(100) GivePartyGold(150) TakePartyItem("abgfEyeL") SetGlobal("abgf_LeftEyeBounty","GLOBAL",1)~ EXIT
END
IF ~~ THEN BEGIN abRightEye
SAY ~One of the Emeralds! That will be a 150 gold bounty for you. Be sure to bring the other if you should find it.~//this is custom text
IF ~~ THEN DO ~AddexperienceParty(100) GivePartyGold(150) TakePartyItem("abgfEyeR") SetGlobal("abgf_RightEyeBounty","GLOBAL",1)~ EXIT
END
IF ~~ THEN BEGIN abLeftEyeLast
SAY ~The last of the Emeralds! That will be another 150 gold bounty for you. Well, you'll make quite a name for yourself among the bounty hunters if you keep this up. Whether it is for better or worse, I do not know.~//this is custom text
IF ~~ THEN DO ~AddexperienceParty(100) GivePartyGold(150) TakePartyItem("abgfEyeL") SetGlobal("abgf_LeftEyeBounty","GLOBAL",1)~ EXIT
END
IF ~~ THEN BEGIN abRightEyeLast
SAY ~The last of the Emeralds! That will be another 150 gold bounty for you. Well, you'll make quite a name for yourself among the bounty hunters if you keep this up. Whether it is for better or worse, I do not know.~//this is custom text
IF ~~ THEN DO ~AddexperienceParty(100) GivePartyGold(150) TakePartyItem("abgfEyeR") SetGlobal("abgf_RightEyeBounty","GLOBAL",1) ~ EXIT
END
END //end the append
//adding additional transitions that allow the player to turn in only one of the two required items for good boy
EXTEND_BOTTOM oublek 9
IF ~PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR") Global("abgf_LeftEyeBounty","GLOBAL",0) Global("abgf_RightEyeBounty","GLOBAL",0)~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO abLeftEye
IF ~!PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR") Global("abgf_LeftEyeBounty","GLOBAL",0) Global("abgf_RightEyeBounty","GLOBAL",0)~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO abRightEye
IF ~PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR") Global("abgf_RightEyeBounty","GLOBAL",1)~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO abLeftEyeLast
IF ~!PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR") Global("abgf_LeftEyeBounty","GLOBAL",1)~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO abRightEyeLast
END //end the extend bottom
//adding additional transitions that continue to keep 'bad boy' player from getting full reward. If they turn in only one gem, they get rewarded but can't turn in the other or resolve brage issue with oublek. It is an overall punishment when compared to 'good boy' rewards.
EXTEND_BOTTOM oublek 10
IF ~Global("OublekBounty2","GLOBAL",0) PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR")~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO 14
IF ~Global("OublekBounty2","GLOBAL",0) !PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR")~
THEN REPLY ~I've come to turn in a bounty, and collect the reward that is duly mine.~ GOTO 14
END //end the extend bottom
//adjustments needed for prism to work with the rest of the component
ADD_STATE_TRIGGER prism 0 ~HasItem("abgfEyeL",Myself) HasItem("abgfEyeR",Myself)~
//REPLACE_TRANS_ACTION ~prism~ BEGIN 7 END BEGIN 0 END ~ReputationInc(1)~ ~~
REPLACE_TRANS_ACTION prism BEGIN 7 END BEGIN 0 END ~DropInventory()~
~DestroyItem("abgfEyeL") DestroyItem("abgfEyeR") SetGlobal("abgf_GemInEye","GLOBAL",1)~
REPLACE_TRANS_ACTION prism BEGIN 9 END BEGIN 0 END ~GiveItem("MISC43","GREYWOLF")~
~GiveItem("abgfEyeL","GREYWOLF") GiveItem("abgfEyeR","GREYWOLF") SetGlobal("abgf_GemInEye","GLOBAL",3)~
//anything not one means that either the gems were not in container when obtained OR the penalty was applied
//only way to get items if player allowed greywolf to attack prism is to attack greywolf before prism is dead and hopefully kill him before he runs away.
APPEND prism
IF ~NumTimesTalkedTo(0) !HasItem("abgfEyeL",Myself) !HasItem("abgfEyeR",Myself) PartyHasItem("abgfEyeL") PartyHasItem("abgfEyeR") Global("ab_GemStoleResolve","GLOBAL",0)~
THEN BEGIN abBothStole
SAY ~My Emeralds! You! You took them! I must have them back. I need them to finish this epiphany. Please, please return them. I will give you all else that is mine.~
IF ~~ THEN REPLY #4750 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO abRelent
IF ~~ THEN REPLY #4751 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO 3
END
IF ~~ THEN BEGIN abRelent
SAY #678
IF ~~ THEN DO ~TakePartyItem("abgfEyeL") TakePartyItem("abgfEyeR") CreateCreature("GREYWO",[1267.2579],0) ClearAllActions() StartCutSceneMode() StartCutScene("Prismcut")~ EXIT
END
IF ~NumTimesTalkedTo(0) HasItem("abgfEyeL",Myself) !HasItem("abgfEyeR",Myself) PartyHasItem("abgfEyeR") Global("ab_GemStoleResolve","GLOBAL",0)~
THEN BEGIN abRightStole
SAY ~My Emerald! You! You took it! I must have it back. I need it to finish this epiphany. Please, please return it. I will give you all else that is mine.~
IF ~~ THEN REPLY #4750 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO abRelent
IF ~~ THEN REPLY #4751 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO 3
END
IF ~NumTimesTalkedTo(0) !HasItem("abgfEyeL",Myself) HasItem("abgfEyeR",Myself) PartyHasItem("abgfEyeL") Global("ab_GemStoleResolve","GLOBAL",0)~
THEN BEGIN abLeftStole
SAY ~My Emerald! You! You took it! I must have it back. I need it to finish this epiphany. Please, please return it. I will give you all else that is mine.~
IF ~~ THEN REPLY #4750 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO abRelent
IF ~~ THEN REPLY #4751 DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO 3
END
IF ~NumTimesTalkedTo(0) !HasItem("abgfEyeL",Myself) !HasItem("abgfEyeR",Myself) !PartyHasItem("abgfEyeL") !PartyHasItem("abgfEyeR") Global("ab_GemStoleResolve","GLOBAL",0)~
THEN BEGIN abBothStoleButGone
SAY ~My Emeralds! You! You took them! I must have them back. I need them to finish this epiphany. Please, please return them. I will give you all else that is mine.~
IF ~Global("OublekBounty2","GLOBAL",1)~ THEN REPLY ~They are gone. Given to the authorities. You will never finish that lump of stone now.~ DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO 8
IF ~Global("OublekBounty2","GLOBAL",0)~ THEN REPLY ~They are gone. Sold by now to hang on the neck as some fat woman's trinket.~ DO ~SetGlobal("ab_GemStoleResolve","GLOBAL",1)~ GOTO 8
END
END//end the append
the trap script for the two containersIF
Opened([ANYONE])
Global("abgf_GemInEye","GLOBAL",1)
THEN
RESPONSE #100
SetGlobal("abgf_GemInEye","GLOBAL",2) //2 is only 1 gem taken from statue
ReputationInc(-1) //only one rep point loss in total cause it reverts the rep point gain given by letting him finish the work
AddJournalEntry(~Perhaps it was wrong, but after allowing Prism to complete his final masterpiece we've taken one of the emeralds he had stolen to use in the statue's eyes. It should bring a hefty price at the right place or a decent reward...~)
END
IF
Opened([ANYONE])
Global("abgf_GemInEye","GLOBAL",2)
THEN
RESPONSE #100
SetGlobal("abgf_GemInEye","GLOBAL",3)
AddJournalEntry(~After a bit of hard work, we finally removed the second emerald which Prism had stolen to use in one of the eyes of his 'final masterpiece'.~)
END
the script addition to ar4800IF
Global("abgf_LeftEyeBounty","GLOBAL",1)
Global("abgf_RightEyeBounty","GLOBAL",1)
Global("OublekBounty2","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("OublekBounty2","GLOBAL",1)
AddJournalEntry(~Prism's story was a sad tale indeed. A shame it could not have had a better ending. Ah well, I profit in the end. 300 gold bounty for the emeralds he stole.~)
END
note i dropped the script from ar5400 and applied a modified version of it to the containers. only a rep loss of 1 occurs (basically a removal of the rep increase for letting him complete the task).
You can easily provide an option for PC to tell Oublek where the emeralds are if you wish