Yes.Is this the component you are using such a thing for?
Optional: Joinable NPCs more closely match the PCs experience
NPCs, upon joining, will have their XP total adjusted to something closer to the PC's. This component is new to the last beta, and I don't much like the implementation at this point. It'll be revised, eventually.
[WIP] Expanded Triggers
#41
Posted 22 March 2011 - 08:46 AM
Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle
#42
Posted 24 March 2011 - 01:01 PM
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#43
Posted 24 March 2011 - 05:45 PM
I personally didn't need it right away, and I've only heard one person asking about it (recently anyway). I liked the idea of a sort of ActualXP trigger, because it would allow a simple script substitution if TobEx were detected (vs. the old way if not). But I suppose variable substitution would be more flexible and could make the script a lot shorter (offhand I can't envision how such a script would look but I guess that's for the future to sort out). Hey, if it takes long enough, maybe even Nythrun will rear her head and code it in, saving me from doing it .OK, I think the best long term solution is to allow variable substitution to some extent, because it will enable much more than a L1NPCs-specific feature. That will obviously take a while to implement, so so long as you are willing to wait a bit then all is good?
Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle
#44
Posted 24 April 2012 - 11:19 PM
Here is a test script I have been mucking around with:0x411A Eval1Str(S:Name*,S:Scope*,I:Mode*TrigEval)
0x411A Eval1Int(I:Mode*TrigEval,I:StatNum*Stats)
0x411B Eval2Str(S:Name*,S:Scope*,I:Mode*TrigEval)
0x411B Eval2Int(I:Mode*TrigEval,I:StatNum*Stats)
Modifies a value in the next trigger depending on the Mode specified based on TRIGEVAL.IDS
This trigger does not evaluate and does not count as a trigger in an OR() block
This trigger does not count as a trigger modified by Eval*()
Use NextTriggerObject() to modify the target to derive the value fromTRIGEVAL.IDS
0 VAR
Modify target value with the value of a variable named "Name" of scope "Scope"
1 STAT
Modify target value with the value of the the stat at index "StatNum"
2 2DA
Modify target value with a value inside a table contained in a 2DA file
Usage:
-"Name" is treated as "<2DA filename>.<column name>.<row name>"
-"Scope" is unused. Note that you can theoretically specify "<2DA filename>." here with "Name" as "<column name>.<row name>". This is discouraged, as certain compilers such as NearInfinity do not compile this correctly.
Example:
-Eval1Str("HPPRS.ROLLS.1","",2DA) will modify the first integer argument of the next valid trigger with the value contained at column "ROLLS", row "1" in "HPPRS.2DA".
0x411C E(I:Num1*,I:Num2*)
0x411D GT(I:Num1*,I:Num2*)
0x411E LT(I:Num1*,I:Num2*)
Compares Num1 to Num2, where E is equals, GT is greater than, and LT is less than.
To make use of these triggers, Eval*() triggers should be used prior to this trigger
IF HotKey© THEN RESPONSE #100 SetGlobal("test","GLOBAL",100) SetGlobal("test2","GLOBAL",100) SetGlobal("test3","GLOBAL",3) END IF HotKey(D) THEN RESPONSE #100 SetGlobal("test","GLOBAL",200) SetGlobal("test2","GLOBAL",100) SetGlobal("test3","GLOBAL",0) END IF HotKey(E) THEN RESPONSE #100 SetGlobal("test","GLOBAL",100) SetGlobal("test2","GLOBAL",200) SetGlobal("test3","GLOBAL",1) END IF Eval1Str("test","GLOBAL",VAR) Eval2Str("test2","GLOBAL",VAR) E(0,1) //it doesn't matter what these values are, they will always be overridden THEN RESPONSE #100 //should only work if I press C or as soon as I give a cre the script for the first time in a game DisplayStringHead(Myself,1) // No, I'm sorry, none of them sound familiar. SetGlobal("test","GLOBAL",1000) SetGlobal("test2","GLOBAL",1001) //stops it from firing forever Continue() END IF Eval1Int(STAT,XP) GlobalLT("test","GLOBAL",0) //does test < XP THEN RESPONSE #100 //should be true in all cases DisplayStringHead(Myself,2) // You played Elminster? SetGlobal("test","GLOBAL",10000000) //stops it from firing forever Continue() END IF Eval1Str("test3","GLOBAL",VAR) Eval2Str("HPPRS.ROLLS.1","",2DA) //in ToB, the value of this is 1 E(0,0) THEN RESPONSE #100 //should only be true if I press E DisplayStringHead(Myself,3) // Uh, the yugoloth, was it? Yeah, you stole the show with that one, if I recall. SetGlobal("test3","GLOBAL",0) //stops it from firing forever ENDThere is potential to add a lot more Modes to evaluate, especially things that cannot usually be accessed with existing triggers. This also opens up a lot more opportunity to be able to compare numbers beyond what is already available in existing triggers. For example, you can theoretically use these new triggers to compare two variables, but that already exists. However, you might want to compare one stat with another stat (e.g. am I strong enough to beat this AC value character?).
I'm thinking about how exactly to add arithmetic, but no bright ideas yet. Not sure how I can modify actions yet either, but we will see.
Edited by Ascension64, 24 April 2012 - 11:29 PM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#45
Posted 25 April 2012 - 08:57 PM
Or is it the "cycle" delay (not knowing which actions will get triggered on each frame, potentially misordering the assigments)? Can't you just add a action with the same name that does the same thing as the trigger (but to the action function offsets of course, so you don't misorder?
Edited by i30817, 25 April 2012 - 09:12 PM.
#46
Posted 25 April 2012 - 11:47 PM
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#47
Posted 26 April 2012 - 05:33 PM
As in:
IF OR(2) Eval1Str("test","GLOBAL",VAR) Eval2Str("test2","GLOBAL",VAR) EQ(_,_) Eval1Str("test","GLOBAL",VAR) Eval2Str("test3","GLOBAL",VAR) EQ(_,_)
if not, if we do instead:
IF Eval1Str("test","GLOBAL",VAR) Eval2Str("test2","GLOBAL",VAR) EQ(_,_) .... IF !EQ(_,_) Eval1Str("test","GLOBAL",VAR) Eval2Str("test3","GLOBAL",VAR) EQ(_,_)would this work? Or would it need to replicate the EvalStr before using !EQ in the second block?
Lol, the horrible contortions that BGScript original design is going through.
Edited by i30817, 26 April 2012 - 05:40 PM.
#48
Posted 28 April 2012 - 04:44 AM
I've done some more work on this. I have figured out to add the actions, but I should settle on some things in concrete with the triggers first.
How obfuscated is this code?
IF Eval1("HPCLASS","",0,1,2DA_STR_SET) //HPCLASS is a 2DA table with strings, let's try and substitute that string is the next 2DA table to look up and get a value from it Eval2("","",-10,0,INT_ADD) Eval2("LEVEL","",0,0,STAT_SET) Eval1("<Eval>","",1,0,2DA_INT_SET) //var1 = (HPCLASS[0.1])[1.(STAT.LEVEL - 10)]; note that this processes all the evaluators above Eval2("test","GLOBAL",0,0,VAR_SET) //var2 = "GLOBALtest" E(-33,-33) //ends up evaluating to E(1,0) on vanilla+TobEx installation THEN RESPONSE #100 DisplayStringHead(Myself,1) // No, I'm sorry, none of them sound familiar. SetGlobal("test","GLOBAL",0) Continue() END
Edited by Ascension64, 28 April 2012 - 04:46 AM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#49
Posted 28 April 2012 - 05:31 AM
0x411A Eval1(S:Name*,S:Scope*,I:Num1*,I:Num2*,I:Mode*Evaluate)
0x411B Eval2(S:Name*,S:Scope*,I:Num1*,I:Num2*,I:Mode*Evaluate)
Modifies a value in the next trigger depending on the Mode specified based on EVALUATE.IDS
This trigger does not evaluate and does not count as a trigger in an OR() block
This trigger does not count as a trigger modified by Eval*() unless one of the 2DA_* modes is used
Use NextTriggerObject() to modify the target to derive the value from
EVALUATE.IDS
Specifies the possible types and modes for the Eval*() triggers
Opcodes are separated into the upper word (Type) and lower word (Mode)
Types
0x0000 *_SET
0x0001 *_ADD
0x0002 *_MUL
0x0004 *_DIV
0x0008 *_MOD
0x0010 *_PC
Modes
1 INT_*
Modify target value with a constant integer "Num1"
2 VAR_*
Modify target value with the value of a variable named "Name" of scope "Scope"
3 STAT_*
Modify target value with the value of the stat specified in "Name"
4 2DA_INT_*
Modify target value with the integer value located at column index "Num1", row index "Num2" of the 2DA file specified in "Name"
"Name", "Num1" and "Num2" can be modified by previous Eval*() triggers
5 STR_SET
Modify target value with a constant string "Name"
6 2DA_STR_SET
Modify target value with the string value located at column index "Num1", row index "Num2" of the 2DA file specified in "Name"
"Name", "Num1" and "Num2" can be modified by previous Eval*() triggers
0x411C E(I:Num1*,I:Num2*)
0x411D GT(I:Num1*,I:Num2*)
0x411E LT(I:Num1*,I:Num2*)
Compares Num1 to Num2, where E is equals, GT is greater than, and LT is less than.
To make use of these triggers, Eval*() triggers should be used prior to this trigger
Edited by Ascension64, 28 April 2012 - 05:32 AM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#50
Posted 28 April 2012 - 09:54 PM
Unless there is a reason you can't (or would prefer to keep) have many more triggers or actions.
A person that should give his input is certainly the_bigg. He's already helped a lot with the TriggerOverride syntax translation (and if that idea is applicable here, one less argument would help a lot).
As for arithmetic, can't you do a "simple" infix to postfix string evaluator?
http://scriptasylum....stfix/index.htm
I guess the problem is variables right? Unless you find a way to bind them to a number or representing the number assignment itself on the expression, it wouldn't be very useful.
Ordering doesn't seem to be enough for more complex expressions.
Can't you hack the second string argument to bind to a variable name instead of a scope? Let the scope be expressed in the function name or as a suffix to the first string?
ReadGlobal("blah", "X", VAR)
ReadLocal("bleh", "Y", VAR)
Eval("X*2 + 3")
Eval("X^3 + Y")
E(_,_)
?
I confess i'm confused about your last example though, and might have lost the plot.
(in the example above, it would be nice to reset the assignments at the end of the block - or if not possible, after the E(), GT() or LT() ).
Keeping the arithmetic functions hidden behind the string form should give you more latitude to add more simple functions like max(), log, % etc, and should allow you to use one of the hundreds of math expression evaluator libraries - so you don't even have to do that.
What about the write operation back to the globals or locals - or stats -? The equality operators won't allow that (but that would be actions i forgot)
Comparing stats/globals/locals is already very good though.
Edited by i30817, 28 April 2012 - 10:48 PM.
#51
Posted 28 April 2012 - 11:11 PM
If its possible, modify some local variables in the script context, do not hack the script itself. You can store the variable inside the script or its runner, but do not modify loaded script lines.
#52
Posted 28 April 2012 - 11:21 PM
I don't intend to modify the script directly. I have changed the way that the triggers are evaluated such that a copy of the trigger is evaluated rather than the triggers themselves. This allows me to modify the copy in any way using local vars. By the way, does GemRB recognise invalid trigger constructions which would spout Unknown trigger errors in the internal dialogue script parser? The constructions are:I haven't seen the current implementation yet. I just know, GemRB stores the script lines in static objects (so caching them is easy and efficient).
If its possible, modify some local variables in the script context, do not hack the script itself. You can store the variable inside the script or its runner, but do not modify loaded script lines.
(S,I,I)
(S,I,I,I)
(S,O,I,I)
(S,O,I,I,I)
(S,S,O)
Edited by Ascension64, 28 April 2012 - 11:25 PM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#53
Posted 28 April 2012 - 11:45 PM
If i've read the arguments right:
ReadGlobal("blah", "X"
ReadLocal("bleh", "Y")
ReadStat("STR", "Z")
Read2DA("HPCLASS", 0, 1, "N") etc.
And write forms.
Calculation engines... there is this .NET thing: http://ncalc.codeplex.com/
but i'm not sure if it's pure c++ (or if it's too much... dates?).
edit: nope, it's C#
As for wine, there is no reason not to try (unless it's just a wrapper over a javascript script engine - that would be bad).
Edited by i30817, 28 April 2012 - 11:54 PM.
#54
Posted 29 April 2012 - 12:04 AM
Edit: P:Point
[x.y].
edit: I'm still not clear if it's going to be possible to use arguments from LOCALS or GLOBALS in functions that don't expect it.
You're only doing it for E() LT() and GT() for now (or ever)?
For instance,
CheckStat(O:Object*,I:Value*,I:StatNum*Stats)
will be able to check a stat against a value in that map (as it can't now, without WEIDU unrolling all possible values?)
If it could be made general - though i suppose this would interfere with GemRB caching Avenger warned about above?
Edited by i30817, 29 April 2012 - 12:26 AM.
#55
Posted 29 April 2012 - 01:30 AM
Say for example, if I wanted to read all these things...
- The global variable DOG
- The value at 2DA table CAT.2DA at point (NearestEnemyOf(Myself).LEVEL + 1).(3)
- The STAT on Myself NUMBEROFATTACKS
- The current game time
- The number of charges on the item Myself has currently equipped on ability number 2
- How many copies of MAGIC_MISSILE I have got left
Strings are a separate story and are fairly easy because it is easy enough to evaluate a string.
Variables are int and int only. P:Point* is expanded into two ints x and y. Note, triggers don't even have a point struct member, only actions do.
The bottom line is sticking to only what is practicable. I am not willing or interest in putting heaps of work into making an 'optimal' solution where you can evaluate some crazy expression like sin(sqrt(7) * log(e) 56). TobEx itself isn't optimal. Optimal solutions should be implemented by BG:EE and co. Hence, I would actually like to hear from people about how exactly they would use variable substitution if it was implemented in any way they please. I need to get a good idea of how complex people will actually use the variable substitution system.
I'll start with a really simple AI example that ignores any scripting conventions for the time being:
//if MyLevel + 6 <= EnemyLevel, runaway 75% of the time IF OR(2) Eval1(Myself, STATS.LEVEL + 6) Eval2(NearestEnemyOf(), STATS.LEVEL) LT(%1, %2) Eval1(Myself, STATS.LEVEL + 6) Eval2(NearestEnemyOf(), STATS.LEVEL) E(%1, %2) THEN RESPONSE #75 RunAwayFrom(NearestEnemyOf(),90) RESPONSE #25 AttackReevaluate(NearestEnemyOf(),90) END
Edited by Ascension64, 29 April 2012 - 01:33 AM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#56
Posted 29 April 2012 - 02:24 AM
IF ReadStat(Myself, STATS.LEVEL, "MyLevel") ReadStat(NearestEnemyOf(), STATS.LEVEL, "EnemyLevel") Eval("MyLevel + 6") Eval("EnemyLevel") OR(2) LT(%1, %2) E(%1, %2) THEN RESPONSE #75 RunAwayFrom(NearestEnemyOf(),90) RESPONSE #25 AttackReevaluate(NearestEnemyOf(),90) END
The crazy expressions should be handled for you by the mathematical evaluator library you choose (if you can bind variables). I suggested you separate the assignment and evaluation and use (unlike your example above), because
1: you might want to use the same variable more than once in 2 expressions (or even the calculated expression)
2: it's easier to read if you do want a expression (granted, it's harder if you don't)
Do you think you can do something that "intercepts any" next trigger (except or or trigger override of course), and replace the first int, the second int etc? It would probably be ideal (not sure if strings arguments would be useful in this context), so people could use E() or CheckStat or whatever.
It also would remove (most) need of write functions, if you can just SetGlobal and derived value (but not sure about stats).
It would probably be useful to make warnings for more Evals than there are arguments in the next one (and to clear the variables binded at the end of the block, so no funny business happens in the next one).
If you can hack the compiler, i suggest making it accept either a placeholder (such as _) or a positional argument like in your example; so that you can match the Eval(s) completely to a trigger and warn if there are less or more than the placeholders.
I never took a compiler class, so i better shut up now.
edit: i mentioned the point because they'd be another kind of "next argument" that would have to be handled specifically if you wanted to allow the
edit 2: you might want to add a trigger that evaluates a boolean expression so you can write this instead of OR, E, LT and GT
Bool would be something that just returns bgscript true for 1 and false for 0 (or whatever the evaluator returns for booleans).
IF ReadStat(Myself, STATS.LEVEL, "MyLevel") ReadStat(NearestEnemyOf(), STATS.LEVEL, "EnemyLevel") Eval("MyLevel + 6 <= EnemyLevel") Bool(%1) THEN RESPONSE #75 RunAwayFrom(NearestEnemyOf(),90) RESPONSE #25 AttackReevaluate(NearestEnemyOf(),90) END
Edited by i30817, 29 April 2012 - 02:58 AM.
#57
Posted 29 April 2012 - 02:35 AM
That would destroy the next trigger. It would take extensive hackery to make a copy of the entire trigger block. So, I cannot do something like this:Do you think you can do something that "intercepts any" next trigger (except or or trigger override of course), and replace the first int, the second int etc? It would probably be ideal (not sure if strings would be useful in this context), so people could use E() or CheckStat or whatever.
IF Assign("STATS.LEVEL", Myself, 1, ) //I can't use more than one string in any trigger Assign("STATS.LEVEL", NearestEnemyOf(), 2) Eval("%1 + 6 <= %2") THEN...What I could possibly do with this is to parse the expression first before passing it to a math expression library, so all the variable substitutions are made before the jit compiler does its work. The assigns will have to map variables to a numerical index (which was something suggested by Galactygon).
No, you will get a warning every single AI update for a trigger!It would probably be useful to make warnings for more Evals than there are arguments in the next one (and to clear the variables binded at the end of the block, so no funny business happens in the next one).
I don't want to hack the compiler. What I do should be completely compatible with the existing GemRB, NearInfinity, and WeiDU implementations of the compiler.If you can hack the compiler, i suggest making it accept either a placeholder (such as _) or a positional argument like in your example; so that you can match the Eval(s) completely to a trigger and warn if there are less or more than the placeholders.
I never took a class.I never took a compiler class, so i better shut up now.
Edited by Ascension64, 29 April 2012 - 02:43 AM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)
#58
Posted 29 April 2012 - 03:10 AM
Edit: oh only one string argument per trigger. So they have to be positional, not nominal to allow reading from maps. Bummer.
But why doesn't this work?
IF Assign("STATS.LEVEL", Myself) //deleted the number... unless it's critical to reassign? Assign("STATS.LEVEL", NearestEnemyOf()) Eval("%1 + 6 <= %2") THEN...If you indeed replace the variables (as you'd have to if you used nominal ones anyway).
Please don't use the % symbol (it's a math operator).
#1, #2 etc should work ok ( i don't think the cardinal set symbol will be used).
or even 'at'
@1, @2
either is a good metaphor
Edited by i30817, 29 April 2012 - 04:01 AM.
#59
Posted 29 April 2012 - 03:35 AM
It seems that you want to use Eval as returning conditional expressions specially?
Because then you'd can't distinguish between failure due to syntax/runtime/divby0 error in the expression and due to the expression returning false (since it's going to be jit-ed or interpreted at runtime).
I'm also wary of how you'd use a int expression later on, unless you want to treat eval like another Assignment? Eg:
IF Assign("STATS.LEVEL", Myself) //saves #1 Eval("1 < 2")//returns true saves #2 (1) Eval("6+ #1")//not boolean only returns false if the expression failed (it won't), saves #3 E(#3, 4) THEN...
My examples above were using nominal variables and positional Eval expression results. And i was not counting on Eval returning anything except if the expression was parsed and computed successfully or not (and the have the possibility of using the result in a later trigger).
I don't think it's a good idea to make Eval return anything except expression parsing/compilation success or failure (don't overload the return). And that it's needed to save the result of eval expressions, not just variables, if they are going to be used in triggers.
I'm not sure what is more confusing, to use the same indexed positions ordering for expressions or to use another indexation
(like #1,#2 for variables and €1, €2 for expressions or something).
Edited by i30817, 29 April 2012 - 03:55 AM.
#60
Posted 29 April 2012 - 04:31 AM
I have to pass the entire Trigger to the EvaluateTrigger() function. In order to do this, I have to replace the values in the Trigger struct with those I want to use to determine if the Trigger returns TRUE or FALSE. At the moment, I get away with permanently defacing the Trigger struct 't' by making a 'tCopy' and directly modifying the elements of 'tCopy'.Could explain with small words why would it destroy the next trigger?
If I am in a trigger block of 3 triggers, of which trigger 1 and 2 substitute some of the variables in trigger 3, I cannot program so that when the engine is looking at trigger 1, it searches ahead for trigger 3 and replaces some values in it. That would destroy trigger 3 and breaks the GemRB static caching system.
Another problem scenario is the one I showed before using the current local copy implementation. The problem is that I want to evaluate a specific 2DA table of 2DA tables, and then use the sub-table to extract the value of a specific evaluated coordinate.
It might look something like this... (let's just say I'm using # to specify something to be evaluated)
IF AssignString("HPCLASS",0,1,/*#1*/1) //#1 = HPCLASS x0 y1 AssignNum("STAT.LEVEL", Myself, /*#2*/2) //#2 = Myself.STAT.LEVEL AssignEval("#2 - 10", /*#3*/3) //#3 = #2 - 10 = Myself.STAT.LEVEL - 10 Eval1("#1[1.#3]") //replace int1 with #1 x1 y#3 = replace int1 with <some table> x1 y(Myself.STAT.LEVEl-10) AssignNum("GLOBALtest", /*#4*/4) //#4 = the value of the GLOBAL variable 'test' Eval2("#4") // replace int2 with #4 = replace int2 with the value of the GLOBAL variable 'test' E(-33,-33) //int1 and int2 get replaced from the above; note: I'm just using a -33 placeholder here, since I have to put some numbers in those places that get substituted THEN RESPONSE #100 DisplayStringHead(Myself,1) // No, I'm sorry, none of them sound familiar. SetGlobal("test","GLOBAL",0) Continue() ENDLooks just as messy as the original code above.
Some rules about the compiler and IDS file:
-I am not allowed to use the same trigger name, so I can't have Assign(I:Num1*) and Assign(I:Num1, I:Num2*). This completely confuses the compiler and the engine
-I am not allowed to use the use more than one string (I said this earlier)
-I am not allowed to use one trigger construction to do two different things if I decide to use the same opcode for it, e.g. I have 0x411A AssignString(S:Name*,I:Num1*,I:Num2*) and 0x411A AssignNum(S:Name*,I:Num1*,I:Num2*). The compiler and the engine cannot tell the difference between these two because it looks up by opcode only. The only way around this for the same opcode, is to specify a MODE in one of the arguments. The alternative is to use different opcodes, which I believe makes things way too complex
Edited by Ascension64, 29 April 2012 - 04:41 AM.
--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.
Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)
Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)