Jump to content


Photo

Increasing existing affects in characters


  • Please log in to reply
143 replies to this topic

#1 i30817

i30817
  • Member
  • 611 posts

Posted 29 October 2011 - 10:13 AM

Let's say i have a item that increases a stat by +1, for instance, the backstab modifier. Any way to have repeated uses of it add 1+1 to the current affect (so there aren't dozens of extra affects when i finish my cheating rampage)?

It can be done in shadowkeeper i know, but i'd like to do it in the item itself, to not need to go out of the game.

#2 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 29 October 2011 - 11:40 AM

I'm not sure exactly what you're asking, but you'd need to make the item effect cumulative, which is type (parameter 2) of 0 in the effect. Use a modding tool like NI or DLTCEP to do it - I'm not sure SK is sophisticated enough to do that.

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


#3 i30817

i30817
  • Member
  • 611 posts

Posted 29 October 2011 - 12:02 PM

I'm using using opcode 263 (backstab) with param 1 set to 1 and param 2 set to 0 already.

Using a item that grants this repeatedly adds a new effect to the save game with another +1 to backstab; and the savegame now has 2 effects.

If, instead, i edit the savegame on SK and modify param 1 to 2 it appears to increase the backstab modifier by 1 (to 2).

What i'm asking is if the engine has a way to add +1 to a granted effect in the character without scripting so i don't have duplicated effects in the savegame
(but i have little hope).

Edited by i30817, 29 October 2011 - 12:05 PM.


#4 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 29 October 2011 - 02:45 PM

You probably added it with timing mode 1 (permanent) or something similar. You should always use timing mode 2 (while equipped) for equipped item effects.

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


#5 i30817

i30817
  • Member
  • 611 posts

Posted 29 October 2011 - 04:04 PM

But it's not a equiped effect. I'm trying to make item that would allow you to play a multiclass thief without the thief class. For instance, a f/m/c + t abilities (if possible with level progression).

Permanent effect is right. I guess a script is the right solution eventually.

Edited by i30817, 29 October 2011 - 04:05 PM.


#6 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 29 October 2011 - 04:18 PM

