What's the best way to read a file into memory in weidu?
I can do:
COPY ~file~ ~%MOD_FOLDER%~
REPLACE_EVALUATE ~\(.*\)~ BEGIN
TEXT_SPRINT contents ~%MATCH1%~
END ~%MATCH1%~
BUT_ONLY
But it seems an ineffective and roundabout way of doing it.
Another questions regards iterative string building, that is invoking something like
TEXT_SPRINT acc ~%acc%%extra%~
in a loop. This is O(n^2) and unless weidu/OCaml is very smart about it (which it isn't to my knowledge). Can this be spead up somehow, perhaps a function which contatenates all strings in an array?
Can anyone tell me if there's some trick to using PartyRested()?
Nothing in my mod involving that trigger seems to be working.
PartyRested() is one of those triggers that is set selectively - I.E. only detectable by certain objects.
The only objects notified of PartyRested() are:
1) All characters currently in the party
2) Any player-summoned familiars
3) The global game script, (BALDUR.BCS or whatever it is in the current campaign)
4) The current area script
Are you trying to detect the trigger with an object not included in the above list? If so, you could use a roundabout hack of setting a variable in the global game script, and then using that variable to detect the trigger. For example, putting this at the top of BALDUR.BCS:
IF
PartyRested()
THEN
RESPONSE #100
SetGlobal("B3Rested","GLOBAL",1)
Continue()
END
IF
Global("B3Rested","GLOBAL",1)
THEN
RESPONSE #100
SetGlobal("B3Rested","GLOBAL",0)
Continue()
END
Can anyone tell me if there's some trick to using PartyRested()?
Nothing in my mod involving that trigger seems to be working.
PartyRested() is one of those triggers that is set selectively - I.E. only detectable by certain objects.
The only objects notified of PartyRested() are:
1) All characters currently in the party
2) The global game script, (BALDUR.BCS or whatever it is in the current campaign)
3) The current area script
Are you trying to detect the trigger with an object not included in the above list? If so, you could use a roundabout hack of setting a variable in the global game script, and then using that variable to detect the trigger. For example, putting this at the top of BALDUR.BCS:
IF
PartyRested()
THEN
RESPONSE #100
SetGlobal("B3Rested","GLOBAL",1)
Continue()
END
IF
Global("B3Rested","GLOBAL",1)
THEN
RESPONSE #100
SetGlobal("B3Rested","GLOBAL",0)
Continue()
END
And then using this in place of PartyRested():
Global("B3Rested","GLOBAL",1)
should work in SoA - at least in theory.
For me PartyRested() won't do anything, even in the file of a person in the party. It won't set triggers, it won't start dialogues. But interestingly it will prevent things from triggering, so the game is recognizing it, I just have no way to set it off.
However Jaheira's romance bandit scene, which relies on PartyRested() triggered just fine in my game. We're both using the latest version of BG2:EE, so it's only affecting things we mod which makes me believe there's some trick we're doing wrong.
For example we have the following in Hexxat.BCS
IF
InParty("Mazzy")
!StateCheck("Mazzy",CD_STATE_NOTVALID)
InParty("Hexxat")
!StateCheck("Hexxat",CD_STATE_NOTVALID)
Global("_bMazHexConflict","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("_bMazHexConflict","GLOBAL",1)
END
IF
InParty("Mazzy")
!StateCheck("Mazzy",CD_STATE_NOTVALID)
InParty(Myself)
!StateCheck("Hexxat",CD_STATE_NOTVALID)
CombatCounter(0)
!AreaType(DUNGEON)
!AreaCheck("AR4500")
Global("_bMazHexConflict","GLOBAL",1)
PartyRested()
THEN
RESPONSE #100
SetGlobal("_bMazHexConflict","GLOBAL",2)
StartDialogNoSet(Player1)
END
And then this is the start of the dialogue:
CHAIN IF WEIGHT #-1 ~Global("_bMazHexConflict","GLOBAL",2)~ THEN HEXXATJ _bMazHexFight1
@40 /*Well, what is it, halfling? You've been staring at me since we awoke. I mean you no harm.*/
DO ~Setglobal("_bMazHexConflict","GLOBAL",3)~
What happens is the dialogue never trigges and Global("_bMazHexConflict","GLOBAL",1) stays at 1 even after a refreshing night in Trademeet's Inn. But if I take out PartyRested() then it triggers immediately if both are in my party. So the PartyRested()'s only function right now is to stop things from triggering. We can't figure out how to get it to actually happen.
@Bubb That's good to know, thanks. I think the PartyRested issues might be save or game specific at least, since the above triggers appear to work in my game just on a slight delay. It seems to take one more rest than it should for the conversation to start.
What I really haven't managed to fix is the dead selection issue, even with your code. If I can't figure it out soon, I may have to resort to posting the code and seeing if there's some obvious error I missed. I've tried it with and without actionoverride and it several different places with no luck.
The above script block works flawlessly for me... weird. The only thing I can think of that could be causing problems is that the PartyRested() trigger is only set for 1 script-pass after resting. If the script is busy doing something else it will evaluate the PartyRested() as false, (because it skipped over the block on the one pass that would've resolved it to true).
If you guys want to upload savegames and the full scripts and dialogs in question I can take a look at what's happening internally - for both the PartyRested() and dead selection issue.
@Bubb Interesting. It's good to know that our code will probably work for other players, even if our issues make it difficult to test. I wonder if the selection fix would work for other people too. I didn't install my game that long ago but I'm thinking it might be time for a fresh save if things keep glitching out.
I'm going to be gone this weekend, but BCaesar should be able to upload something. His game is having more issues with PartyRested() than mine and if you're able to figure out why, we would be very grateful. Both of us are more or less learning to code things as we go.
I don't remember which version of my attempts to fix the selection glitch he currently has, but I can upload that code next week if need be. If you end up looking for it, it's either in gettingClara.baf (which is where she joins) or _bClara.baf depending on the version. Thanks again for the help.
@subtledoctor
Continuing from the other thread I mistakenly posted in:
I was interested in adding new weapon types, basically doing the reverse of Scales of Balance (and others grouping proficiences). Instead of bundling similar weapons and basically making everything within equivalent, I thought about adding a free '*' in similar weapons once mastery in a weapon style is reached. So, for example, wakizashi, ninjato and scimitars could become separate proficiences, but gaining mastery in one would give free (first only!) '*' in the others. Most of the stuff I could likely just move around to a satisfying effect, but I was really intent on making thrown axes and thrown daggers separate proficiences, as it makes no sense to group them with melee equivalent. This would most likely remove their melee capabilities altogether and close some exploits.
Do you know what other mods use that unused proficiency slots? Maybe they would be incompatible with what I plan in the first place.
Aaaand a WeiDU question: is there any way of returning an empty array from a function? It always complains that the return value is uninitialized. This is a mind boggling deficiency in my eyes...
I feel like an idiot for not coming up with the oldest trick in the book. Although I doubt it would be much more convenient than always returning array length with an array, as both solutions require an additional IF (unless the array is indexed by consecutive intgerers and can be iterated with a FOR without the extra plumbing.
Hello everyone,
I hope i'm in the right place to ask dumb newbie questions about modding ?
I'm going to assume that's the case and go straight ahead:
I'm using Near Infinity atm and i came across an Effect that i don't understand, it's called "Modify script state".
Being ignorant as i am, i have absolutely no clue as to what this does or is able to do, in my case i'd like to know what it does on the Cleric lvl 5 spell "Death Ward" ?
Is there a list somewhere that explains all these Effects btw ?
Is there a list somewhere that explains all these Effects btw ?
Yes, there is! Take a look at the IESDP Index, a website with modding information for the Infinity Engine games. This page gives information about all the different kinds of effects.
@Maerdyl - That specific effect on Death Ward does nothing by itself. AI scripts can detect that value and react accordingly - generally when looking for a target to dispel or to avoid wasting instant death spells on that target.
Not sure if this is the best place to post this. But I haven't seen the Near Infinity thread in some time, and I don't think its active anymore. I'm trying to use NI to edit BG1's Moonblade to be usable by lawful good characters, but I don't know how. I can find the item file and the edit tab, but I'm not really sure what I'm looking at.
*edit*
Oh, and I seem to recall that it uses the dagger prof in EE. Is that true? and if so, can I change it?
Not sure if this is the best place to post this. But I haven't seen the Near Infinity thread in some time, and I don't think its active anymore. I'm trying to use NI to edit BG1's Moonblade to be usable by lawful good characters, but I don't know how. I can find the item file and the edit tab, but I'm not really sure what I'm looking at.
*edit*
Oh, and I seem to recall that it uses the dagger prof in EE. Is that true? and if so, can I change it?
To make the Moonblade usable by someone other than Xan, you must remove its entry from item_use.2da. Then just edit the item to be usable only by lawful good characters.
If you want it to be usable by Xan AND lawful good characters, regardless of Xan's alignment, I can't help you there.
Aaaand a WeiDU question: is there any way of returning an empty array from a function? It always complains that the return value is uninitialized. This is a mind boggling deficiency in my eyes...
The above script block works flawlessly for me... weird. The only thing I can think of that could be causing problems is that the PartyRested() trigger is only set for 1 script-pass after resting. If the script is busy doing something else it will evaluate the PartyRested() as false, (because it skipped over the block on the one pass that would've resolved it to true).
If you guys want to upload savegames and the full scripts and dialogs in question I can take a look at what's happening internally - for both the PartyRested() and dead selection issue.
@Ratatoskr
I'll let Ratatoskr give you the Clara selection thing since she's been working on that.
But for PartyRested() I attached my save.
The full script code is:
//Hexxat - Mazzy Conflict, both SOA and TOB - uses this file because starts after rest, not on rest or interrupted
IF
InParty("Mazzy")
!StateCheck("Mazzy",CD_STATE_NOTVALID)
InParty("Hexxat")
!StateCheck("Hexxat",CD_STATE_NOTVALID)
Global("_bMazHexConflict","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("_bMazHexConflict","GLOBAL",1)
END
IF
InParty("Mazzy")
!StateCheck("Mazzy",CD_STATE_NOTVALID)
InParty(Myself)
!StateCheck("Hexxat",CD_STATE_NOTVALID)
CombatCounter(0)
!AreaType(DUNGEON)
!AreaCheck("AR4500")
Global("_bMazHexConflict","GLOBAL",1)
PartyRested()
THEN
RESPONSE #100
SetGlobal("_bMazHexConflict","GLOBAL",2)
StartDialogNoSet(Player1)
END
The dialogue is long and all tra'd but here's the start of it in our d file. Even though the dialogue is tra'd we always put what they say inside /* */ because otherwise it makes it impossible for us to find anything.
//Hexxat-Mazzy conversation
CHAIN IF WEIGHT #-1 ~Global("_bMazHexConflict","GLOBAL",2)~ THEN HEXXATJ _bMazHexFight1
@40 /*Well, what is it, halfling? You've been staring at me since we awoke. I mean you no harm.*/
DO ~Setglobal("_bMazHexConflict","GLOBAL",3)~
== MAZZYJ @41 /*Where did you go last night, vampire? You left as soon as you thought the rest of us had fallen asleep.*/
== HEXXATJ @42 /*I thought wrong, it seems. There is a house near here. I went inside and found a girl and drank her blood while her father slept in the other room. The girl tasted of loss, but also of happiness and joy. She was cared for and loved and at peace. She remained asleep the whole time and when I finished, I lay there basking in her emotions and her memories; they were so warm and beautiful. I'm trying to hold onto those feelings, but they are already slipping away.*/
== MAZZYJ @43 /*You murdered a girl...*/
== HEXXATJ @44 /*Yes.*/
== MAZZYJ @45 /*...who was happy and loved...*/
== HEXXATJ @46 /*Yes.*/
== MAZZYJ @47 /*...and you felt it?*/
== HEXXATJ @48 /*Feeding is the only time that I feel anything. I do not remember what it was like to truly have emotions, but when I satisfy my hunger I can experience those of my prey for a little while if they stay asleep until the end. Often they wake up while I am drinking and then it is ruined because their blood just tastes like fear.*/
== MAZZYJ @49 /*Draw your weapon and fight me, spawn of evil!*/
== HEXXATJ @50 /*I am not your enemy, Mazzy. I would like to be your friend. Why do you wish to fight?*/
== MAZZYJ @51 /*For the girl. For her father who woke up today and found his daughter dead. For every innocent you've killed or will kill if I let you live!*/
== HEXXATJ @52 /*I am sorry to hear that. There is no malice in me, child. I am only death. I take the evil and the good, the vile and the innocent, the righteous and the wicked. Everyone must die, Mazzy, and I need to drink in order to survive.*/
== MAZZYJ @53 /*Then I will end your life where you stand. Are you with me, <CHARNAME>? I do not wish to kill you too, but I will if you try to stop me.*/
For op331 (in Spell/Item):
Special=0: Summon amount equal to (Param1 + DiceNum(d)DiceSize))
Special=1: Summon amount equal to (Param1 + DiceNum(d)DiceSize))
Special=2: Summon until power level equals/exceeds "Caster Level"
For op331(in EFF):
Special=0: Summon until power level equals/exceeds Param1
Special=1: Summon amount equal to (Param1 + DiceNum(d)DiceSize))
Special=2: Summon until power level equals/exceeds "Caster Level" field of EFF
For op127 (in Spell/Item):
Special=0: Summon until power level equals/exceeds Param1
Special=1: Summon amount equal to Param1
Special=2: Summon until power level equals/exceeds "Caster Level"
For op127 (in EFF):
Special=0: Summon until power level equals/exceeds Param1
Special=1: Summon amount equal to (Param1 + DiceNum(d)DiceSize))
Special=2: Summon until power level equals/exceeds "Caster Level" field of EFF
What about allegiance of the summoned creatures? Is it automatically set to "Match target"? If so, is "Controlled" OK?
Separately, do you know if it's possible to prevent the player from summoning more than X creatures whose GENDER is different from SUMMONED? I tried to expand/add a row to SUMMLIMT.2da but it's not working......
What about allegiance of the summoned creatures? Is it automatically set to "Match target"? If so, is "Controlled" OK?
op331 uses "Match Target", which sets the summoned creature's allegiance to one of 4|Ally, 128|Neutral, or 255|Enemy, based on the summoner (whichever group the summoner belongs).
op127 the allegiance is still based on parameter2 (0-4:Ally, 5-9:Enemy), even when using a custom 2da file.
Separately, do you know if it's possible to prevent the player from summoning more than X creatures whose GENDER is different from SUMMONED? I tried to expand/add a row to SUMMLIMT.2da but it's not working.
Separately, do you know if it's possible to prevent the player from summoning more than X creatures whose GENDER is different from SUMMONED? I tried to expand/add a row to SUMMLIMT.2da but it's not working.
I do not.
I noticed that you cannot hit the summoning cap via summoning creatures whose SEX is SUMMONED. Is it intended?
Hey there,
I've encountered an odd "phenomenon" while making my own items with Near Infinity in BG1 SoD, more specifically any item that adds AC through the Effect "AC bonus (0)".
So here's an example:
- I grab "The Guard's Ring +2" and make a copy of it to the override folder
- I only modify the copy, adding to it some new effects, i.e Regeneration (98)
- I give it a nice new name, save everything and start the game to try it out
Everything works perfectly, i get both bonuses as i should... well, until i realize that everyone can wear the ring, regardless of other enchanted equipment that should prevent it from being worn simultaneously.
What bothers me here is that i didn't even touch the effects that grant the AC bonuses and it still does this regardless.
So how come it gets a free pass all of a sudden ? i also have to mention that it replicated this exact behavior with Armors, Helmets, Amulets etc... As soon as i add or modify anything on an item with AC modifiers it completely lifts the magic item restriction.
Any insight/help on the matter would be greatly appreciated!
P.S: i linked the Ring used in my example, if anyone wants to take a look at it.
@Maerdyl The restrictions against multiple enchanted gear is controlled by a 2da file (ITEMEXCL.2da), which lists all such items that cannot be worn together, here is what it looks like:
Aw, damn alright, so do you have any suggestions on what to do for it to work as it's supposed to in the game ? Because i've taken a quick look at some 2DA files using NI and there are over 600 of those! How do i figure out which one i need to modify, if that is indeed what i have to do ofc...
P.S: My bad, i was reading diagonally i guess, i just noticed you actually pointed out what file was responsible for the enchanted gear restrictions.
@Bubb Here is the latest version of the code to fix our dead character selection glitch. I've tried both with and without ActionOverride, but nothing seems to work. Any suggestions you might have would be greatly appreciated.
IF //Script to add Clara to your party once Hexxat is dead.
Dead("hexxat")
Global("_bClaraLives","GLOBAL",1)
!InPartyAllowDead("hexxat")
THEN
RESPONSE #100
SetGlobal("_bClaraLives","GLOBAL",2)
CreateCreature("_bClara",[-1.-1],N)
ActionOverride("_bClara",JoinParty())
ActionOverride("_bClara",MoveGlobalObject("_bClara",Player1))
END
Comments
I can do: But it seems an ineffective and roundabout way of doing it.
Another questions regards iterative string building, that is invoking something like in a loop. This is O(n^2) and unless weidu/OCaml is very smart about it (which it isn't to my knowledge). Can this be spead up somehow, perhaps a function which contatenates all strings in an array?
PartyRested() is one of those triggers that is set selectively - I.E. only detectable by certain objects.
The only objects notified of PartyRested() are:
1) All characters currently in the party
2) Any player-summoned familiars
3) The global game script, (BALDUR.BCS or whatever it is in the current campaign)
4) The current area script
Are you trying to detect the trigger with an object not included in the above list? If so, you could use a roundabout hack of setting a variable in the global game script, and then using that variable to detect the trigger. For example, putting this at the top of BALDUR.BCS:
And then using this in place of PartyRested():
should work in SoA - at least in theory.
For me PartyRested() won't do anything, even in the file of a person in the party. It won't set triggers, it won't start dialogues. But interestingly it will prevent things from triggering, so the game is recognizing it, I just have no way to set it off.
However Jaheira's romance bandit scene, which relies on PartyRested() triggered just fine in my game. We're both using the latest version of BG2:EE, so it's only affecting things we mod which makes me believe there's some trick we're doing wrong.
For example we have the following in Hexxat.BCS
And then this is the start of the dialogue:
What happens is the dialogue never trigges and Global("_bMazHexConflict","GLOBAL",1) stays at 1 even after a refreshing night in Trademeet's Inn. But if I take out PartyRested() then it triggers immediately if both are in my party. So the PartyRested()'s only function right now is to stop things from triggering. We can't figure out how to get it to actually happen.
What I really haven't managed to fix is the dead selection issue, even with your code. If I can't figure it out soon, I may have to resort to posting the code and seeing if there's some obvious error I missed. I've tried it with and without actionoverride and it several different places with no luck.
The above script block works flawlessly for me... weird. The only thing I can think of that could be causing problems is that the PartyRested() trigger is only set for 1 script-pass after resting. If the script is busy doing something else it will evaluate the PartyRested() as false, (because it skipped over the block on the one pass that would've resolved it to true).
If you guys want to upload savegames and the full scripts and dialogs in question I can take a look at what's happening internally - for both the PartyRested() and dead selection issue.
I'm going to be gone this weekend, but BCaesar should be able to upload something. His game is having more issues with PartyRested() than mine and if you're able to figure out why, we would be very grateful. Both of us are more or less learning to code things as we go.
I don't remember which version of my attempts to fix the selection glitch he currently has, but I can upload that code next week if need be. If you end up looking for it, it's either in gettingClara.baf (which is where she joins) or _bClara.baf depending on the version. Thanks again for the help.
Continuing from the other thread I mistakenly posted in:
I was interested in adding new weapon types, basically doing the reverse of Scales of Balance (and others grouping proficiences). Instead of bundling similar weapons and basically making everything within equivalent, I thought about adding a free '*' in similar weapons once mastery in a weapon style is reached. So, for example, wakizashi, ninjato and scimitars could become separate proficiences, but gaining mastery in one would give free (first only!) '*' in the others. Most of the stuff I could likely just move around to a satisfying effect, but I was really intent on making thrown axes and thrown daggers separate proficiences, as it makes no sense to group them with melee equivalent. This would most likely remove their melee capabilities altogether and close some exploits.
Do you know what other mods use that unused proficiency slots? Maybe they would be incompatible with what I plan in the first place.
Most inns appear to have that type listed, but NearInfinty marks it with an error.
Edit: Nevermind, I think it may have been the difference between using AreaType and AreaCheck. I'm not getting the error now.
I hope i'm in the right place to ask dumb newbie questions about modding ?
I'm going to assume that's the case and go straight ahead:
I'm using Near Infinity atm and i came across an Effect that i don't understand, it's called "Modify script state".
Being ignorant as i am, i have absolutely no clue as to what this does or is able to do, in my case i'd like to know what it does on the Cleric lvl 5 spell "Death Ward" ?
Is there a list somewhere that explains all these Effects btw ?
Yes, there is! Take a look at the IESDP Index, a website with modding information for the Infinity Engine games. This page gives information about all the different kinds of effects.
*edit*
Oh, and I seem to recall that it uses the dagger prof in EE. Is that true? and if so, can I change it?
To make the Moonblade usable by someone other than Xan, you must remove its entry from item_use.2da. Then just edit the item to be usable only by lawful good characters.
If you want it to be usable by Xan AND lawful good characters, regardless of Xan's alignment, I can't help you there.
Is that found in the item file?
No, it's found in item_use.2da.
http://www.weidu.org/~thebigg/README-WeiDU.html#DEFINE_ACTION_FUNCTION
http://www.weidu.org/~thebigg/README-WeiDU.html#LAUNCH_ACTION_FUNCTION
@Ratatoskr
I'll let Ratatoskr give you the Clara selection thing since she's been working on that.
But for PartyRested() I attached my save.
The full script code is:
The dialogue is long and all tra'd but here's the start of it in our d file. Even though the dialogue is tra'd we always put what they say inside /* */ because otherwise it makes it impossible for us to find anything.
What about allegiance of the summoned creatures? Is it automatically set to "Match target"? If so, is "Controlled" OK?
Separately, do you know if it's possible to prevent the player from summoning more than X creatures whose GENDER is different from SUMMONED? I tried to expand/add a row to SUMMLIMT.2da but it's not working......
In my game they only seem to trigger in dialogue files even though the game itself has that command in bcs files.
op127 the allegiance is still based on parameter2 (0-4:Ally, 5-9:Enemy), even when using a custom 2da file. I do not.
I noticed that you cannot hit the summoning cap via summoning creatures whose SEX is SUMMONED. Is it intended?
I've encountered an odd "phenomenon" while making my own items with Near Infinity in BG1 SoD, more specifically any item that adds AC through the Effect "AC bonus (0)".
So here's an example:
- I grab "The Guard's Ring +2" and make a copy of it to the override folder
- I only modify the copy, adding to it some new effects, i.e Regeneration (98)
- I give it a nice new name, save everything and start the game to try it out
Everything works perfectly, i get both bonuses as i should... well, until i realize that everyone can wear the ring, regardless of other enchanted equipment that should prevent it from being worn simultaneously.
What bothers me here is that i didn't even touch the effects that grant the AC bonuses and it still does this regardless.
So how come it gets a free pass all of a sudden ? i also have to mention that it replicated this exact behavior with Armors, Helmets, Amulets etc... As soon as i add or modify anything on an item with AC modifiers it completely lifts the magic item restriction.
Any insight/help on the matter would be greatly appreciated!
P.S: i linked the Ring used in my example, if anyone wants to take a look at it.
P.S: My bad, i was reading diagonally i guess, i just noticed you actually pointed out what file was responsible for the enchanted gear restrictions.
Dead("hexxat")
Global("_bClaraLives","GLOBAL",1)
!InPartyAllowDead("hexxat")
THEN
RESPONSE #100
SetGlobal("_bClaraLives","GLOBAL",2)
CreateCreature("_bClara",[-1.-1],N)
ActionOverride("_bClara",JoinParty())
ActionOverride("_bClara",MoveGlobalObject("_bClara",Player1))
END