Jump to content


Photo

TobEx Wish list


  • Please log in to reply
821 replies to this topic

#441 The Cow King

The Cow King
  • Member
  • 19 posts

Posted 14 November 2011 - 10:24 AM

Still, this is not something that has to do with ToBEx .
ToBEx simply corrects a bug.

You're stating that a very high level archer using a +1 attack bow deals more damage for a round using "Critical Strike" than a +5 crossbow using Greater Whirlwind.

Unless you're fighting modded creatures or creatures with missile resistance, there is NOTHING in game that can whistand the damage of a high level archer for a long time.
Dragons, demons, everything dies to an archer, even more so if they use their shot ability that lowers saves and strength.


I only compared the bow performance as a reasoning for making the Non-Ammo Launcher fix an optional component during install (and for the sake of being thorough, countered the arguments against my original point), but since ToBEx can easily be modified even by a casual user (which I very much like), the whole point is moot.

#442 i30817

i30817
  • Member
  • 611 posts

Posted 14 November 2011 - 08:04 PM

I've thought a little bit more and most of my complains could be addressed by a "simpler" fix : returns.

I know there is a workaround for returns in bgscript with bounded objects in triggers (like LastTalkedTo). So if a new trigger int object could be added and a new function to store it (like See). Then the original functions could be used unmodified

Like for instance

Record("somevar", "Global")//always true, or maybe only if the variable is set
LevelGT(VARIABLE)

Even be able to move things around ( with SetGlobal("name", "GLOBAL", VARIABLE)

If this would be possible it would be great because most the functions that take ints could be used with stored memory (though for stats, if you need to use/show the exact value, since some have a large range, storing them directly in globals - the other direction - is still needed).

I'd still like new arithmetic functions like multiplication though.

Edited by i30817, 15 November 2011 - 09:13 PM.


#443 i30817

i30817
  • Member
  • 611 posts

Posted 20 November 2011 - 08:29 PM

Is the suggestion above possible?

*oh, please say yes*

Edited by i30817, 20 November 2011 - 11:12 PM.


#444 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 21 November 2011 - 04:36 PM

I have variable substitution penned down on the to-do list. I am still in the process of working how I can manipulate the script compiler/decompiler as such, which may require much hacking. Like we did with trigger override, I may be able to precede some trigger/action with a Substitute() or something so that I don't have to tamper with the implementation of every single existing trigger/action.

--------------
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)


#445 i30817

i30817
  • Member
  • 611 posts

Posted 21 November 2011 - 05:25 PM

Yay!

#446 The Cow King

The Cow King
  • Member
  • 19 posts

Posted 23 November 2011 - 08:42 PM

Would it be possible to add an extra option in the "Weapon Specialisation Number of Attacks Mod" that only gives the character the extra 1/2 attack per round if he is specialized (or above) in the weapon he is using, but NOT the level based extra attacks?

Right now you can only enable/disable it, so if you're playing a swashbuckler (or using Haer'Dalis) for example, you can only choose between not getting the extra 1/2 APR (for being specialized), or getting extra 1+1/2 APR (even though a thief is not supposed to get the extra attacks based on level, only from being specialized).

I'm sorry if this option is somehow already available, I must be too dumb to see it.

Edited by The Cow King, 23 November 2011 - 08:43 PM.


#447 Galactygon

Galactygon

    Modding since 2002

  • Member
  • 938 posts

Posted 24 November 2011 - 12:01 AM

I have variable substitution penned down on the to-do list. I am still in the process of working how I can manipulate the script compiler/decompiler as such, which may require much hacking. Like we did with trigger override, I may be able to precede some trigger/action with a Substitute() or something so that I don't have to tamper with the implementation of every single existing trigger/action.


It might be worth checking what IWD2 has once IESDP is back up at G3. They have something like this for recalling creatures/locations.