If it's not equipped, then what kind of item is it? If it's something like a per-use potion, then I would just set the backstab stat to an absolute value (rather than a cumulative one). The char you're using on doesn't have thief abilities anyway (wouldn't make much sense). But an equipped item makes a bit more sense. You could even add it to an item they would otherwise have equipped.

Aurora has some vaguely similar items (lockpicks, mask of evasion, etc.). But they're not for non-thieves generally and not as cheaty :P.

Edit: also, you probably don't want permanent timing mode anyway - for PC/NPC effects you want timing mode 9 (permanent after death) unless you want the effects to be wiped if the NPC dies and gets resurrected.

Edited by Miloch, 29 October 2011 - 04:19 PM.

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


#7 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 04:05 AM

Per use, but eventually i want something a little more complex. My idea is to make either a item or a location where if you aren't a thief, you can level up as a assassin (since bhaal was the god of assassins) in almost all respects except innates and HLAs.
It would use the thief level up table and remove the exp needed for level+1 it reaches a threshold and use a dialog to modify thief abilities.

Stealth and detect traps and pickpocket are usable by AI script (i already am), open locks can use knock, detect traps is the only troublesome part.

If TobEx implements removing the check for class in the game shortcuts for class abilities, it could be slicker yet.

I want my F/M/C/T! (no semi-multi clerics is not enough, due to not being compatible with scripts).

Edited by i30817, 30 October 2011 - 04:05 AM.


#8 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 06:17 AM

Stealth and detect traps and pickpocket are usable by AI script (i already am), open locks can use knock, detect traps is the only troublesome part.

Do you mean remove traps?

Let me do some looking I did something in regards to traps and locks for thieves. It seemed to work fairly easy...


Here is a thought. a singular item, something all classes can wear, that when equipped gives the boosts of a level 1 thief. Have script code that when the character levels up in main class triggers a spell which removes and replaces the item with an identical item that when equipped gives level 2 thief skills and repeat with each level up. Of course it can be done via dialog too rather than just in script...

I've done something similar in regards to swapping items so I could probably be able to steer you in the right direction if that is something you'd like to try.

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#9 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 06:56 AM

Sure. I'd like that.

Though using a "when equipped" item seems to me like it is not very flexible due to table adjustments from various mods - like level 40 rules.

Or does it take into account that?

Edited by i30817, 30 October 2011 - 06:57 AM.


#10 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 07:09 AM

I found my remove traps stuff. idk how well you can read wiedu code. but here you go. it dynamically creates the script code and in the code below adds it to a party ai script that was previously installed by my mod.

If you can't figure out what it is doing, I'll put the mod up where you could download it, install it and then you can look at the script in NI or something and check out the thief action blocks. Perhaps after seeing what it does, it'll shed some light on what the code below does. It's been a while so I can't exactly recall, I think tho it looks for floor trigger traps, container traps and door traps.

OUTER_SPRINT ie_file ~ar~
ACTION_IF (FILE_EXISTS_IN_GAME ~FW2600.are~) THEN BEGIN
 OUTER_SPRINT ie_file ~fw~
END

//--This is the actual script block
<<<<<<<< inlined/thief_hk_trap.baf
IF
HotKey(%F2%)
Global("%cont_var%","LOCALS",0)
ActionListEmpty()
!Exists([ENEMY])
AreaCheck("%area%")
!Disarmed("%trigger%")
Range("%trigger%",10)
CheckStatGT(Myself,1,TRAPS)
THEN
RESPONSE #100
SetGlobal("%cont_var%","LOCALS",1)
RemoveTraps("%trigger%")
Continue()
END
>>>>>>>>

//-- this just asked the user about which hot key they wanted to use to initiate the search for traps
PRINT @16
ACTION_READLN ~hk~
OUTER_WHILE ((%hk% != 1) AND (%hk% != 2)) BEGIN
 PRINT @5
 PRINT @16
 ACTION_READLN ~hk~
END
OUTER_SPRINT F2 ~D~
ACTION_IF (%hk% = 1) THEN BEGIN
 PRINT @17
 ACTION_READLN ~F2~
 OUTER_WHILE !(~%F2%~ STRING_COMPARE_REGEXP ~[A-Z]~ =0) BEGIN
  PRINT @5
  PRINT @17
  ACTION_READLN ~F2~
 END
END

PRINT @27

//-- this begins the code which searches for the trapped objects in area files and stores necessary variables and appends to the script after each
OUTER_PATCH ~this_is_not_a_variable~ BEGIN
 FOR ("i1" = 0x0; "i1" < 0x100; "i1" += 0x1) BEGIN
  WRITE_BYTE 0x0 "i1"
  READ_ASCII 0x0 ~c~ (0x1)
  SPRINT EVALUATE_BUFFER ~0t%i1%~ ~%c%~
 END
END
COPY_EXISTING_REGEXP GLOB ~^%ie_file%.*\.are$~ ~override~
 PATCH_IF (SOURCE_SIZE > 0x11b) THEN BEGIN
  SPRINT area ~%SOURCE_RES%~
  READ_SHORT 0x5a "tc"
  READ_LONG  0x5c "to"
  READ_LONG  0x70 "co"
  READ_SHORT 0x74 "cc"
  READ_LONG  0xa4 "dc"
  READ_LONG  0xa8 "do"
  FOR ("i1" = 0x00; "i1" < ("tc" * 0xc4); "i1" += 0xc4) BEGIN
   SPRINT ~trigger~ ~~
   SPRINT ~co_name~ ~~
   READ_SHORT ("to" + "i1" + 0x68) "trap_detect"
   READ_SHORT ("to" + "i1" + 0x6a) "trap_disarm"
   READ_SHORT ("to" + "i1" + 0x6c) "trapped"
   READ_SHORT ("to" + "i1" + 0x20) trig_type
   READ_LONG ("to" + "i1" + 0x60) flag
   PATCH_IF ( (%trig_type% = 0)
          AND ("trap_detect" < 0x64)
          AND ("trap_disarm" < 0x64)
          AND ((%flag% BAND 0b1000) = 0b1000)
          AND (("trapped" & 0x01) = 0x01) ) THEN BEGIN
    FOR ("i2" = 0x00; "i2" < 0x20; "i2" += 0x01) BEGIN
     READ_BYTE ("to" + "i1" + "i2") "char"
     READ_ASCII ("to" + "i1" + "i2") "char2" (1)
     PATCH_IF (~%char%~ = 32) AND (~%char2%~ STRING_COMPARE_REGEXP ~ ~ =0) BEGIN
      SPRINT ~char2~ ~_~
     END
     PATCH_IF (%char% != 0) BEGIN
      SPRINT ~co_name~ ~%co_name%%char2%~
     END
     PATCH_IF (("char" = 0x00) AND ("i2" = 0x00)) THEN BEGIN
      SET "i2" = 0x20
     END
     ELSE
     PATCH_IF (("char" = 0x00) AND ("i2" > 0x00)) THEN BEGIN
      READ_ASCII ("to" + "i1" + 0x00) ~trigger~ ("i2")
      SPRINT ~cont_var~ ~ab_%area%_%co_name%~
      INNER_ACTION BEGIN
       EXTEND_BOTTOM ~abparty.bs~ ~inlined/thief_hk_trap.baf~
        EVALUATE_BUFFER
      END
      SET "i2" = 0x20
     END
    END
   END
  END
  FOR ("i1" = 0x00; "i1" < ("cc" * 0xc0); "i1" += 0xc0) BEGIN
   SPRINT ~trigger~ ~~
   SPRINT ~co_name~ ~~
   READ_SHORT ("co" + "i1" + 0x2c) "trap_detect"
   READ_SHORT ("co" + "i1" + 0x2e) "trap_disarm"
   READ_SHORT ("co" + "i1" + 0x30) "trapped"
   READ_SHORT ("co" + "i1" + 0x26) "lock_dif"
   READ_LONG ("co" + "i1" + 0x28) "flag"
   PATCH_IF ( ("trap_detect" < 0x64)
          AND ("trap_disarm" < 0x64)
          AND (("trapped" & 0x01) = 0x01) ) THEN BEGIN //trapped only
    FOR ("i2" = 0x00; "i2" < 0x20; "i2" += 0x01) BEGIN
     READ_BYTE ("co" + "i1" + "i2") "char"
     READ_ASCII ("co" + "i1" + "i2") "char2" (1)
     PATCH_IF (~%char%~ = 32) AND (~%char2%~ STRING_COMPARE_REGEXP ~ ~ =0) BEGIN
      SPRINT ~char2~ ~_~
     END
     PATCH_IF (%char% != 0) BEGIN
      SPRINT ~co_name~ ~%co_name%%char2%~
     END
     PATCH_IF (("char" = 0x00) AND ("i2" = 0x00)) THEN BEGIN
      SET "i2" = 0x20
     END
     ELSE
     PATCH_IF (("char" = 0x00) AND ("i2" > 0x00)) THEN BEGIN
      READ_ASCII ("co" + "i1" + 0x00) ~trigger~ ("i2")
      SPRINT ~cont_var~ ~ab_%area%_%co_name%~
      INNER_ACTION BEGIN
       EXTEND_BOTTOM ~abparty.bs~ ~inlined/thief_hk_trap.baf~
        EVALUATE_BUFFER
      END
      SET "i2" = 0x20
     END
    END
   END
  END
  FOR ("i1" = 0x00; "i1" < ("dc" * 0xc8); "i1" += 0xc8) BEGIN
   SPRINT ~trigger~ ~~
   SPRINT ~co_name~ ~~
   READ_SHORT ("do" + "i1" + 0x6c) "trap_detect"
   READ_SHORT ("do" + "i1" + 0x6e) "trap_disarm"
   READ_SHORT ("do" + "i1" + 0x70) "trapped"
   READ_LONG ("do" + "i1" + 0x28) "flag"
   PATCH_IF ( ("trap_detect" < 0x64)
          AND ("trap_disarm" < 0x64)
          AND ((%flag% BAND 0b1000) = 0b1000)
          AND (("trapped" & 0x01) = 0x01)) THEN BEGIN
    FOR ("i2" = 0x00; "i2" < 0x20; "i2" += 0x01) BEGIN
     READ_BYTE ("do" + "i1" + "i2") "char"
     READ_ASCII ("do" + "i1" + "i2") "char2" (1)
     PATCH_IF (~%char%~ = 32) AND (~%char2%~ STRING_COMPARE_REGEXP ~ ~ =0) BEGIN
      SPRINT ~char2~ ~_~
     END
     PATCH_IF (%char% != 0) BEGIN
      SPRINT ~co_name~ ~%co_name%%char2%~
     END
     PATCH_IF (("char" = 0x00) AND ("i2" = 0x00)) THEN BEGIN
      SET "i2" = 0x20
     END
     ELSE
     PATCH_IF (("char" = 0x00) AND ("i2" > 0x00)) THEN BEGIN
      READ_ASCII ("do" + "i1" + 0x00) ~trigger~ ("i2")
      SPRINT ~cont_var~ ~ab_%area%_%co_name%~
      INNER_ACTION BEGIN
       EXTEND_BOTTOM ~abparty.bs~ ~inlined/thief_hk_trap.baf~
        EVALUATE_BUFFER
      END
      SET "i2" = 0x20
     END
    END
   END
  END
 END
BUT_ONLY_IF_IT_CHANGES
COPY ~override/abparty.bs~ ~scripts/abparty.bs~

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#11 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 07:21 AM

Sure. I'd like that.

Though using a "when equipped" item seems to me like it is not very flexible due to table adjustments from various mods - like level 40 rules.

Or does it take into account that?

It could depending upon how you create it. If you make it via DLTCEP or NI, probably not. But if you make a template in DLTCEP or NI, weidu can be used to modify each of the effects based upon the value read in the necessary ids/2da files and then save it for each level. while weidu can also modify a script or dialog to use the necessary spell(s) to remove the old and add in the new. In this manner it could support whatever table adjustments are available at mod install time.

On my website linked below in my signature is a small mod which gives support to the off hand when swapping weapons. The stuff needed to remove and create items that a character has is in there. Feel free to take a look at it.

Edited by Sasha Al'Therin, 30 October 2011 - 07:23 AM.

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#12 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 08:02 AM

Reading WeiDU is like reading hieroglyphics.

Wouldn't that approach slow down the game due to the party AI code checking thousands of traps and trap variables?

The other mod i've seen that does something similar (altered knock) uses a summoned invisible cre, that is destroyed at the end of the block.

Obvious problem: the cre is not facing where the char is facing. But always at a 140º angle.

Edited by i30817, 30 October 2011 - 08:04 AM.


#13 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 08:34 AM

In fact, something like this at the end of each AI file:

IF
HotKey(%F2%)
ActionListEmpty()
CheckStatGT(Myself,1,TRAPS)
!Exists([ENEMY])
THEN
RESPONSE #100
SetGlobal(currentAI, "nameofaifile");
ChangeAIScript(trap_rem_script,DEFAULT)
END

and at the end of trap_rem_script
IF
True()
THEN
RESPONSE #100
ChangeAIScript(GetGlobal(currentAI),DEFAULT)
END


Wouldn't be faster?

Forgive the obvious errors.

PS: anyone know how would

ChangeAIScript(somthing,DEFAULT)
Continue()

react at the end of a script file? End the current round, and only use the new file in the next round? Continue from the top of the new file in the current round? Try to continue from the equivalent position in the new file (and possibly fail hard)?

Edited by i30817, 30 October 2011 - 08:41 AM.


#14 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 10:07 AM

you are on the right track actually

the code I posted is older and I've learned a few things since.

yes you can change the ai script but best to use it inside of an ActionOverride tho

IWD let me do ChangeAIScript on all the players but BG1 wouldn't change scripts for the protagonist without using ActionOverride. Not sure how BG2 does it so an ActionOverride would probably be safest to include

Check the script slots on characters in a save game. You don't want to change an existing script. There are several that are empty.

Override is used for joinable NPC scripts it's where banters and such get fired from
Class is used for player assigned party AI scripts
Race is typically empty
General is typically empty
Default is where the dplayer2 or dplayer3 scripts are located

my party AI script that I've been tweaking from my IWD version uses class & race slots

Here is my recommendation... tweaking my previous posted code to output a new script based on area file. I'd prolly name 'em abtXXXX.bcs where XXXX is the # of the area file that it will be associated with. And then add something like...
IF
AreaCheck(ar%XXXX%)
Global("abthief%XXXX%","LOCALS",0)
THEN
RESPONSE #100
ActionOverride(Myself,ChangeAIScript("abt%XXXX%",GENERAL))
SetGlobal("abthief%XXXX%","LOCALS",1)
END
IF
!AreaCheck(ar%XXXX%)
!Global("abthief%XXXX%","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("abthief%XXXX%","LOCALS",0)
END
to the bottom of the dplayer scripts or a party AI script that you'll require to be used. Still adds a number of blocks, but instead of hundreds only 2 per area that has a trap. If no trap, then no script UNLESS you want to put other script blocks for other thief type actions onto the area specific creature scripts then a script tied to each area could be made. of course %XXXX% would be replaced by weidu with the number of the area file.

The global variable needs to be there to prevent the character from repeatedly changing the ai script cause that block would always return true. Also having the global variable means that a second block must be present to reset it so that the character can change the script back should they re-enter the area multiple times.


obviously if you are looking for BGT & TuTu usage of your mod then there would have to be additional variables involved since the area file names are all different between games

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#15 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 10:58 AM

"The global variable needs to be there to prevent the character from repeatedly changing the ai script cause that block would always return true"
Why not just use the Hotkey trigger as a user validation? Disarming traps is not so common as all that that they need to be automated. Or would this be too slow still?

Now a aside: I've found that modal actions are impossible to use in most scripts unmodified. A thief in stealth will try to attack a seen enemy losing stealth for instance.
But this is the only way i found of actually using the thief abilities granted in shadowkeeper without a thief.

So, even if executed earlier, such a "complete" script would be probably undermined by the char AI - so there is no actual point in trying to accept all AI, so i might as well just make a custom one to actually use the abilities (just use the "ActionOverride(Myself,ChangeAIScript("traps%",GENERAL))" trick not to test every trap in the main script.

I'm sad about this (but the programmatic alternative is insane, decompile ai scripts, find actions that break stealth and add !StateCheck(Myself,STATE_NOT_VISIBLE) to their triggers).

So i'm most interested in a way to generate the list of traps conditions, run it without a creature (seems like the ActionOverride&ChangeAIScript and a hotkey would work), and modify a item so it grants the bonuses of a thief per level (probably use a dialog to distribute the points).
Thinking also of stealing experience on "level up", but not sure that would work ok (of if there is a better way).

Edited by i30817, 30 October 2011 - 11:23 AM.


#16 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 11:25 AM

Then again, a component to disarm traps automatically or on key press / pickpocket on key press could possibly be used with other AI mods if put in BALDUR.BCS...

Edited by i30817, 30 October 2011 - 11:29 AM.


#17 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 12:20 PM

"The global variable needs to be there to prevent the character from repeatedly changing the ai script cause that block would always return true"
Why not just use the Hotkey trigger as a user validation? Disarming traps is not so common as all that that they need to be automated. Or would this be too slow still?

I wasn't ruling out using the hotkey button. the hotkey button would be used to get the character to find traps. the global variable part with the change ai script is so that the scripts could be properly changed. If the hotkey were to do that, then the new script would fail to run because the hotkey trigger had already been flushed. Note that unless you use a timer, the hotkey is in memory only until the first valid block or the script restarts at the top. UNLESS you were hotkeying the script change and then with another hotkey the actual thief action.

Of course the changing of ai script is only to help reduce script bloat, because if all those remove trap script blocks were in baldur.bcs it would bog down the game like crazy. Not to mention that baldur.bcs is not directly tied to any one character and as such would have to use ActionOverride with a specific Object like Player1, etc... and then since any regular thief as well as a character given external thief abilities could use these remove trap blocks, there would need to be SIX blocks for each trap - one block per party member.

Using a script that applies directly to the character allows you to use Myself as the Object and thusly cover all party members that are using the script(s) and reducing overall script block count as well as parsing time.

Now a aside: I've found that modal actions are impossible to use in most scripts unmodified. A thief in stealth will try to attack a seen enemy losing stealth for instance.
But this is the only way i found of actually using the thief abilities granted in shadowkeeper without a thief.

True. Even regular thieves have their modal actions stopped by script actions. ActionListEmpty() can help too on some of those blocks. Depends on the kind of behavior you want the character to have.

So, even if executed earlier, such a "complete" script would be probably undermined by the char AI - so there is no actual point in trying to accept all AI, so i might as well just make a custom one to actually use the abilities (just use the "ActionOverride(Myself,ChangeAIScript("traps%",GENERAL))" trick not to test every trap in the main script.

probably...

I'm sad about this (but the programmatic alternative is insane, decompile ai scripts, find actions that break stealth and add !StateCheck(Myself,STATE_NOT_VISIBLE) to their triggers).

Not as problematic as you may think... but there will always be something that will break the action at some point. modal states like find traps are best done when standing still. yeah you can walk while searching, but not in the trailing formation and when moving about the 'seen' area changes and new script blocks could become true...

So i'm most interested in a way to generate the list of traps conditions, run it without a creature (seems like the ActionOverride&ChangeAIScript and a hotkey would work), and modify a item so it grants the bonuses of a thief per level (probably use a dialog to distribute the points).
Thinking also of stealing experience on "level up", but not sure that would work ok (of if there is a better way).

Not sure what you mean by without a creature... Only other place that scripts could be changed not on a creature is the area file... Certainly don't think you want to mess with that.
You can't generate the traps in game, has to be done outside of the game and then applied in game. whether it is done dynamically via weidu to catch mod added stuff or hard set by hand to only deal with original game material...
If you are going to have a dialog file allow the player to distribute points (such as pick-lock, open lock, find trap, and stealth abilities) then those stat modifier effects can not be on an equipped item. If you were making those values before hand, then yes they could be on an item. But if they will be set inside a dialog file, then you'll need to have a spell triggered which uses the opcode for using an external .eff file. The external .eff file would be where the stat gets modified at, but then you will probably end up back where you started with multiple effects of the same type.... Otherwise when the mod is installed you could ask the player to decide how many points in each ability to automatically apply at level up and then use that value to build the equipped effects on the template item...

I must say you've gotten my mind going on this topic... got some ideas rolling in my head :P may just try some of this out for myself at some point...

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#18 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 01:43 PM

"The global variable needs to be there to prevent the character from repeatedly changing the ai script cause that block would always return true"
Why not just use the Hotkey trigger as a user validation? Disarming traps is not so common as all that that they need to be automated. Or would this be too slow still?

I wasn't ruling out using the hotkey button. the hotkey button would be used to get the character to find traps. the global variable part with the change ai script is so that the scripts could be properly changed. If the hotkey were to do that, then the new script would fail to run because the hotkey trigger had already been flushed. Note that unless you use a timer, the hotkey is in memory only until the first valid block or the script restarts at the top.

I misunderstood your intent. I thought you only wanted to use those trap references to use the "remove traps" not "find traps".

"remove traps" can adequately be used without interference from AI scripts with RemoveTraps(O:Trap*) - not being modal - and it's the only thing that actually requires the trap name.

I'd put in the Hotkey trigger in BALDUR.BCS (always available) and put in the trap list in another script for performance reasons

The script would remove the trap if appropriate, then redirect again (in the same block) to "nill" or the previous script if any, to stop executing.

("open locks" and "pickpocket" because they aren't modal, aren't interfered with by AI scripts, so maybe they can go into BALDUR.BCS too - and open locks can be omitted anyway, considering knock exists)

OTOH, since "FindTraps()" is a modal action, that is one of the things i scripted into my AI code (along with stealth).


Separating things this way should allow one to use other AI scripts and still get those non modal abilities (and if those other AI scrips don't check for class, but only ability, they would work too).

UNLESS you were hotkeying the script change and then with another hotkey the actual thief action.

No, it was just redirect, doing the trapremoval, then go back at once.

What i'm not sure if the redirect strategy is possible without having party AI turned on. It's a minor issue, but i'd prefer not having to record which script is running then have to restore it. Is there any of the script slots that is consistently empty and runs always (like BALDUR.BCS)?




Also, i'm not quite sure if "find traps" will detect secret doors and detect illusions too... I mean, there is no "Detect Illusions" in the actions and the button serves both functions in the GUI, but there is a "DetectSecretDoor(O:Object*)" action, that is obviously worse than FindTraps() since it takes a argument. Need to test it.

Edited by i30817, 30 October 2011 - 02:24 PM.


#19 i30817

i30817
  • Member
  • 611 posts

Posted 30 October 2011 - 02:08 PM

Well, forgot something pretty important about BALDUR.BCS.

It there's no current creature running it doh. So it will have to be one of the other slots.

Any one of those runs even with the party AI turned off and is empty?

"Override, Area, Specifics, Class, Race, General and Default"

Edited by i30817, 30 October 2011 - 02:22 PM.


#20 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 30 October 2011 - 02:32 PM

What i'm not sure if the redirect strategy is possible without having party AI turned on. It's a minor issue, but i'd prefer not having to record which script is running then have to restore it. Is there any of the script slots that is consistently empty and runs always (like BALDUR.BCS)?

No. when party AI button is off I believe override is the only running script slot for a party member. Tho you could append to whatever script is in the override slot with weidu, but you'd have to check and see if the given character's override script gets changed between pre-join and while in party... don't think any do, but then you never know....

Oh if you want to open locks etc... I've another version that does that too along with removing traps. ^^ Also got one that opens up the container for you but it does some wonky map screen shifting to get to the container and I think it also bypasses the container script that would call guards... can't remember but there was some reasons why I stopped using that part even tho I left it in the tp2...

Separating things this way should allow one to use other AI scripts and still get those non modal abilities (and if those other AI scrips don't check for class, but only ability, they would work too).

Exactly, E-series while good didn't always work well since multi-class/dual class and bards all had to use the big ass everything in one script. being able to break 'em down and change script between class functions makes it quicker and allows you to use script leveling to ensure that attack spell blocks which return true are used before making the mage equip sling :P

Idk if you have IWD but you can take a look at the party ai script on my website which I made for IWD (still got a long way to go for full spell support, was putting 'em in as spells became available)


Oh OH OH!!! you can use baldur.bcs for the hotkey...

IF
Hotkey(F)
Global("ab_thiefactions","GLOBAL",0)
!GlobalTimerNotExpired("ab_thieftimer","GLOBAL")
THEN
RESPONSE #100
SetGlobal("ab_thiefactions","GLOBAL",1)
SetGlobalTimer("ab_thieftimer","GLOBAL", ONE_TURN)
END
IF
Global("ab_thiefactions","GLOBAL",1)
GlobalTimerExpired("ab_thieftimer","GLOBAL")
THEN
RESPONSE #100
SetGlobal("ab_thiefactions","GLOBAL",0)
END
then you'd put the global check for 1 and that the timer is active on each script block which needs to be accessed via the hotkey. You'll need to read up on the global timer stuff to make sure the right one gets used in the right spot but that gives ya a general idea. One block via hotkey turns on the actions via a global and the timer allows multiple actions to take place for the duration of the timer. The second block will reset the global and thus turn off the actions once the timer expires....

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm