I don't get it. Kitlist.2da has a Proficiency column, but with values that (for me) goes from 29 to 54. How can this be helpful?
If the value is 29 in KITLIST, then the kit uses column 30 of WEAPPROF.
The original classes use columns 4-21, then the specialists 22 - 29, and the monk and shaman are somewhere between 30 and 60.
The 0th column is an arbitrary label, the 1st column is the proficiency stat ID, 2nd and 3rd columns are string references (name/desc).
COPY_EXISTING ~KITLIST.2DA~ override
READ_2DA_ENTRIES_NOW READ 3
FOR (i = 1; i < READ; ++i) BEGIN
READ_2DA_ENTRY_FORMER READ i 1 ~label~
PATCH_IF ~%label%~ STR_EQ ~KITNAME~ BEGIN // replace KITNAME
READ_2DA_ENTRY_FORMER READ i 6 column ++column
SET i = READ
END
END
BUT_ONLY
COPY_EXISTING ~WEAPPROF.2DA~ override
COUNT_2DA_COLS cols
READ_2DA_ENTRIES_NOW READ cols
FOR (i = 0; i < READ; ++i) BEGIN
READ_2DA_ENTRY_FORMER READ i 1 prof
PATCH_IF prof = 96 BEGIN // 96 = dagger proficiency stat
SET_2DA_ENTRY i column cols ~1~
END
END
BUT_ONLY
EEex needs to know what game is running in order to decide which graphical elements to load in. I think reading the lua global "engine_mode", which is defined in engine.lua, would be sufficient. I assume no mods screw around with this value?
Also, EEex will have to, in the future, detect which mods are installed. I assume directly reading and parsing WeiDU.log is my best hope?
Can I chain Opcode 177 (EA/Anyone) -> Opcode 232 (HP < 102% - .eff) -> Opcode 326 (custom splprot entry: INT > 8) -> MySpell (Set Int = 8) ?
I'm designing a kit that has one severe limitation: Intelligence can never be greater than 8. I thought that would be a way to implement it (not an elegant one, I admit). But I'm afraid the chain will be too long.
EEex needs to know what game is running in order to decide which graphical elements to load in. I think reading the lua global "engine_mode", which is defined in engine.lua, would be sufficient. I assume no mods screw around with this value?
Also, EEex will have to, in the future, detect which mods are installed. I assume directly reading and parsing WeiDU.log is my best hope?
With Weidu, you can use MOD_IS_INSTALLED. Be aware that some UI mods have no installation, if you want to detect them, you have to check for some specific files in the override folder. This is what EEUITweaks does.
Might be easier to simply set max INT to 7 or 8 at chargen, and simply forbid a few known effects that raise INT (potion, Tome, etc.). A few bonuses might still sneak through (I don't know if you can block Lum's Machine), but all in all the INT score will likely remain < 10.
I thought about that, but my initial concern was mod-added and scripted stuff. I also thought about blocking the Int Opcode, but that also would protect against mind flayers attacks.
What can I use with the See() and Dead() trigger? Only Death Variables or also CRE Resref or even a General (like Undead - See(Undead)) or Race (like Spider - Dead(Spider))
Also, I want a thing to happen only if the number of times a creature has talked to me is greater than 0. I know this NumTimesTalkedToGT(I:Num) exists, but don't know how to use it.
To be more precise: Coogan in SoD talks to the party about spiders being nearby. I want to pop up a string in an NPC after he has talked and performed his EscapeArea()
So far I have:
IF
!StateCheck("RANPCNAME",CD_STATE_NOTVALID)
!See([ENEMY])
NumTimesTalkedToGT(I:Num) // here I want to check if the party has talked to Coogan
!See(CREDeathVariable)// here I want to know if this is a valid approach
Global("XXXXXSpiderComment","LOCALS",0)
THEN
RESPONSE #100
DisplayStringHead(Myself,~My Text~)
SetGlobal("XXXXXSpiderComment","LOCALS",1)
END
Thanks!
Edit: I think I've solved one of the problems (NumTimesTalkedTo) with NumTimesInteractedGT, but I'm not certain about See() yet.
NumTimesInteracted can only be used with NPCs that are in NPC.ids and those are only the joinable ones.
In the game, See is used, e.g. See([NOTGOOD.HUMANOID]) !See(LastTrigger) See(FarthestEnemyOf(Myself)) See(NearestEnemyOfType([0.0.0.MAGE_ALL]))
In the EE, there is this OverrideTrigger which I'm not familiar with. But someone else will know whether this could be used with the NumTimesTalkedToGT().
Another possibility I can think of is to give the character a script that sets a global variable if NumTimesTalkedToGT(x). But Coogan doesn't even have an own OVERRIDE script so that's a bit risky with regard to compatibility. (Just for info, I made a list concerning this here and would be happy if people would post what they are using for their mods there, too).
Another possibility is to use ADD_TRANS_ACTION into Coogan's dialogue if the PC talks to him and set a global variable you can use there.
Can you please explain to me how to use the ADD_TRANS_ACTION like I was a 3 yo discovering that daddy will not get back home because he is in jail for being an abusive alcoholic?
Here's an example code for ADD_TRANS_ACTION. This goes into a .d-file.
ADD_TRANS_ACTION BANOMEN BEGIN 432 434 366 END BEGIN END ~SetGlobal("Blabla","GLOBAL",1)~
"BANOMEN" - is the dlg file
BEGIN 432 434 366 END - these are the state numbers (A_T_A patches several at once)
BEGIN END - if you put a number here, the action will only be patched to the according reply options/transactions. Count starts at "0" from top to bottom. (Meaning, if there are three different reply options / transactions, the first one on top has the number "0", the seond is "1", etc.). If there is no number like in this example all reply options / transactions of the states will be patched.
~SetGlobal("Blabla","GLOBAL",1)~ - this is the action you want to add
I think that will do the trick, but I was not able to test it yet because I'm having an ERROR installing the mod:
Adding RAPFAUG to internal list of available DLGs
BIFF may be in hard-drive CD-path [.\lang\en_us\SOD-DLC\DIALOG.BIF]
BIFF may be in hard-drive CD-path [.\cache\SOD-DLC\DIALOG.BIF]
[.\SOD-DLC\DIALOG.BIF] 2307788 bytes, 584 files, 0 tilesets
[BDGLINTJ.DLG] loaded
ERROR locating resource for 'CHAIN3'
Resource [VICONIJ.DLG] not found in KEY file:
[./chitin.key]
ERROR: preprocessing APPEND_EARLY [Pfaug_Raduziel/Dlg/RAPFAUG.d]: Failure("resource [VICONIJ.DLG] not found for 'CHAIN3'")
Stopping installation because of error.
ERROR Installing [Pfaug NPC by Raduziel], rolling back to previous state
This error is related to this piece of code:
CHAIN IF ~Global("RAPfaugJoin","GLOBAL",0) !AreaCheck ("BD0101") !StateCheck("RAPFAUG",CD_STATE_NOTVALID)~ THEN RAPFAUG JOIN000
~For Abbathor's sake, <GIRLBOY>. Do ye have a death wish? Why are ye pesterin' me?~
== BDGLINTJ IF ~InParty("Glint") !StateCheck("Glint",CD_STATE_NOTVALID)~ THEN ~Abatthor? That's interesting.~
== VICONIJ IF ~InParty("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~Ease your tone, Pfaug. <CHARNAME> is an acquaintance of mine. Trust me, you'll want <PRO_HIMHER> by your side.~
== RAPFAUG IF ~InParty("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~Heh. Ye know how to touch this heart o' mine, Viconia. Too bad that's th' only thing ye touch.~
END
IF ~InParty("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN REPLY ~You better respect Viconia, otherwise I assure you this conversation will take an unpleasant turn.~ EXTERN RAPFAUG JOIN001
IF ~~ THEN REPLY ~Death wish? I can show you that I'm not someone easy to kill. Others have tried before and failed. Do you want to join them?~ EXTERN RAPFAUG JOIN001
IF ~~ THEN REPLY ~Sorry for disturbing you. I was just trying to make conversation.~ EXTERN RAPFAUG JOIN002
IF ~~ THEN REPLY ~I guess I'll take my leave, then.~ EXTERN RAPFAUG JOIN005
* I've tried to do this with VICONIJ, BDVICONIJ, BDVICONI and BVICON. The area I was trying to have this dialogue is BD1000.ARE
* BDVICONI and BVICON allows me to install but makes the conversation shut down when she's in the party and was supposed to talk. Same happens with Glint (who doesn't even appear interdia.2da).
You should use Viconias SoD post-join dialogue. That would be BDVICONJ - that is for sure. I have no idea why the game can't find the resource. I suppose you haven't been re-installing BGEE with SoD and forgot to use modmerge, right?
You should use Viconias SoD post-join dialogue. That would be BDVICONJ - that is for sure. I have no idea why the game can't find the resource. I suppose you haven't been re-installing BGEE with SoD and forgot to use modmerge, right?
Both dlgs do not exist in SoD: BG:EE is VICONJ and SoD is BDVICONJ (without the second "i").
Was Viconia in party at the time or not?
If she is in party, it should work with "BDVICONJ".
If not, it should work with "BDVICONI" but you need other triggers.
I would account for both instances in your CHAIN:
== BDVICONJ IF ~InParty("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID) InMyArea("Viconia")~ THEN ~Ease your tone, Pfaug. <CHARNAME> is an acquaintance of mine. Trust me, you'll want <PRO_HIMHER> by your side.~
== BDVICONI IF ~!InParty("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID) InMyArea("Viconia")~ THEN ~Ease your tone, Pfaug. <CHARNAME> is an acquaintance of mine. Trust me, you'll want <PRO_HIMHER> by your side.~
EDIT: corrected the triggers for Viconia not in party but able to speak, doh.
Same for Glint.
Same happens with Glint (who doesn't even appear interdia.2da)
The J.dlgs are listed in bddialog.2da. "interdia" would be for the banter files.
@jastey thanks! I'm adding LOS(O,I) instead of InMyArea(O) to avoid that kind of conversation where an NPC at the other side of the area interact with a conversation she/he isn't can't hear.
The whole block looks like this now:
CHAIN IF ~Global("RAPfaugJoin","GLOBAL",0) !AreaCheck ("BD0101") !StateCheck("RAPFAUG",CD_STATE_NOTVALID) Global("RAPfaugReject","GLOBAL",0) !BeenInParty("RAPfaug")~ THEN RAPFAUG JOIN000
~For Abbathor's sake, <GIRLBOY>. Do ye have a death wish? Why are ye pesterin' me?~
== BDGLINTJ IF ~InParty("Glint") LOS ("Glint",10) !StateCheck("Glint",CD_STATE_NOTVALID)~ THEN ~Abbathor? That's interesting.~
== BDGLINT IF ~!InParty("Glint") LOS ("Glint",10) !StateCheck("Glint",CD_STATE_NOTVALID)~ THEN ~Abbathor? That's interesting.~
== BDVICONJ IF ~InParty("Viconia") LOS ("Viconia",10) !StateCheck("Viconia",CD_STATE_NOTVALID) BeenInParty("Viconia")~ THEN ~Ease your tone, Pfaug. <CHARNAME> is an acquaintance of mine. Trust me, you'll want <PRO_HIMHER> by your side.~
== BDVICONI IF ~!InParty("Viconia") LOS ("Viconia",10) !StateCheck("Viconia",CD_STATE_NOTVALID) BeenInParty("Viconia")~ THEN ~Ease your tone, Pfaug. <CHARNAME> is an acquaintance of mine. Trust me, you'll want <PRO_HIMHER> by your side.~
== RAPFAUG IF ~LOS ("Viconia",10) !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~Heh. Ye know how to touch this heart o' mine, Viconia. Too bad that's th' only thing ye touch.~
END
IF ~LOS ("Viconia",10) !StateCheck("Viconia",CD_STATE_NOTVALID) BeenInParty("Viconia")~ THEN REPLY ~You better respect Viconia, otherwise I assure you this conversation will take an unpleasant turn.~ EXTERN RAPFAUG JOIN001
IF ~~ THEN REPLY ~Death wish? I can show you that I'm not someone easy to kill. Others have tried before and failed. Do you want to join them?~ EXTERN RAPFAUG JOIN001
IF ~~ THEN REPLY ~Sorry for disturbing you. I was just trying to make conversation.~ EXTERN RAPFAUG JOIN002
IF ~~ THEN REPLY ~I guess I'll take my leave, then.~ EXTERN RAPFAUG JOIN005
Two more questions:
1) BeenInParty will return True if the character was in Charname's party during BGEE but not in SoD yet?
2) What the hell is this "Dream Script File" that I find in some banter-related 2da?
BeenInParty will return True if the character was in Charname's party during BGEE but not in SoD yet?
That the trigger also works in SoD from NPCs being in the group in BG:EE is how I understood it, yes.
Dream script: gets executed when the player hits the "rest" button (outdoor or in an inn). The most obvious use was to trigger the dreams (dream script file of Player1 is player1d.bcs, also for SoD.) or "intimacies" lovetalks for romances.
Ok, a new call for aid, even this thread being a little dead lately.
What I want to do: if CHARNAME is a Dwarf, says X. If it's not a Dwarf, says Y. I have the following block:
//Initial Insults
IF
!InParty ("RAPFAUG")
AreaCheck("BD0101")
InMyArea ("Viconia")
!StateCheck("RAPFAUG",CD_STATE_NOTVALID)
!StateCheck("Viconia",CD_STATE_NOTVALID)
LOS([PC], 15)
!Race([PC], DWARF)
Global("PfaugInsultPC","LOCALS",0)
THEN
RESPONSE #100
DisplayStringHead(Myself,~This damn war will get us kille'.~)
Wait (2)
DisplayStringHead ("Viconia",~Spare me from your complaints, Pfaug.~)
Wait (2)
DisplayStringHead(Myself,~Leave me be, woman!~)
Wait (2)
DisplayStringHead(Myself,~Wait a minute, *that* <PRO_GIRLBOY> is th' hero o' Baldur's Gate?.~)
Wait (3)
DisplayStringHead(Myself,~Heh. This city is doomed.~)
SetGlobal("PfaugInsultPC","LOCALS",1)
Continue()
END
IF
!InParty ("RAPFAUG")
AreaCheck("BD0101")
InMyArea ("Viconia")
!StateCheck("RAPFAUG",CD_STATE_NOTVALID)
!StateCheck("Viconia",CD_STATE_NOTVALID)
LOS([PC], 15)
Race([PC], DWARF)
Global("PfaugInsultPC","LOCALS",0)
THEN
RESPONSE #100
DisplayStringHead(Myself,~This damn war will get us kille'.~)
Wait (2)
DisplayStringHead ("Viconia",~Spare me from your complaints, Pfaug.~)
Wait (2)
DisplayStringHead(Myself,~Leave me be, woman!~)
Wait (2)
DisplayStringHead(Myself,~Wait a minute, *that* dwarf is th' hero o' Baldur's Gate?.~)
Wait (3)
DisplayStringHead(Myself,~Heh. Maybe we have a chance.~)
SetGlobal("PfaugInsultPC","LOCALS",1)
Continue()
END
The problem: I've tested with a Dwarf Charname (importing the pre-made dwarf character) and the NPC keeps referring to him as "BOY" instead of using the other block where he should say "DWARF".
Comments
The original classes use columns 4-21, then the specialists 22 - 29, and the monk and shaman are somewhere between 30 and 60.
The 0th column is an arbitrary label, the 1st column is the proficiency stat ID, 2nd and 3rd columns are string references (name/desc).
Thanks!
Also, EEex will have to, in the future, detect which mods are installed. I assume directly reading and parsing WeiDU.log is my best hope?
Tagging @kjeron...
The second question is beyond my scope, but I would assume the same as you.
I'm designing a kit that has one severe limitation: Intelligence can never be greater than 8. I thought that would be a way to implement it (not an elegant one, I admit). But I'm afraid the chain will be too long.
Thanks.
I don't think any mod change engine_mode.
With Weidu, you can use MOD_IS_INSTALLED. Be aware that some UI mods have no installation, if you want to detect them, you have to check for some specific files in the override folder. This is what EEUITweaks does.
I thought about that, but my initial concern was mod-added and scripted stuff. I also thought about blocking the Int Opcode, but that also would protect against mind flayers attacks.
Thanks
What can I use with the See() and Dead() trigger? Only Death Variables or also CRE Resref or even a General (like Undead - See(Undead)) or Race (like Spider - Dead(Spider))
Also, I want a thing to happen only if the number of times a creature has talked to me is greater than 0. I know this NumTimesTalkedToGT(I:Num) exists, but don't know how to use it.
To be more precise: Coogan in SoD talks to the party about spiders being nearby. I want to pop up a string in an NPC after he has talked and performed his EscapeArea()
So far I have:
Thanks!
Edit: I think I've solved one of the problems (NumTimesTalkedTo) with NumTimesInteractedGT, but I'm not certain about See() yet.
NumTimesInteracted can only be used with NPCs that are in NPC.ids and those are only the joinable ones.
Damn.
In the EE, there is this OverrideTrigger which I'm not familiar with. But someone else will know whether this could be used with the NumTimesTalkedToGT().
Another possibility I can think of is to give the character a script that sets a global variable if NumTimesTalkedToGT(x). But Coogan doesn't even have an own OVERRIDE script so that's a bit risky with regard to compatibility. (Just for info, I made a list concerning this here and would be happy if people would post what they are using for their mods there, too).
Another possibility is to use ADD_TRANS_ACTION into Coogan's dialogue if the PC talks to him and set a global variable you can use there.
http://www.pocketplane.net/tutorials/simscript.html
Can you please explain to me how to use the ADD_TRANS_ACTION like I was a 3 yo discovering that daddy will not get back home because he is in jail for being an abusive alcoholic?
Here's an example code for ADD_TRANS_ACTION. This goes into a .d-file.
"BANOMEN" - is the dlg file
BEGIN 432 434 366 END - these are the state numbers (A_T_A patches several at once)
BEGIN END - if you put a number here, the action will only be patched to the according reply options/transactions. Count starts at "0" from top to bottom. (Meaning, if there are three different reply options / transactions, the first one on top has the number "0", the seond is "1", etc.). If there is no number like in this example all reply options / transactions of the states will be patched.
~SetGlobal("Blabla","GLOBAL",1)~ - this is the action you want to add
This error is related to this piece of code:
* I've tried to do this with VICONIJ, BDVICONIJ, BDVICONI and BVICON. The area I was trying to have this dialogue is BD1000.ARE
* BDVICONI and BVICON allows me to install but makes the conversation shut down when she's in the party and was supposed to talk. Same happens with Glint (who doesn't even appear interdia.2da).
* VICONIJ and BDVICONIJ give the error above.
What I'm doing wrong?
Thanks.
Nope, the game is modmerged for sure.
Was Viconia in party at the time or not?
If she is in party, it should work with "BDVICONJ".
If not, it should work with "BDVICONI" but you need other triggers.
I would account for both instances in your CHAIN: EDIT: corrected the triggers for Viconia not in party but able to speak, doh.
Same for Glint.
The J.dlgs are listed in bddialog.2da. "interdia" would be for the banter files.
I would always include a "InMyArea()" check. Dialogues do not work across different areas.
The whole block looks like this now:
Two more questions:
1) BeenInParty will return True if the character was in Charname's party during BGEE but not in SoD yet?
2) What the hell is this "Dream Script File" that I find in some banter-related 2da?
Dream script: gets executed when the player hits the "rest" button (outdoor or in an inn). The most obvious use was to trigger the dreams (dream script file of Player1 is player1d.bcs, also for SoD.) or "intimacies" lovetalks for romances.
---
Does anyone know if I can add more Tokens (like PRO_HIMHER, PRO_GIRLBOY) to the game?
Thanks in advance.
I know. I've expressed myself poorly.
I want to add some other that will behave like those two. To be my precise I want to add PRO_LASSBOY and LASSBOY.
Thanks!
Bonus questions:
i)
Let's say I have at the Override script of a creature a line with the following Object
NearestEnemyOfType([0.UNDEAD])
Will it target the nearest enemy of the creature that is an undead (1) or will it target the nearest enemy that is the enemy of an undead (2)?
Creature + Undead + A
Assumptions:
--- A and Undead have conflicting alliances;
--- Creature and A have allied or neutral alliances, but not necessarily the same;
--- Creature and Undead have conflicting alliance.
1) Creature's script targets Undead
2) Creature's script target's A
What happens?
ii)
What is the difference between SmallWait and Wait?
Thanks.
What I want to do: if CHARNAME is a Dwarf, says X. If it's not a Dwarf, says Y. I have the following block:
The problem: I've tested with a Dwarf Charname (importing the pre-made dwarf character) and the NPC keeps referring to him as "BOY" instead of using the other block where he should say "DWARF".
What am I doing wrong?
Replace [PC] with Player1.
0x400B - Allegiance
0x404D - Gender
0x400E - General
0x4017 - Race
0x401D - Specifics
0x4062 - InteractingWith
for
doesn't solve the issue.
Race("Playe1",DWARF) -> Race(Player1,DWARF)
In-file it was correct, my typo was only here (0344 here in Brazil).
@Bubb What is an object selector? Is it different from a regular object?
Thank you both.