I have an idea about implementation. It goes by the same design principle as NextTriggerObject().
IF
  See(NearestEnemyOf(Myself))
  StoreVariableAs("VARIABLE","LOCALS",1255) // This is really an action inside a trigger. 1255 is an arbritrary number that is used as a marker in the next trigger
  HP(LastSeenBy(Myself),1255) // A select number of triggers can be "transformed" if previous trigger is StoreVariableAs() with a valid marker number
  // A good way to store these variables would be through effects carried on a .cre with a new opcode or the existing StoreLocalVariable opcode. This way they are kept through saved games.
  // TOKENS should be stored the same way.
  NumGT("VARIABLE","LOCALS",59) // If this trigger dne, we need one. I don't know off the top of my head and IESDP is down.
THEN
  RESPONSE #100
    DecrementGlobal("VARIABLE","LOCALS",1)
    SetNextNumToVariable("VARIABLE",89080983) // 89080983 is just a marker value for the next action.
    ApplyDamage([FIRE],89080983)
// Applies the number of hitpoints worth of damage that's stored in the LOCAL "VARIABLE",
// which is equal to the hitpoints of the NearestEnemyOfMyself() minus one
    SetGlobal("VARIABLE","LOCALS",0) // We clear the last value of the variable in case we need it again. Not really necessay.
END

-Galactygon

Edited by Galactygon, 24 November 2011 - 12:03 AM.

Posted Image

#448 i30817

i30817
  • Member
  • 611 posts

Posted 24 November 2011 - 01:41 AM

Edit: the below is the "squeaky clean" option. I just realized what you meant with the numbers, to fool the compiler and decompiler. Simplifying the hacking process.

Yes, it's a good idea/option and allows to get this feature before hacking the compiler. I think i would support it as a intermediate step, because i would like to get my filthy paws on this feature as soon as possible.

However, a point: that number can't be one that is already used in the block. Otherwise, the TobEx runtime would replace the number by the variable since it has no way to differentiate them! This is something to think for the "squeaky clean" compiler implementation.
To implement this this way "only" requires the tobex runtime options below. The scripter would be acting as the compiler to checking that the variables don't clash.






"squeaky clean" option:

If you need more than one int variable, maybe use a growable datastructure.

Record("somevar", "Global", VAR1)<-- the compiler, replaces it by a number not in all of the block, tobex records the number in the datastructure
Record("somevar2", "Global", VAR1)<-- same constant. Compiler needs to use the same number used before, not a new one. Tobex runtime needs to NOT replace VAR1 by the dereference due to the previous record (since it's in a record, it's a store operation, not a read). In fact, if it is forward replacing that variable, it can stop here, since the rest will only get replaced again. (premature optimization, root of all evil, etc)

Record("somevar", "Global", VAR2)<-- new constant
Record("somevar", "Global", VAR3)<-- etc

VARX would need to be recognized as "valid" by the compiler/decompiler. Using numbers allows this, as long as the numbers are not the same as other real numbers in the block, there should be no ill effects.
Constants are only associated to numbers by the compiler in "Record" statements (otherwise undeclared variables would typecheck and cause problems to the script in runtime).

HP(LastSeenBy(Myself),VAR1) <-- compiler references same number.
Tobex runtime (somehow) recognizes the constant, and dereferences it's internal array to inject the number stored by Record before the action/trigger is run.
Maybe when record happens it replaces all forward references in memory in the same block.

HP(LastSeenBy(Myself),VAR6) <-- not recorded variable. Compiler should (ideally) warn of this and exit.
...
END<-- end of the block, compiler clears it's VAR->number mapping, tobex clears the constant datastructure, stops replacing.

(this doesn't appear to need hacking the decompiler, but the numbers would be strange when you used constants before. This already happens with IDS files though)



Aside 1: it's desirable to use the "Record" operation both in the action sequence and the Trigger sequence, with the same name if possible.
That VARXXX variables can be used after the transition from the Trigger to the Actions, is desirable, but not really required (it's just a gotcha if it is not).

Aside 2: Am unsure if Record-as-a-trigger should return always true, or only if the variable was in the LOCALS/GLOBALS/AREA mappings. Also unsure about it's behavior in a OR().

Aside 3: i think it's a little bit silly that if i want to perform arithmetic under a local with this system, i can:
1) move a LOCAL variable to a GLOBAL one by storing it in a variable and using SetGlobal.
2) perform the operation
3) move a GLOBAL variable to a LOCAL one by storing it in a variable and using SetGlobal.

Silly isn't it? Maybe there could be a shortcut?

Regardless, multiply, abs, subtraction and maybe modulo would be nice to have - integer division might be dangerous (X/0) - but it's also nice...



This was my attempt at a "formal" specification. I'm sure Ascension64 already thought of all of this and more
:)

Edited by i30817, 25 November 2011 - 02:50 AM.


#449 FlameWing

FlameWing
  • Member
  • 41 posts

Posted 24 November 2011 - 07:31 AM

I don't know if it has been suggested (since the search function seems to return no hits regardless of terms used, and there are 23 pages in the thread), but: currently, TobEx handles mage school restrictions by using its own custom 2da file, MGSRCREQ.2DA. I think that it would be better to implement mage schools and kits by using K_M_*.2DA instead, so as to be consistent with kits for other classes. Doing it this way would allow mods to add player-selectable mage kits that do not overwrite mage school specialists (and they would work with WeiDU's ADD_KIT command).

Another, related, suggestion (which is quite probably a lot trickier and much more work): add similar support for multi-classes [i.e., K_(FM|FC|FT||FMT|MT|CM|CT|FD|FMC|CR)_*], sorcerers (K_S_*) and monks (K_MN_*) (barbarians being out, of course, because they are a fighter kit). The support for player-selectable sorcerer and monk kits would probably be of interest for more people than the multi-classes; the support for the multi-classes is, or course, thinking on my own mod.

#450 i30817

i30817
  • Member
  • 611 posts

Posted 24 November 2011 - 03:26 PM

BTW, flamewing, any chance of merging your work with level1npcs?

#451 phordicus

phordicus
  • Member
  • 212 posts

Posted 24 November 2011 - 06:04 PM

I desire that the Stoneskin effect be completely externalized. While getting rid of the full avatar coloring is lovely, I'd like to be able to tie other effects to the Stoneskin such as just coloring the skin or using a different/no portrait icon.
Druid Kit Enhancements 1.0 (requires Dispel Magic fix, whether ToBEx's or Taimon's)

#452 Andrea C.

Andrea C.
  • Modder
  • 464 posts

Posted 25 November 2011 - 02:16 AM

I'd like to be able to tie other effects to the Stoneskin such as just coloring the skin


How cool would that be?!? :woot:

#453 FlameWing

FlameWing
  • Member
  • 41 posts

Posted 25 November 2011 - 08:46 AM

BTW, flamewing, any chance of merging your work with level1npcs?

It is actually level 1 NPCs that needs to be updated for my mod, not the other way around. It fails to look for kits from multi-classes as viable options, and even if this behavior is corrected, it would have to work with my mod and set the correct specific value for the multi-kit for things to work.

Hm. I need to check with the GemRB folks to see if their implementation of kits works as the original game does or else my mod won't work on it.

Now, please lets not derail this topic further; any further question regarding my mod is better asked in its topic.

#454 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 25 November 2011 - 03:14 PM

Would it be possible to add an extra option in the "Weapon Specialisation Number of Attacks Mod" that only gives the character the extra 1/2 attack per round if he is specialized (or above) in the weapon he is using, but NOT the level based extra attacks?

Right now you can only enable/disable it, so if you're playing a swashbuckler (or using Haer'Dalis) for example, you can only choose between not getting the extra 1/2 APR (for being specialized), or getting extra 1+1/2 APR (even though a thief is not supposed to get the extra attacks based on level, only from being specialized).

I'm sorry if this option is somehow already available, I must be too dumb to see it.

Wouldn't you just disable the mod? ToB already appears to implement the extra 1/2 attack for specific weapon specialisations if you have 2 or more stars in said weapon. Only paladins, fighters, and rangers by default in vanilla get the level-based specialisation bonus. Thieves in vanilla shouldn't get the level-based bonus.

re: variable substitution

If I want to leave the compiler alone as much as possible, I must strictly adhere to the arg types of each trigger/action, so I can't do HPLT(LastSeenBy(Myself),<somevar>), since <somevar> must be stored in memory as an integer. ApplyDamage() is similarly as difficult, because I have to tamper with the implementation of ApplyDamage() itself to recognise that that massive number that you put there should search for a variable index rather than use the actual number itself as damage.
The way I think this would have to work is to have a preceding trigger/action such as Evaluate(I:*Argument, O:*ObjectType, S:*StringType, S:*StringType2, I:*IntegerType), which would specify:

Argument: which data structure you want to evaluate (this will have to be based on the BCS scripting AC and TR structure)
ObjectType: the object data you want to replace with (if you want to substitute objects, probably redundant)
StringType: the text you want to replace with, supposedly the name of a variable
StringtTpe2: the text you want to replace with 2, supposedly the context of a variable (GLOBAL, LOCALS, etc.)
IntegerType: the integer you want to replace with

Since this is still fairly limited, I would presume you want to try and evaluate certain stats into the next trigger/action, so I may need an extra I:*Opcode and specifically define what each opcode fetches.

I don't know if it has been suggested (since the search function seems to return no hits regardless of terms used, and there are 23 pages in the thread), but: currently, TobEx handles mage school restrictions by using its own custom 2da file, MGSRCREQ.2DA. I think that it would be better to implement mage schools and kits by using K_M_*.2DA instead, so as to be consistent with kits for other classes. Doing it this way would allow mods to add player-selectable mage kits that do not overwrite mage school specialists (and they would work with WeiDU's ADD_KIT command).

Another, related, suggestion (which is quite probably a lot trickier and much more work): add similar support for multi-classes [i.e., K_(FM|FC|FT||FMT|MT|CM|CT|FD|FMC|CR)_*], sorcerers (K_S_*) and monks (K_MN_*) (barbarians being out, of course, because they are a fighter kit). The support for player-selectable sorcerer and monk kits would probably be of interest for more people than the multi-classes; the support for the multi-classes is, or course, thinking on my own mod.

This seems rather moot, since I don't plan to add support for extra mage kits, and unlikely for sorcerer and monk kits as well. I would really have to investigate how much work it really is to add such support, since mage kits are treated very specifically in code in many places.

I desire that the Stoneskin effect be completely externalized. While getting rid of the full avatar coloring is lovely, I'd like to be able to tie other effects to the Stoneskin such as just coloring the skin or using a different/no portrait icon.

Can't you just tag extra effects onto the stoneskin spell?

--------------
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)


#455 i30817

i30817
  • Member
  • 611 posts

Posted 25 November 2011 - 03:53 PM

re: variable substitution

If I want to leave the compiler alone as much as possible, I must strictly adhere to the arg types of each trigger/action, so I can't do HPLT(LastSeenBy(Myself),<somevar>), since <somevar> must be stored in memory as an integer.

Yes. That's why me and Galactygon were talking about using integers as markers. It would still be nice to have some compiler hacking (to disallow the marker integers being the same as another ones used in the same block), but would still allow it to be used before that typecheck was done.
As for it being stored in memory as a integer, i was assuming that the argument list of each action/trigger gets stored the same way in memory, and that the whole block is stored. So when you'd see a substitution function (like my Record example), you'd "scan forward", checking the arguments lists of the subsequent actions/triggers to replace the markers in memory.

ApplyDamage() is similarly as difficult, because I have to tamper with the implementation of ApplyDamage() itself to recognise that that massive number that you put there should search for a variable index rather than use the actual number itself as damage.
The way I think this would have to work is to have a preceding trigger/action such as Evaluate(I:*Argument, O:*ObjectType, S:*StringType, S:*StringType2, I:*IntegerType), which would specify:


If i understand correctly, you're going with another approach than the "scanning forward", of executing/evaluating the internal function with the arguments you give them, like reflection in java.
That's nicer if you can do it since it's probably faster than scanning forward the rest of the block, and requires much of the same jumps in memory, without needing to modify the compiler.

Accessibility would be a problem though, what with:


Argument: which data structure you want to evaluate (this will have to be based on the BCS scripting AC and TR structure)

I assume this is the numbers in the action/triggers in IESDP? As in:

22 MoveToObject(O:Target*)
?

ObjectType: the object data you want to replace with (if you want to substitute objects, probably redundant)

StringType: the text you want to replace with, supposedly the name of a variable
StringtTpe2: the text you want to replace with 2, supposedly the context of a variable (GLOBAL, LOCALS, etc.)
IntegerType: the integer you want to replace with


I don't understand how this would deal with things that take multiple arguments; ie, if for some reason i really really want to use

140 GiveItemCreate(S:ResRef*,O:Object*,I:Usage1*,I:Usage2*,I:Usage3*)
with the Integer arguments all from globals i set previously.

Or is the IntegerType argument, actually IntegerPosition aka the offset in the argument list of the next trigger/action that will get replaced on exec?

I'd like the final solution to be able to deal with things like moving a int from a global to a local & vice-versa for instance (because of the "only globals can do arithmetic" stupidity).

VarOverride("variable", "LOCALS", 3)//third position in the next trigger
SetGlobal("variabletosum", "GLOBALS", -1)

You appear to want to take the variable substitution beyond simple "LOCALS/GLOBALS/AREA" stored-memory ints, into objects and strings too? I don't object, if there is a elegant way to do it, but i really didn't think of it, since strings can't be stored in bgscript (objects can already be stored with "see", but it would be nice to expand that true).


Since this is still fairly limited, I would presume you want to try and evaluate certain stats into the next trigger/action, so I may need an extra I:*Opcode and specifically define what each opcode fetches.

I assumed reading stats into memory was a different problem - since that really has no equivalent right now in bgscript. Though, it makes sense - if you're going to be able to read from the GLOBALS/LOCALS/AREA mappings, why not from the stats too.

Eh, expand [Set]Global with a new mapping "STATS" for the current object, like LOCALS - that'd be pretty slick.

SetGlobal("LEVEL", "STATS", 1)
SetGlobal("XP", "STATS", 0)
I don't know if they are all ints... i think so?

BTW, i think you lost a opportunity to name your DialogueSetGlobal just "Set"
and Global just "Get" or "Is" since the Global part of the name is misleading, and already specified anyway by the second argument. Not that anyone is using them yet... just a thought.

Edited by i30817, 25 November 2011 - 04:54 PM.


#456 The Cow King

The Cow King
  • Member
  • 19 posts

Posted 25 November 2011 - 04:10 PM

Thieves in vanilla shouldn't get the level-based bonus.


Well I've always considered that as a "bug", or something the devs just didn't take into account with the introduction of swashbuckler, black blade of disaster, Haer'Dalis etc.. seeing the proficiency text doesn't state anything about non-fighter classes not receiving the extra 1/2 attack.

How does it work in P&P?

#457 FlameWing

FlameWing
  • Member
  • 41 posts

Posted 25 November 2011 - 04:24 PM

This seems rather moot, since I don't plan to add support for extra mage kits, and unlikely for sorcerer and monk kits as well. I would really have to investigate how much work it really is to add such support, since mage kits are treated very specifically in code in many places.

If you want, I can help with that, as I have a lot of experience reverse-engineering stuff. I would only need a few pointers to get up to speed on how you have been doing it so any work I do can be easily integrated with yours.

#458 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 25 November 2011 - 05:02 PM

HPLT(LastSeenBy(Myself),<somevar>), since <somevar> must be stored in memory as an integer.

The issue with this is that HPLT expects (O:*Object,I:Amount). I can't place a string in place of the integer Amount without creating a completely new trigger. The issue with using an indexed variable is you have to make sure that that you aren't using the indexed variable twice in some trigger/action that uses multiple integer variables. Also, it is not generalisable to string variables.

If i understand correctly, you're going with another approach than the "scanning forward", of executing/evaluating the internal function with the arguments you give them, like reflection in java.
That's nicer if you can do it since it's probably faster than scanning forward the rest of the block, and requires much of the same jumps in memory, without needing to modify the compiler.

Yes, the approach is to scan forward and replace the appropriate struct with the appropriate value, meaning that I would only have to implement one new trigger and one new action, rather than modifying the implementations of all triggers/actions.

I assume this is the numbers in the action/triggers in IESDP? As in:

22 MoveToObject(O:Target*)
?

No, this is the BCS compiled TR and AC structures. One might have to know these or have them available for reference, but I pulled this straight from IESDP. The description will need refining for the specific order of struct members in the engine, but I will explain in the TobEx Reference.

Trigger
This format is slightly hairier. First, it has a "trigger ID", which is an ID in the TRIGGER.IDS file. Essentially, each trigger corresponds to a call to one of the functions listed in there. See the section on parameters for details.

TR (newline)
trigger ID from TRIGGER.IDS (no newline)
1 integer parameter (no newline)
1 flags dword (no newline):
bit 0: negate condition flag (if true, this trigger is negated -- i.e. success=>false, failure=>true)
1 integer parameter (no newline)
1 integer. Unknown purpose.
2 string parameters (no newline)
1 object parameter (newline)
TR (newline)

Action
This format is slightly hairier. First, it has a "action ID", which is an ID in the action.IDS file. Essentially, each action corresponds to a call to one of the functions listed in there. See the section on parametersfor details.
AC (newline)
action ID from ACTION.IDS (no newline)
3 object parameters (newlines after each)
1 integer parameters (no newline)
1 point parameter (formatted as two integers x y) (no newline)
2 integer parameters (no newline)
2 string parameters (no newline)
AC (newline)


I don't understand how this would deal with things that take multiple arguments; ie, if for some reason i really really want to use

140 GiveItemCreate(S:ResRef*,O:Object*,I:Usage1*,I:Usage2*,I:Usage3*)
with the Integer arguments all from globals i set previously.

Or is the IntegerType argument, actually IntegerPosition aka the offset in the argument list of the next trigger/action that will get replaced on exec?

I'd like the final solution to be able to deal with things like moving a int from a global to a local & vice-versa for instance (because of the "only globals can do arithmetic" stupidity).

VarOverride("variable", "LOCALS", 3)//third position in the next trigger
SetGlobal("variabletosum", "GLOBALS", -1)

You appear to want to take the variable substitution beyond simple "LOCALS/GLOBALS/AREA" stored-memory ints, into objects and strings too? I don't object, if there is a elegant way to do it, but i really didn't think of it, since strings can't be stored in bgscript (objects can already be stored with "see", but it would be nice to expand that true).

You can call Eval() multiple times, to replace multiple arguments in the next trigger/action.

Let's say, in complete theoretical sense, you can do:
Eval(<stringArg1>, "MYVARIABLE") //next first str argument will be replaced with MYVARIABLE
Eval(<intArg1>, NearestOf(Myself), <statHP>) //next int argument replaced by the nearest amount of HP (would have to implement a system for deriving the stat)
//you would replace <Arg> by the index of the TR/AC struct that corresponds to the one you want to replace
SetGlobal(" /*stringArg1*/ ", "LOCALS", 0 /*intArg1*/)
In-game this would set MYVARIABLE (LOCALS) to the HP of the Nearest object.

I assumed reading stats into memory was a different problem - since that really has no equivalent right now in bgscript. Though, it makes sense - if you're going to be able to read from the GLOBALS/LOCALS/AREA mappings, why not from the stats too.

Eh, expand [Set]Global with a new mapping "STATS" for the current object, like LOCALS - that'd be pretty slick.

SetGlobal("LEVEL", "STATS", 1)
SetGlobal("XP", "STATS", 0)
I don't know if they are all ints... i think so?

That's bad. Stats shouldn't be set that way without breaking heaps of things. However, retrieving stats should be fine.
But preferably, you want to GetGlobal and actually do something with it, say, sum up all the char attributes (STR, DEX, WIS, INT) etc., and see if it adds up to say 70, and if not prompt for some extra attributes (in some L1NPC mod or some other).

How does it work in P&P?

I'll defer this to the P&P experts.

If you want, I can help with that, as I have a lot of experience reverse-engineering stuff. I would only need a few pointers to get up to speed on how you have been doing it so any work I do can be easily integrated with yours.

Sure, I do it rather crappily since I use OllyDbg to maintain by DB rather than IDA Pro. Check your PM.

Edited by Ascension64, 25 November 2011 - 06:24 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)


#459 i30817

i30817
  • Member
  • 611 posts

Posted 25 November 2011 - 05:44 PM

Ok, i mistunderstood the part about the "reflection approach".

You're scanning forward with a generalized approach for all argument types instead.

Question: will the "Eval"-ed variables persist across more than one action/trigger call of the scanning or does it actually stops at the first action/trigger that is not a Eval?

Because i'd prefer if it stopped - it's less error prone, and probably more efficient IMO (if more tedious if you're trying to use the same variable twice).


If you're not using positions but the arguments names as markers (i assume from the action.ids and trigger.ids files?) then we need to be sure that there are no functions that have argument names repeated no? For example (invented):
140 GiveItemCreate(S:ResRef*,O:Object*,I:Usage*,I:Usage*,I:Usage*)

And, trying to discuss it with you: this will require people to actually memorize the names of the arguments, instead of just the types... They'll be constantly checking IESDP when they need to use this feature. Just some devil advocacy...


This is all assuming that your example
Eval(<stringArg1>, "MYVARIABLE") //next first str argument will be replaced with MYVARIABLE
Eval(<intArg1>, NearestOf(Myself), <statHP>) //next int argument replaced by the nearest amount of HP (would have to implement a system for deriving the stat)
//you would replace <Arg> by the index of the TR/AC struct that corresponds to the one you want to replace
SetGlobal(" /*stringArg1*/ ", "LOCALS", 0 /*intArg1*/)
Is using the action.ids for it's mapping of <intArg1> to position. If not, i'm not really understanding how the runtime can replace that without modifying the compiler since that information doesn't appear to be in the compiled form of the TR and AC struct you showed in your last post.

Or is it some predefined names?
String_1 is The first string your scan finds,
String_2 is The second string your scan finds, etc.
That would work too.

Pity about setting stats (though reading them is very useful still)

Edited by i30817, 25 November 2011 - 06:06 PM.


#460 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 25 November 2011 - 06:35 PM

[quote name='i30817' date='26 November 2011 - 11:44 AM' timestamp='1322271870' post='527813']
You're scanning forward with a generalized approach for all argument types instead.

[quote]Question: will the "Eval"-ed variables persist across more than one action/trigger call of the scanning or does it actually stops at the first action/trigger that is not a Eval?

Because i'd prefer if it stopped - it's less error prone, and probably more efficient IMO (if more tedious if you're trying to use the same variable twice).[/quote]Yep, like TriggerOverride, it will only apply to the first trigger/action that is not Eval(). Also, ideally it will replace and be lost every time the script block runs. However, if you decide to save the number into a variable, then it will save every time as well. Unfortunately, for triggers, variables you set would keep updating themselves. I'm sure I can work a way around this so that they would only be set once, and this should be configurable.

[quote]If you're not using positions but the arguments names as markers (i assume from the action.ids and trigger.ids files?) then we need to be sure that there are no functions that have argument names repeated no? For example (invented):
140 GiveItemCreate(S:ResRef*,O:Object*,I:Usage*,I:Usage*,I:Usage*)[/quote]
The exact BCS correlations are:
Trigger correlation: TR opcode, i, dwFlags, i2, u22, sName1, sName2, o TR
Action correlation: AC opcode, oOverride, oObject, oTarget, i, pt.x, pt.y, i2, i3, sName1, sName2 AC
So if I wanted to replace I:Usage* in GiveItemCreate(), I would use something like Eval(1, "MYVALUE", "GLOBAL"). Since i is at index 4 of the Action structure. For S:ResRef* that would be 9.

[quote]And, trying to discuss it with you: this will require people to actually memorize the names of the arguments, instead of just the types... They'll be constantly checking IESDP when they need to use this feature. Just some devil advocacy...[/quote]I will put in the TobEx Modder Reference. Alternatively, we can defer this into an .IDS so you can use labels instead.

Edited by Ascension64, 25 November 2011 - 07:45 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)