Skip to content

Infinity Engine Scripting Discussion

2»

Comments

  • BelanosBelanos Member Posts: 968


    3) Confirmed: this does work for multiple item abilities of the same item, if you follow the blueprint above. I:Abil entry--start with 0 for ability 0, 1 for 1, etc. Just like with UseWeaponAbility

    So it is possible to get a character to use a special ability on a weapon? I was under the impression that it wasn't. I recall beating my head against the wall trying to get one of them, Nalia I believe, to use the Haste ability on some sword in BG2, but I could never get it to work. IIRC, it's some Short Sword that you come across in BG2. And reading up on it I got the impression that it simply wasn't possible, that the function was broken. Or is that something that has been improved upon with the EE games?

  • BelanosBelanos Member Posts: 968
    edited January 2014
    lansounet said:

    About AddStoreItem() I'm pretty sure this was added for BP2 so only implemented in BG2EE.

    Yes. As I mentioned, it's in the Action IDS file for BG2EE, but not for BGEE. I'm really hoping it gets added, it can be a very handy trigger for anyone hoping to add an item in the game, or for creating some randomization.
    lansounet said:

    No idea how it works but my guess would be that it requires that you opened that store at least once.

    That sort of defeats the purpose IMO. Why would you want to create an item after you've already been to a merchant? Of course it allows for flexibility with their inventory, but it would be much more useful if it occurred before going to see someone.
    lansounet said:

    Containers and their items are stored in ARE files so predefined. However there is some randomness with the RNDTRE01-05 items that create a random item based on 2DA tables, when that is decided I don't know, I guess 1st time the area is loaded.

    What about items that are created randomly through a script? I'm trying to set up random placement of the containers in the game, including the Ammo Belt. Will those be predefined or will they only appear when I open a container, or enter an area? I'm wondering whether I should include an area check before the game creates the items, so I don't end up finding the last bag in the very last container of the game, when it's not going to do me much good. I tried using the "Opened" trigger, but apparently that only works with doors.

  • lansounetlansounet Member Posts: 1,182
    Randomization at play time or install time? I haven't followed this thread entirely but it seems you're trying to reproduce the Item Randomizer mod? I believe it does swap items between ARE files at install times following some tables (area name, container name, item name).

    For play time randomization through scripts I'm not sure how this would be handled but you have to be in the same area to interact with anything (container/door/trap/creature) usually so area script or one that goes through the whole game (BALDUR.BCS / DPLAYERX.BCS ?) would be best to use.

    I'll make an exemple of how I'd do (try) it within BG2 :

    4 different randomization paths decided at game start (We'll use those to randomize new location of the item) : EXTEND_BOTTOM AR0602.bcs with something like
    IF
    Global("RandomVar","GLOBAL",0)
    RandomNum(4,1)
    THEN
    RESPONSE #100
    SetGlobal("RandomVar","GLOBAL",1)
    END

    IF
    Global("RandomVar","GLOBAL",0)
    RandomNum(4,2)
    THEN
    RESPONSE #100
    SetGlobal("RandomVar","GLOBAL",2)
    END

    IF
    Global("RandomVar","GLOBAL",0)
    RandomNum(4,3)
    THEN
    RESPONSE #100
    SetGlobal("RandomVar","GLOBAL",3)
    END

    IF
    Global("RandomVar","GLOBAL",0)
    RandomNum(4,4)
    THEN
    RESPONSE #100
    SetGlobal("RandomVar","GLOBAL",4)
    END


    I want to move Helm of Balduran (whatever random path has been selected at game start) from starting dungeon which is already added via ar0602 script and a 2DA list of items using this action : ActionOverride("Shelf1",TakeItemListPartyNum("IMPORT03",1)) so I EXTEND_BOTTOM that script again with
    IF
    GlobalGT("RandomVar","GLOBAL",0)
    Global("BalduranHelmMoved","GLOBAL",0)
    THEN
    RESPONSE #100
    ActionOverride("Shelf1",DestroyItem("HELM07"))
    SetGlobal("BalduranHelmMoved","GLOBAL",1)
    END


    Now it's removed and can reappear in 4 different areas (say firkraag dungeon, spellhold, temple ruins or nalia's keep), each of these areas correspond to 1 of the randomization paths so each of these area script I would extend_bottom as usual with
    IF
    Global("RandomVar","GLOBAL",X)
    Global("BalduranHelmMoved","GLOBAL",1)
    Global("BalduranHelmRelocated","GLOBAL",0)
    THEN
    RESPONSE #100
    ActionOverride("NAMEOFTHECONTAINEROFYOURCHOICE",CreateItem("HELM07"))
    SetGlobal("BalduranHelmRelocated","GLOBAL",1)
    END


    And voila the item has been moved randomly but only as you visit the area. This is probably not very elegant/efficient scripting but this is my quick take on it.
    Also the biggest issue I see with this is that it only works when the order you visit these areas is predetermined, like in my example you can't visit the other areas before the starting dungeon so it works without issues, but say you want to move the Hammer of thunderbolts from sewer illithids lair you have to go in there for the item to be removed then eventually backtrack to areas you have potentially already visited to make it appear in a container
  • horredtheplaguehorredtheplague Member, Developer Posts: 186
    Belanos said:


    3) Confirmed: this does work for multiple item abilities of the same item, if you follow the blueprint above. I:Abil entry--start with 0 for ability 0, 1 for 1, etc. Just like with UseWeaponAbility

    So it is possible to get a character to use a special ability on a weapon? I was under the impression that it wasn't. I recall beating my head against the wall trying to get one of them, Nalia I believe, to use the Haste ability on some sword in BG2, but I could never get it to work. IIRC, it's some Short Sword that you come across in BG2. And reading up on it I got the impression that it simply wasn't possible, that the function was broken. Or is that something that has been improved upon with the EE games?

    Quite possible, in all 3 games. This function existed all along, just buried in code. The short sword you're thinking of is Arbane's Sword, and I believe I already have it working in the BP Series scripts.

    I never tested a weapon with UseItemExt, but UseWeaponAbility has been in use in BP for many years as well as vanilla scripts. It's how you get a winter wolf or a hell hound to choose between breath and bite (e.g.).

  • BelanosBelanos Member Posts: 968
    edited January 2014
    lansounet said:

    Randomization at play time or install time?



    Neither actually. I'm hoping I can create a random creation of an item at the time that a container is actually opened. Or failing that, at the time my party enters an area.
    lansounet said:

    I haven't followed this thread entirely but it seems you're trying to reproduce the Item Randomizer mod?



    No, I'm trying to add items that don't already exist in the game, namely containers. I've never really cared for the way these games handled containers, they're too uber IMO. So I've created a series of them, including the Ammo Bag, which have less capacity but there will be one for each party member. I've based the capacity on the value of a single stack within a characters inventory, with the exception of the Ammo Bag, which will have the same capacity as all of a character's ammo slots combined. I've also added a Minor Bag of Holding for each party member which will hold up to 10 items that aren't covered by the other bags. But I want them to be earned, not just handed to them by placing them all in some merchant's inventory.

    This is the script I've come up with:


    IF
    RandomNum(12,1)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,2)
    Global("BagOfHoldingA","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag1A",0,0,0) // Minor Bag of Holding
    SetGlobal("BagOfHoldingA","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,3)
    Global("AmmoBagA","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag2A",0,0,0) // Ammo Belt
    SetGlobal("AmmoBagA","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,4)
    Global("PotionCaseA","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag3A",0,0,0) // Potion Case
    SetGlobal("PotionCaseA","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,5)
    Global("GemBagA","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag4A",0,0,0) // Gem Bag
    SetGlobal("GemBagA","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,6)
    Global("ScrollCaseA","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag5A",0,0,0) // Scroll Case
    SetGlobal("ScrollCaseA","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,7)
    Global("BagOfHoldingB","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag1B",0,0,0) // Minor Bag of Holding
    SetGlobal("BagOfHoldingB","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,8)
    Global("AmmoBagB","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag2B",0,0,0) // Ammo Belt
    SetGlobal("AmmoBagB","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,9)
    Global("PotionCaseB","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag3B",0,0,0) // Potion Case
    SetGlobal("PotionCaseB","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,10)
    Global("GemBagB","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag4B",0,0,0) // Gem Bag
    SetGlobal("GemBagB","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,11)
    Global("ScrollCaseB","Global",0)
    Global("CandleKeepBag","Global",0)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("a2zBag5B",0,0,0) // Scroll Case
    SetGlobal("ScrollCaseB","Global",1)
    SetGlobal("CandleKeepBag","Global",1)
    END

    IF
    RandomNum(12,12)
    Global("CandleKeepBag","Global",0)
    HPGT(Player1,27)
    HPGT(Player2,27)
    HPGT(Player3,27)
    HPGT(Player4,27)
    HPGT(Player5,27)
    HPGT(Player6,27)
    THEN
    RESPONSE #100
    SetGlobal("CandleKeepBag","Global",1)
    RESPONSE #100
    CreateItem("potn52",0,0,0) // Potion of Extra Healing
    SetGlobal("CandleKeepBag","Global",1)
    END



    The bag globals prevent any more than a single one of each type from being created, and the area globals prevent any more than a single bag of any type from appearing in a specific area. Or prevent anything at all from being created. I've been attaching them to any container in the game that doesn't have an existing trap script, with a separate global for each area the container is in. Needless to say that this is proving to be a very time consuming method, but it works at least. This is the one I'm using for Candlekeep at the beginning of the game.

    But I'm not sure how the game is going to create these new items, whether it happens on the fly or whether they're predefined at the beginning of a new game. I would prefer that they eventually appear in the early stages of a game, though not too early, when they'll do the most good. So I'm wondering whether I should add an area check condition, like InActiveArea[(PC]), to prevent anything from being created when a game begins. Or I may have to create a global in an area script and apply that, as I'm not sure if InActiveArea will work on a trap script. I know Opened doesn't, at least not on containers. Apparently it only applies to doors.
    Post edited by Belanos on
  • BelanosBelanos Member Posts: 968
    edited January 2014



    Quite possible, in all 3 games. This function existed all along, just buried in code. The short sword you're thinking of is Arbane's Sword, and I believe I already have it working in the BP Series scripts.

    I never tested a weapon with UseItemExt, but UseWeaponAbility has been in use in BP for many years as well as vanilla scripts. It's how you get a winter wolf or a hell hound to choose between breath and bite (e.g.).

    Well damn. Come to think of it though, I don't believe I ever tried UseWeaponAbility. I've always worked with SelectWeaponAbility. Which works fine for swapping slots, but I could never get anyone to use any special abilities that were attached to their weapons. I'll have to remember to try that one. What I've been doing is creating AI scripts for each individual character in my party, and I really wanted Nalia to use the Sword of Arbane's Haste ability from time to time. But I could never get it to work.

    BTY, the changes I've made to my scripts based on your tips is definitely paying off. Using the interrupt toggle and the Attack action has made them much more responsive, and I've been noticing that Dynaheir is a bit more prone to using spells, rather than just firing away with her sling. She even seems quite fond of that Wand of Magic Missiles I gave her. I had never seen a character using any sort of wand before. I actually had to create some conditions for her so she didn't end up wasting all the charges on Gibberlings, or other low-end creatures.

    Also, you mentioned that it was beneficial having HPGT("target",0) in the targeting parameters. I've added !StateCheck("target",State_Really_Dead). Does that work as well? And what is the difference between State_Dead and State_Really_Dead?

  • horredtheplaguehorredtheplague Member, Developer Posts: 186
    edited January 2014
    I just tested this very simple script for Arbane's Sword, and it worked:


    IF
    HasItemEquiped("SW1H27",Myself) // Arbane's Sword +2
    !StateCheck(Myself,STATE_HASTED)
    THEN
    RESPONSE #100
    UseItemExt("SW1H27",Myself,SLOT_WEAPON,1) // Arbane's Sword +2
    DisplayStringHead(Myself,3320) // Arbane's Sword +2
    END

    I switched the sword between SLOT_WEAPON0 and SLOT_WEAPON1 on the PC, and it worked for both slots. Hasted individual. Incidentally I could not get SelectWeaponAbility (sorry, was reciting from memory earlier) to work with UseItem or even Attack(Myself), for this spell. I originally had it as the top action in this script (w/ a SmallWait) but it wasn't even needed. Nice stuff. :)
  • BelanosBelanos Member Posts: 968


    I switched the sword between SLOT_WEAPON0 and SLOT_WEAPON1 on the PC, and it worked for both slots.

    Well this is interesting. I've been having a few characters like Minsc switch to a crushing weapon using SelectWeaponAbility Slot_Weapon1, where I put a crushing weapon, when they see creatures like skeletons, rather than using EquipMostDamagingMelee. I've also been telling my ranged characters to use magic ammo for creatures that are immune to normal weapons. Not having to specify which slots to use would make this much more versatile.

  • BelanosBelanos Member Posts: 968
    Is it possible to have a character drop an item from their slots into their inventory? It would be the opposite of FillSlot. So say I gave Minsc a collection of different weapons and have them stored in his inventory. Depending on a situation he would fill a weapon slot I'd leave empty for him with a special weapon, like a +3 vs Undead for instance, then after that particular situation was over he'd dump that weapon back into his inventory and go back to using his regular weapons.
  • horredtheplaguehorredtheplague Member, Developer Posts: 186
    I think you misunderstood. I was able to use the Spelllike power of Arbane's sword (Haste) with UseItemExt. Supposedly it still works even if you use 0 SLOT_AMULET as a default. After seeing this I'm more inclined to believe it. I don't think you can use it for weapon switching however. I didn't try, but see what happens.


    The only way I can think of, is if you are talking a specific item by name. Otherwise, it's not possible. (Perhaps possible, but what it would theoretically take is surely not practical). Even with a named item, you have to actually drop it on the ground, then pick it up (DropItem/PickUpItem).

  • lansounetlansounet Member Posts: 1,182
    @Belanos Alright I see what you're trying to do now (at least I think so).

    You should take a look at this page and other RNDxxxx.2DA tables to see how to create lists of random items and then fill your bag's store files with RNDxxxx.ITM. I was doubtful it would work in stores but it actually does... except that the random item is only generated when taken out of the inventory : in store and inventory it will appear invisible and named "invalid", once dropped to the ground (still in inventory screen) they turn into a random item from the table :/
  • BelanosBelanos Member Posts: 968
    edited January 2014
    lansounet said:


    You should take a look at this page and other RNDxxxx.2DA tables to see how to create lists of random items and then fill your bag's store files with RNDxxxx.ITM.

    Thanks, but I'm not really interested in doing that. It's the bags themselves I'm after, they don't need to have anything inside of them. I did take a look at the RNDITM tables in the 2DA files. It doesn't seem all that difficult to create a new random item. That might be useful for the scripts themselves in fact. I've since expanded the scope of my container script. I've decided that there's a few items that are too powerful to have knowing exactly where they are, so I'm going to randomize them. So far I have the Ring of Wizardry you can find outside the Friendly Arm Inn, and the Ankheg armour you can find in that farmer's field in Nashkell. As well as the skill boosting books you can find. I'll now have to hunt around for all those items instead of heading straight for them.

    I did a bit of testing and it looks like the items created by the scripts are generated along with the area they're in, when I first access it. They definitely don't change after the area has been loaded. I also found that the regular items seem to be pregenerated at the start of the game. When I tried to remove the Ankheg armour from it's container, the game kept crashing every time I tried to enter Nashkell. Though it didn't have a problem with a test script I created.

  • BelanosBelanos Member Posts: 968
    lansounet said:



    I want to move Helm of Balduran (whatever random path has been selected at game start) from starting dungeon which is already added via ar0602 script and a 2DA list of items using this action : ActionOverride("Shelf1",TakeItemListPartyNum("IMPORT03",1)) so I EXTEND_BOTTOM that script again with

    IF
    GlobalGT("RandomVar","GLOBAL",0)
    Global("BalduranHelmMoved","GLOBAL",0)
    THEN
    RESPONSE #100
    ActionOverride("Shelf1",DestroyItem("HELM07"))
    SetGlobal("BalduranHelmMoved","GLOBAL",1)
    END


    I discovered an easier way of doing this part. Attach this to the trap script of the container where the helmet is.

    IF
    OnCreation()
    THEN
    RESPONSE #100
    DestroyItem("HELM07")
    END


    As soon as the party enters the area, the trap script will run and remove the helmet. I ran into a problem with the game crashing because I had removed an item from a container, but doing it this way fixed the problem. No item, no crash.


  • BelanosBelanos Member Posts: 968
    All right, I've got it. The reason Opened() didn't work to create the items was because I didn't have the "Is Trapped" flag set on the container. I decided to take a closer look at the container functions and came across that part. As soon as I set it for Yes, the items started being created. So I'll be able to have everything spawn "on the fly" whenever a container is opened. Man, this turning out to be a lot of work. Now I'll have to go through all my containers again and set that flag.
Sign In or Register to comment.