Jump to content

Possible bug


-JW-

Recommended Posts

I'm not exactly sure if this was a bug or something I messed up in my game, but I'm reporting it anyway.

 

The dialogue between the PC and Denak, in the Spider Wood, is supposed to trigger different interjections (or none), depending on several Edwin globals. However they were not triggering properly due what seemed to be a typo.

 

Below there is a snip from x#edint.d. The section that reads GlobalGT is what I'm referring to, and I believe it should be Global, without the GT. Otherwise this will always return true (as there is no such GlobalGT), preventing the other interjections to actually happen.

 

APPEND ~%tutu_var%DENAK~

IF WEIGHT #-2 ~GlobalGT("X#EdwinReturn","GLOBAL",0)~ EdwinDeath
SAY @3
IF ~~ THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())
Enemy()~ EXIT
END

 

Notes: Why the other interjections did not happen, even when their Global existed and was true, I couldn't say for sure. It could be because the script bit in the code box above is at the bottom of them all (and thus it could have priority over the ones over it), or perhaps because of the WEIGHTings... I don't know that much about scripting.

 

Anyhow, thanks for mod!

 

EDIT:

 

I didn't know I can't bold inside code boxes :)

Link to comment

Okay, I have just learned that GT stands for Greater Than, so my report is moot. The condition in the code box then should work, yet I cannot understand why it didn't until I removed the GT... Could it be that GlobalGT actually includes the value stated in the variable?

 

:)

Link to comment

GlobalGT only triggers if the variable is really "greater than" the specified value.

 

If you remove the "greater than" condition from GlobalGT("X#EdwinReturn","GLOBAL",0), it will always be true. For the original case, "X#EdwinReturn" has to be at least at 1 for the state to trigger. I don't know where it gets set, but are you sure it should be in your game?

Link to comment

I just managed to confuse myself, sorry about that. Scratch everything I said. I'm going to try to re-explain things, now making actual sense.

 

As far as I understand, when you refuse to kill Dynaheir, the Global X#EdwinAbandoned gets set to 1. This triggers the following script in _EDWIN.BCS.

 

IF
Global("X#EdwinAbandoned","GLOBAL",1)
Global("X#EdwinReturn","GLOBAL",0)
THEN
RESPONSE #100
	SetGlobal("X#EdwinReturn","GLOBAL",1)
	EscapeAreaMove("FW3000",1833,2153,2)
END

 

Thus setting X#EdwinReturn to 1.

 

The problem is there are two dialogues in _DENAK.DLG that depend on this variable:

 

(state 0)

Global("X#EdwinAllies","GLOBAL",0)
Global("X#EdwinReturn","GLOBAL",1)
!InParty("edwin")
See("denak")

 

(state 11)

GlobalGT("X#EdwinReturn","GLOBAL",0)

 

And both can return true if you refused to kill Dynaheir. Meaning that the one with lower WEIGHTing (the second one) gets the preference and fires always first, preventing the external Edwin dialogue linked to the first from ever happening.

 

Now, this is not a real problem, since Edwin turns hostile anyway, but leaves missing content that probably you guys wanted to be seen. Moreover, there are a total of three Edwin dialogues associated to the Denak meeting, but only one one of them is actually linked to _DENAK.DLG (_EDWIN.DLG - state 32), and it's bugged as I have said above. The other two seem to be a situation where Edwin summons a couple of flesh golems in addition to the Red Wizards becoming hostile, those dialogues are in _EDWIN.DLG (state 33) and in _EDWINP.DLG (state 5).

 

So, in short, when I changed GlobalGT to Global, it seems I wasn't actually fixing anything, but just preventing the state where no Edwin dialogue is linked to fire.

 

I hope this made sense, finally.

I'm sorry to nose so much into your mod, I'm just learning how to code and I'm basically examining everything I come across.

 

Thanks for reading!

Link to comment

Nose, nose, by all means nose!!!!

 

We probably need to rebuild that, to allow all content to be accessed - that looks like a WEIGHT situation, but could also be repaired with more careful scripting. Post any suggestions/tests here, anyone; many hands make liht work, and I won't be back to this until next week.

Link to comment

Okay, I don't want to step on anybody's toes here, but since you asked and I'm eager to try the things I'm learning, here comes a possible alternative code.

 

Currently x#edint.d has the following code setting that encounter:

 

(snip from x#edint.d)

INTERJECT ~%tutu_var%DENAK~ 0 X#EdwinAllies
== ~%tutu_var%EDWIN~ IF ~Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin") See("denak")~ THEN
@1
END
IF ~~ THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",2)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())~ EXIT

APPEND ~%tutu_var%EDWIN~

IF WEIGHT #-2 ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin")~ EdwinUnhappy
SAY @2
IF ~~ THEN DO ~
SetGlobal("X#EdwinReturn","GLOBAL",2)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
Enemy()~ EXIT
END

END

APPEND ~%EDWIN_POST%~

IF WEIGHT #-2 ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin")~ EdwinUnhappy
SAY @2
IF ~~ THEN DO ~
SetGlobal("X#EdwinReturn","GLOBAL",2)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
Enemy()~ EXIT
END

END

APPEND ~%tutu_var%DENAK~

IF WEIGHT #-2 ~GlobalGT("X#EdwinReturn","GLOBAL",0)~ EdwinDeath
SAY @3
IF ~~ THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())
Enemy()~ EXIT
END

END

 

Following my explanations there is a code box with what I thought could be a good replacement (explanations first, code second :)):

 

I have WEIGHTed the starter dialogue with Denak so that it overrides the original bioware one (otherwise it fires first, as its state trigger is 0, the lowest). It should not cause any problem because we are checking for a BG1NPC variable anyway, X#EdwinReturn.

 

The starter dialogue checks if "X#EdwinReturn" > 0 to fire up and override the original bio dialogue. If this returns true, then every dialogue has its own "X#EdwinReturn" condition (1,2,3) depending on what has happened before the encounter (controlled by a script). This is what I have sketched:

 

- If "X#EdwinReturn" = 1, not enough time has passed for him to set up an ambush, and the ~Never double cross... blah~ dialogue fires up. No ogres are summoned.

 

- If "X#EdwinReturn" = 2, Edwin has had time to prepare the ambush, and two ogres will appear. This assumes we go to %EDWIN_POST% (*)

 

* Here I believe we can just obliterate the option to go to %tutu_var%EDWIN, since Edwin's dialogue file should be %EDWIN_POST%, I think. Still I don't know if there's a special case in which it might be needed, but if it is, I could add to the _EDWIN.BCS script a line that changes the dialogue appropriately.

 

- If "Dead("Edwin")", as a safety measure against violent players (like myself), who could kill him while he was escaping, the dialogue is expected to exit. As far as I know, this check is not needed, as in the case he's dead no dialogue will fire anyway.

 

- If "X#EdwinReturn" = 3, then we already have gone through this.

 

Lastly, I have appended the necessary states to %EDWIN_POST%.

 

I'm almost sure more experienced modders will know how to code this better, more efficiently, but I'm a rookie mind you :(. Besides, I've tried my best and I had fun doing it. It works, I have tested it :D (ok, I made a couple of last minute changes for optimization, but I'm gonna test it now)

 

APPEND %tutu_var%DENAK

IF WEIGHT #-2 ~%BGT_VAR% GlobalGT("X#EdwinReturn","GLOBAL",0)~ THEN BEGIN X#EdwinAllies1
	SAY @3
	IF ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",1) !Dead("Edwin") !InParty("edwin") See("denak")~  // no ogre ambush
		THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
				ActionOverride("denak",Enemy())
				ActionOverride("brendan",Enemy())
				ActionOverride("lasala",Enemy())
				ActionOverride("diana",Enemy())
				ActionOverride("edwin",Enemy())~
		EXTERN ~%EDWIN_POST%~ X#EdwinAllies1.1
	IF ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",2) !Dead("Edwin") !InParty("edwin") See("denak")~  // little ogre surprise
		THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
				ActionOverride("denak",Enemy())
				ActionOverride("brendan",Enemy())
				ActionOverride("lasala",Enemy())
				ActionOverride("diana",Enemy())
				ActionOverride("edwin",Enemy())~
		EXTERN ~%EDWIN_POST%~ X#EdwinAllies1.2
	IF ~Dead("Edwin")~  // Edwin is dead
		THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
				ActionOverride("denak",Enemy())
				ActionOverride("brendan",Enemy())
				ActionOverride("lasala",Enemy())
				ActionOverride("diana",Enemy())~
		EXIT
END

END

APPEND %EDWIN_POST%

IF ~!StateCheck("edwin",CD_STATE_NOTVALID)~ X#EdwinAllies1.1
	SAY @1
	IF ~~ THEN DO ~~ EXIT
END

IF ~!StateCheck("edwin",CD_STATE_NOTVALID)~ X#EdwinAllies1.2
	SAY @2
	IF ~~ THEN DO ~CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
				  CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)~ EXIT
END

END

 

Later I'll try to make a script that checks for a certain time before setting "X#EdwinReturn" to 2. It should probably go into %SpiderWood_BCS%. I hope I can do it.

 

EDITs:

So that the code box doesn't look all messed up.

Btw I used indentation, I find it easier that way.

And I'm using those nice macros that unify BGT and Tutu coding. I'm still a bit lost there, so I hope they are fine.

Typo in code box, now it installs properly within BG1NPC

Link to comment

I have added the following lines and scripts to make the whole thing work:

 

(to bg1npc.tp2)

 /* Area Script additions */
 EXTEND_BOTTOM ~%SpiderWood_BCS%.bcs~ ~BG1NPC/Phase2/baf/JW#FW3000.BAF~
  EVALUATE_BUFFER

 

(to x#edint2.baf)

/* Edwin Goes to RW randezvous */
IF %BGT_VAR%
Global("X#EdwinAbandoned","GLOBAL",1)
Global("X#EdwinReturn","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("X#EdwinReturn","GLOBAL",1)
SetGlobalTimer("JW#Edwin","GLOBAL",FOUR_DAYS)  // <--- JW addition
EscapeAreaMove("%SpiderWood%",1833,2153,2)
END

 

(new file: bg1npc/phase2/baf/jw#fw3000.baf

IF
GlobalTimerExpired("JW#Edwin","GLOBAL")
Global("X#EdwinReturn","GLOBAL",1)
THEN
RESPONSE #100
	SetGlobal("X#EdwinReturn","GLOBAL",2)
END

 

This installs fine, and (touch wood) should work. It's late, I'll test it tomorrow.

 

I think I completed my suggestion for an alternative, so not much to add. Only that most likely this differs from the original idea the author had for the encounter, the problem is I just don't know what he had in mind... so I assumed (which is the mother of all fuck ups).

 

Anyhow, it's been a lot of fun trying my first lines of code. If any of you guys want to do something with them, they're all yours to do as you please.

Link to comment

Well, I felt like a dumb when realising that your remark was not the noobish one I thought. Sorry for that!

 

Thank you for the proposal, I will have a look at it hopefully soon and see how it fits with developper's intend. :)

 

Feel free to digg through the rest of the code! All team members are also acive elsewhere, so it happens that we are not able to be the intensive bug-hunters such a huge project should ideally have. So, we are grateful for such effective help. If you find anything else please let us know!

 

Thank you for the kind words, btw!

Link to comment

Whew! I read this topic and felt a few moments of panic. You see, I recoded a whole lot of interjections back in the early spring, and seemed to remember having fits over trying to make sure all Denak's fired. But here's the thing that will let me sleep tonight: this is a WEIGHT issue, and a CHAIN one, not an I_C_T or I_C_T3 one. So I'm off the hook. Yay!

Link to comment

CHAIN! I didn't know I could create the dialogue sequence using a CHAIN command! Thank you, berelinde. :)

 

Last meddling into this, I promise (*crosses fingers*). Below there is another sequence that could replace the one in x#edint.d, much sorter, neater.

 

CHAIN
IF WEIGHT #-2 ~%BGT_VAR% GlobalGT("X#EdwinReturn","GLOBAL",0)~ THEN ~%tutu_var%DENAK~ X#EdwinAllies1
@3
DO ~ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())
SetGlobal("X#EdwinReturn","GLOBAL",3)~ 
== ~%EDWIN_POST%~ IF ~Global("X#EdwinReturn","GLOBAL",1) !Dead("Edwin") !InParty("edwin") !StateCheck("edwin",CD_STATE_NOTVALID) See("denak")~ THEN @1
DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)~
== ~%EDWIN_POST%~ IF ~Global("X#EdwinReturn","GLOBAL",2) !Dead("Edwin") !InParty("edwin") !StateCheck("edwin",CD_STATE_NOTVALID) See("denak")~ THEN @2
DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)~
EXIT

 

I'm not sure if CHAIN is exactly designed for this kind of dialogue, it took me a while to make it work properly. The strings insisted in being funny about their distribution (not in a good way), and some of the actions joined the train, too. No matter, it installs fine now.

 

Hey, I don't think I've said it specifically, but I don't know where to say it either without hijacking a thread. So, Thanks to you guys for all your cool mods out there. Good to play them, good to learn from them.

Link to comment

Added to bg1npc.tp2, at line 2298

/* -JW-'s Edwin and Denak fix */
/* http://forums.gibberlings3.net/index.php?s=&showtopic=15516&view=findpost&p=133308 */
 EXTEND_BOTTOM ~%SpiderWood_BCS%.bcs~ ~BG1NPC/Phase2/baf/JW#FW3000.BAF~

Confirmed correct entries in g3_tutu_cmpvars.tpa and g3_bgt_cmpvars.tpa

 

Created new file bg1npc/phase2/baf/jw#f3000.baf, contents

IF
GlobalTimerExpired("JW#Edwin","GLOBAL")
Global("X#EdwinReturn","GLOBAL",1)
THEN
RESPONSE #100
	SetGlobal("X#EdwinReturn","GLOBAL",2)
END

 

Added to bottom of bg1npc\phase2\baf\x#edint2.baf

/* Edwin Goes to RW randezvous */
IF %BGT_VAR%
Global("X#EdwinAbandoned","GLOBAL",1)
Global("X#EdwinReturn","GLOBAL",0)
SetGlobalTimer("JW#Edwin","GLOBAL",FOUR_DAYS)
THEN
RESPONSE #100
SetGlobal("X#EdwinReturn","GLOBAL",1)
EscapeAreaMove("%SpiderWood%",1833,2153,2)
END

 

Removed lines 17 - 75,

INTERJECT ~%tutu_var%DENAK~ 0 X#EdwinAllies
== ~%tutu_var%EDWIN~ IF ~Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin") See("denak")~ THEN
@1
END
IF ~~ THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",2)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())~ EXIT

APPEND ~%tutu_var%EDWIN~

IF WEIGHT #-2 ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin")~ EdwinUnhappy
SAY @2
IF ~~ THEN DO ~
SetGlobal("X#EdwinReturn","GLOBAL",2)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
Enemy()~ EXIT
END

END

APPEND ~%EDWIN_POST%~

IF WEIGHT #-2 ~%BGT_VAR% Global("X#EdwinReturn","GLOBAL",1) !InParty("edwin")~ EdwinUnhappy
SAY @2
IF ~~ THEN DO ~
SetGlobal("X#EdwinReturn","GLOBAL",2)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
Enemy()~ EXIT
END

END

APPEND ~%tutu_var%DENAK~

IF WEIGHT #-2 ~GlobalGT("X#EdwinReturn","GLOBAL",0)~ EdwinDeath
SAY @3
IF ~~ THEN DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())
Enemy()~ EXIT
END

END

as your analysis is spot on, and replaced with lines 17 - 32

/* Edwin and Denak, -JW-'s recode */
CHAIN IF WEIGHT #-2 ~%BGT_VAR% GlobalGT("X#EdwinReturn","GLOBAL",0)~ THEN ~%tutu_var%DENAK~ X#EdwinAllies1
@3
DO ~ActionOverride("denak",Enemy())
ActionOverride("brendan",Enemy())
ActionOverride("lasala",Enemy())
ActionOverride("diana",Enemy())
ActionOverride("edwin",Enemy())
SetGlobal("X#EdwinReturn","GLOBAL",3)~
== ~%EDWIN_POST%~ IF ~Global("X#EdwinReturn","GLOBAL",1) !Dead("Edwin") !InParty("edwin") !StateCheck("edwin",CD_STATE_NOTVALID) See("denak")~ THEN @1
DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)~
== ~%EDWIN_POST%~ IF ~Global("X#EdwinReturn","GLOBAL",2) !Dead("Edwin") !InParty("edwin") !StateCheck("edwin",CD_STATE_NOTVALID) See("denak")~ THEN @2
DO ~SetGlobal("X#EdwinReturn","GLOBAL",3)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)
CreateCreature("%tutu_var%FGOLEM",[-1.-1],0)~
EXIT

-JW-, as far as I can tell, you matched author intent clearly, and the work on this is very much appreciated. The sole variation is the move of Edwin to the area after four days if left elsewhere, which makes sense according to the dialog. It is entirely possible that the block making that happen was lost over the recodes over the years - it predates creation of the "wait at an inn" and similar components. I am adding you to the credits as a troubleshooter, and send my personal thanks (you saved us a huge chunk of time on this restoration).

 

 

One more follow up to recheck before declaring this fixed. One more state sets the variable X#EdwinAbandoned;

x#edint.d, phase1:

EXTEND_BOTTOM ~%EDWIN_JOINED%~ %BGTEDWINJState12%
IF ~InParty("edwin") InMyArea("edwin") !StateCheck("edwin",CD_STATE_NOTVALID)~ THEN DO ~SetGlobal("X#EdwinAbandoned","GLOBAL",1) SetGlobal("%KICKED_OUT%","LOCALS",2) SetLeavePartyDialogFile() LeaveParty() ChangeAIScript("",DEFAULT)~ EXIT
END

 

As far as I can tell, this is a cool way of shutting down the original state 12. After compilation, in _EDWINJ

IF ~~ THEN BEGIN 12 // from:
 SAY #86895 /* ~(If they'll not do the deed then our deal is forfeit!)  You side with the witch then you will die with her!  Beware my return!~ */
 IF ~~ THEN DO ~SetGlobal("EdwinAbandoned","GLOBAL",1)
EraseJournalEntry(74242)
LeaveParty()
EscapeArea()
~ EXIT
 IF ~InParty("edwin")
InMyArea("edwin")
!StateCheck("edwin",CD_STATE_NOTVALID)
~ THEN DO ~SetGlobal("X#EdwinAbandoned","GLOBAL",1)
SetGlobal("KickedOut","LOCALS",2)
SetLeavePartyDialogueFile()
LeaveParty()
ChangeAIScript("",DEFAULT)
~ EXIT
END

 

This, in conjunction with your script addition, should work beautifully, as Edwin will leave for his rendezvous immediately, and will not need his KickedOut variable to set to 0 or 1 enabling "wait at an inn or just wait here" joining at a very unfortunate time...

 

only two followups for later versions/research.

 

1. Since it won't ever fire, as far as I can tell, but I want to be absolutely sure, I am adding a notation here to research under what condition Edwin could possibly show up in Spiderwood having never joined the party. I can't see how it could happen. Regular scripting sets EdwinAbandoned (not the new X#EdwinAbandoned) in many places, each one having to do with leaving the party. There is dialog that indicates he returns - but I find no indication that anything scripted him to move to the SpiderWood area to fight the party in his script, in the area script for Spiderwood, in the area script for Nashkel, or in baldur.bcs (which makes no sense). We will want to check with UB to make sure there isn't a restoration that would do that on BGT (I have UB for tutu installed and can find no such code).

 

2. The only hassle with both new and old code is the journal entry not being removed. I am flagging this to a list of journal Entry re-tinkerings that may or may not ever get done.

 

So I think we can call this repaired, 11/24/2008 prerelease v17. Thank you :)

Link to comment

Duh. Missed the typo.

/* Edwin Goes to RW rondezvous */
IF %BGT_VAR%
Global("X#EdwinAbandoned","GLOBAL",1)
Global("X#EdwinReturn","GLOBAL",0)
THEN
RESPONSE #100
SetGlobalTimer("JW#Edwin","GLOBAL",28800) //four days
SetGlobal("X#EdwinReturn","GLOBAL",1)
EscapeAreaMove("%SpiderWood%",1833,2153,2)
END
Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...