Jump to content


Photo

Modding assistance request and rumination


  • Please log in to reply
46 replies to this topic

#1 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 07:20 AM

I trying to make an item, in this case I'm making magic tomes. I want when player X uses it (single use item) to call a script in baldur.bcs.

Using near infinity, I think I need to create a spell or something that activates when I use the item?

I did look around for tutorials and couldn't find exactly what I was looking for, any ideas?

Looking at the game it seems like maybe the figurines are doing something similar to what I need although I'm not entirely sure because it seems they are destroyed and replaced by something else?   Could be way off base though.

 

The "Complete Scripting Guide" mentions this : "The appropriate blocks in the script can be activated from the item by setting a variable". That would work : how do I set a variable after using an item?

This is my first Weidu mod, so I only think I kinda know what I'm doing and I'm learning.


Edited by smeagolheart, 26 May 2013 - 05:39 PM.


#2 Wisp

Wisp
  • Modder
  • 1353 posts

Posted 09 May 2013 - 07:54 AM

You can set global variables from items and spells by using opcode #265.

With WeiDU, it could be something like this, assuming youritem.itm is complete save for the variable-setting effect:

COPY "yourmod/youritem.itm" override
  LPF ADD_ITEM_EFFECT
    INT_VAR
      opcode = 265
      //other integer vars
    STR_VAR
       resource = yourvar //this must be prefixed
  END



#3 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 08:30 AM

(formatting fail see next post)


Edited by smeagolheart, 09 May 2013 - 08:37 AM.


#4 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 08:35 AM

Thank you!

 

Sorry if this is basic stuff..  So I this would allow me to detect a variable in my script later...  So I can check if it is used (foo=1) or skip if not...

 

tp2

COPY "yourmod/book99.itm" override
  LPF ADD_ITEM_EFFECT
    INT_VAR
      opcode = 265
      //other integer vars
    STR_VAR
       resource = foo //this must be prefixed (huh?)
  END

 

 

 

baf

IF
    //HasItem("book99",Player1)   Want to check Foo instead of this...
    // Global("FOO","GLOBAL",1)
    // Global("S9Kit","GLOBAL",0) maybe don't need this if item gets destroyed after use
THEN
    RESPONSE #100
    //Do stuff
    //SetGlobal("S9Kit","GLOBAL",1)
END

Edited by smeagolheart, 09 May 2013 - 08:55 AM.


#5 Ulb

Ulb
  • Modder
  • 373 posts

Posted 09 May 2013 - 09:14 AM

I'm not sure, but I'd say your tp2 code is missing a few bits (for example, to which value should the variable be set?)

 

Sadly I'm no expert on this and can't tell for sure.

 

However, since it's your own item and not a preexisting one, you could just add that effect via NearInfinity instead of patching it in with WeiDU.

(You can look up FAMIMP.ITM or any other familiar item, all of them employ that opcode to set a global variable.)

 

Your .baf code looks about right.

 

By the way, if you plan to release this mod, you might want to register your personal modder tag/prefix (here) to avoid incompatibilities with other mods, or if you have already done so, use your personal modder tag for variables too.

Also, you might want to think about employing an invisible creature instead of baldur.bcs. Again, I'm no expert but I think it is commonly advised to stay away from baldur.bcs if possible. (Maybe someone with more insight could elaborate on that...)

 

Anyway, good luck with your mod. :)



#6 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 10:47 AM

@ulb, I did register a prefix :)

 

.. and I don't know how to set the variable in the TP2. 

 

I've done some tests and my mod seems to coming along ok.  Not that I have mastered the underlying mechanics of weidu or anything.



#7 Wisp

Wisp
  • Modder
  • 1353 posts

Posted 09 May 2013 - 11:01 AM

In this case, you want to prefix the item book99 and the variable foo. You also need to fill out the values for the remaining relevant variables for ADD_ITEM_EFFECT, such as parameter1 (the value you want the variable set to). The WeiDU readme contains documentation of ADD_ITEM_EFFECT and the IESDP documents the opcode.

The complete item patch could look something like this:
COPY "yourmod/prefix#book99.itm" override
  LPF ADD_ITEM_EFFECT
    INT_VAR
      opcode = 265
      target = 1 // 1 is 'self'; will probably work but may not be optimal
      parameter1 = 1 //assuming you want your thing to happen when the value of the variable is 1
      timing = 1 // instant, may be irrelevant for this opcode
    STR_VAR
       resource = prefix#foo // the name of the variable; 8 characters max
  END
Substitute 'prefix' for your actual prefix.
The remaining function variables either don't need to be specified or are not used, in this particular case.
add that effect via NearInfinity
You should not use NI to alter file structures. There are bugs deep in the program that can result in corrupted files. Altering values is fine.
Using WeiDU to do stuff to your files has advantages over using editors, such as WeiDU code being easier to tweak and significantly lighter on redundant labour.

#8 The Imp

The Imp

    Not good, see EVIL is better. You'll LIVE.

  • Member
  • 5155 posts

Posted 09 May 2013 - 12:15 PM

You should not use NI to alter file structures. There are bugs deep in the program that can result in corrupted files. Altering values is fine.
Using WeiDU to do stuff to your files has advantages over using editors, such as WeiDU code being easier to tweak and significantly lighter on redundant labour.
Well, I prefer editing things with DLTCEP ... it has the added benefit of not needing professional Weidu coders to recheck your weidu code. :P Although I give it to you you are very good at it...
Like say if we go and take the above code without preknown context... I end up with the first line being:
COPY ~Impsmod/ij#book99.itm~ ~override~ 
The sad thing is the item file name can only contain 8 marks with the .itm suffix, the ij#book99.itm having 9 gives a nice kick to the non-profecional coders <insert a bodypart> ... :P

Edited by The Imp, 09 May 2013 - 12:17 PM.

Yep, Jarno Mikkola. my Mega Mod FAQ. Use of the BWS, and how to use it(scroll down that post a bit). 
OK, desert dweller, welcome to the sanity, you are free to search for the limit, it's out there, we drew it in the sand. Ouh, actually it was still snow then.. but anyways.


#9 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 01:12 PM

I think I got enough stuff to test in a couple hours when I get home



#10 Wisp

Wisp
  • Modder
  • 1353 posts

Posted 09 May 2013 - 01:44 PM

it has the added benefit of not needing professional Weidu coders to recheck your weidu code.
If you use standard stuff, it has already been vetted. The demands on the modder are not much different from using NI or DLTCEP. Granted, there are currently some holes in what the prefabbed solutions cover, but adding effects is not one of them.

About the 8-character resref limit: meh. I mentioned it once, sort of.

#11 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 02:15 PM

Ok...  wall of codes..

 

tp2

BACKUP ~\kittomes\backup~
AUTHOR ~Smeagolheart~
VERSION ~v1~

ALWAYS

  INCLUDE ~kittomes/lib/always.tpa~
END
 
BEGIN ~Kit Tomes for Baldur's Gate~

//Compile Dialog

COMPILE ~kittomes\dlg\s9Panver.d~
 
//Extending the Script Files

//EXTEND_BOTTOM ~AR6700.bcs~ ~kittomes\baf\tc6700.baf~
//EXTEND_BOTTOM ~baldur.bcs~ ~kittomes\baf\tomes.baf~
EXTEND_BOTTOM ~AR0015.bcs~ ~kittomes\baf\tomes.baf~

//Copying Creature Files

COPY ~kittomes\bmp\s9panver.bmp~ ~override\s9panver.bmp~
COPY ~kittomes\CRE\s9PANVER.CRE~ ~override\s9PANVER.cre~
  SAY 0x8 ~Panver~
  SAY 0xC ~Panver~

//Copying Items

COPY ~kittomes\itm\S9tome01.itm~ ~override\S9tome01.itm~
  SAY 0x8 ~Book of the Berserker~
  SAY 0xC ~Book of the Berserker~
  SAY 0x50 ~Book of the Berserker: ~ + #25201

/*
COPY ~kittomes\itm\S9tome02.itm~ ~override\S9tome02.itm~
  SAY 0x8 ~Book of the Wizard Slayer~
  SAY 0xC ~Book of the Wizard Slayer~
  SAY 0x50 ~Book of the Wizard Slayer: ~ + #25203

COPY ~kittomes\itm\S9tome03.itm~ ~override\S9tome03.itm~
  SAY 0x8 ~Book of the Kensai~
  SAY 0xC ~Book of the Kensai~
  SAY 0x50 ~Book of the Kensai: ~ + #25204
 
COPY ~kittomes\itm\s9tome04.itm~ ~override\s9tome04.itm~
  SAY 0x8 ~Textbook of the Cavalier~
  SAY 0xC ~Textbook of the Cavalier~
  SAY 0x50 ~Textbook of the Cavalier: ~ + #25206



etc... until




COPY ~kittomes\itm\s9tome30.itm~ ~override\s9tome30.itm~
  SAY 0x8 ~Book of the Barbarian~
  SAY 0xC ~Book of the Barbarian~
  SAY 0x50 ~Book of the Barbarian: ~ + #45869  
*/

// patch in item effects

COPY "kittomes/s9tome01.itm" override
    LPF ADD_ITEM_EFFECT
INT_VAR
    opcode = 265
    target = 1 // 1 is 'self'
    parameter1 = 1
    timing = 1 // instant (possibly irrelevant)
STR_VAR
    resource = S9KITTOM // the name of the variable; 8 characters max
END

/*  justing test one before commiting to all...
COPY "kittomes/s9tome02.itm" override
    LPF ADD_ITEM_EFFECT
INT_VAR
    opcode = 265
    target = 1 // 1 is 'self'
    parameter1 = 2
    timing = 1 // instant (possibly irrelevant)
STR_VAR
    resource = S9KITTOM // the name of the variable; 8 characters max
END

COPY "kittomes/s9tome03.itm" override
    LPF ADD_ITEM_EFFECT
INT_VAR
    opcode = 265
    target = 1 // 1 is 'self'
    parameter1 = 3
    timing = 1 // instant (possibly irrelevant)
STR_VAR
    resource = S9KITTOM // the name of the variable; 8 characters max
END

COPY "kittomes/s9tome04.itm" override
    LPF ADD_ITEM_EFFECT
INT_VAR
    opcode = 265
    target = 1 // 1 is 'self'
    parameter1 = 4
    timing = 1 // instant (possibly irrelevant)
STR_VAR
    resource = S9KITTOM // the name of the variable; 8 characters max
END



etc...



*/

baf

 

//BERSERKER
IF
    Global("S9KITTOM","GLOBAL",1)
THEN
    RESPONSE #100
    ActionOverride(Player1,AddKit(BERSERKER))  //would be better instead of duping player1, player 2 etc to use last used or something? 
    ReallyForceSpellRES("IKitAno2",Myself)   //dunno if this is needed
    SetGlobal("S9KITTOM","GLOBAL",0)
END

//WIZARDSLAYER
IF
    Global("S9KITTOM","GLOBAL",2)
THEN
    RESPONSE #100
    ActionOverride(Player1,AddKit(WIZARDSLAYER))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
END

//KENSAI
IF
    Global("S9KITTOM","GLOBAL",3)
THEN
    RESPONSE #100
    ActionOverride(Player1,AddKit(KENSAI))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
END

//CAVALIER
IF
    Global("S9KITTOM","GLOBAL",4)
THEN
    RESPONSE #100
    ActionOverride(Player1,AddKit(CAVALIER))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
END



etc...

 

 



#12 -smeagolheart-

-smeagolheart-
  • Guest

Posted 09 May 2013 - 03:19 PM

ok it kinda worked..

 

This series of stuff isn't:

 


COPY ~kittomes\itm\s9tome22.itm~ ~override\s9tome22.itm~   SAY 0x8 ~Tome of the Conjurer~   SAY 0xC ~Tome of the Conjurer~   SAY 0x50 ~Tome of the Conjurer: ~ + #9565  // + 9565 not worky and actually the whole description didn't work

 



#13 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 09 May 2013 - 03:20 PM

er.. as I was saying...

 

 

this wasn't working (description)..  

COPY ~kittomes\itm\s9tome22.itm~ ~override\s9tome22.itm~
  SAY 0x8 ~Tome of the Conjurer~
  SAY 0xC ~Tome of the Conjurer~
  SAY 0x50 ~Tome of the Conjurer: ~ + #9565  

 

edit: working now all is well; creating a store to sell the things


Edited by smeagolheart, 09 May 2013 - 06:17 PM.


#14 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 10 May 2013 - 06:34 PM

So *almost* everything is working.  

Need help with this...

 

IF
Global("S9KITTOM","GLOBAL",1)
THEN
  RESPONSE #100
  ActionOverride(Player1,AddKit(BERSERKER))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
END

Is there a way to distinguish who (player 1-6) caused use of the item? (thus setting Global S9KITTOM to 1?) so I can add that to the if condition?

 


#15 Ulb

Ulb
  • Modder
  • 373 posts

Posted 10 May 2013 - 08:17 PM

You could either use an invisible creature and LastSummonerOf(Myself) or, assuming your tomes are somewhat unique, don't have the tomes destroy themselves and check for HasItem(PayerX,"s9tome22") for each party member and then destroy it.

 

By the way, what does IkitAno2 do and where is that spell from?

When I was messing around with AddKit it didn't really work out that well... :P



#16 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 11 May 2013 - 08:49 AM

You could either use an invisible creature and LastSummonerOf(Myself) or, assuming your tomes are somewhat unique, don't have the tomes destroy themselves and check for HasItem(PayerX,"s9tome22") for each party member and then destroy it.

 

By the way, what does IkitAno2 do and where is that spell from?

When I was messing around with AddKit it didn't really work out that well... :P

 

Wouldn't the hasitem method not work?   My tomes set a variable, I'm not sure but isn't it set upon use?   If I don't use it; won't it not set my little variable?   If I do the hasitem won't it just destroy itself as soon as it's put in inventory?

 

I'd not like to summon invisible cretaures as a last resort.   It seems a bit strange that this is so hard to do, determine who in the party used an item.

 

IkitAno2 is from NPCkit script that gives Anomen the berserker kit.   I'm a noob, I don't know what it does but it's in there for now because it's working while I try to figure out other stuff.

 

As I say everything is working in the mod.  I've got tomes that set fighter, priest, mage kits.   They seem to be working.  But right now it only affects player 1, (using the code above).    Originally, I envisioned a quest giver and such, may still go that route possibly having a install option, once I have everything working.



#17 Ulb

Ulb
  • Modder
  • 373 posts

Posted 11 May 2013 - 10:05 AM

The item doesn't destroy itself if you don't want it to.

 

If you want it to destroy itself upon use, you would set it to have exactly one charge and then set the 'when drained' parameter to 'item vanishes'. Set it to item remains or anything else and the item stays.

 

Anyway, checking for the item is obviously an inferior way, at least if there is even the slightest chance of the player having more than one copy of a specific tome.

 

I still don't understand why you are so eager to put your script into baldurs.bcs instead of using an invisible creature, but even so, you could still employ an invisible creature to check which player has used your tome.

 

Simply have the tome set the variable and also spawn an invisible creature (let's call it s9use.cre) and then check for (or better say, use it as a target object) lastsummonerof(''s9use''). (Don't forget to make the creature destroy itself.)

 

Haven't tested it but it should work that way.


Edited by Ulb, 11 May 2013 - 10:09 AM.


#18 smeagolheart

smeagolheart
  • Member
  • 278 posts

Posted 11 May 2013 - 11:08 AM

The item doesn't destroy itself if you don't want it to.
If you want it to destroy itself upon use, you would set it to have exactly one charge and then set the 'when drained' parameter to 'item vanishes'. Set it to item remains or anything else and the item stays.

 

Anyway, checking for the item is obviously an inferior way, at least if there is even the slightest chance of the player having more than one copy of a specific tome.

 

I still don't understand why you are so eager to put your script into baldurs.bcs instead of using an invisible creature, but even so, you could still employ an invisible creature to check which player has used your tome.

 

Simply have the tome set the variable and also spawn an invisible creature (let's call it s9use.cre) and then check for (or better say, use it as a target object) lastsummonerof(''s9use''). (Don't forget to make the creature destroy itself.)

 

Haven't tested it but it should work that way.

 

I'm not so eager to use an invisible creature because it seems like "cheating" to me.   I know that's kind of dumb.   I like to code things a certain way that seem "right" to me and that just doesn't feel right, it feels like a LAST resort.   Maybe that's dumb, sorry!  Basically, I don't want problems with the summon limit and it seems like the wrong way to go about it to me?    

 

 

The code below works, I made the tome not destroyed on use in NI...   The problem is if, as you said, there is only one copy available.  If there is more than one then it gets a problem where it would go in order due to the script (player1, player2, etc).  I was going to have my little tome seller have multiple copies but maybe going to only have one if this is the only way to do this without summoning a creature.  

IF
Global("S9KITTOM","GLOBAL",1)
HasItem("S9TOME01",Player1)
THEN
RESPONSE #100
ActionOverride(Player1,AddKit(BERSERKER))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
ActionOverride(Player1,DestroyItem("S9TOME01"))
END


IF
Global("S9KITTOM","GLOBAL",1)
HasItem("S9TOME01",Player2)
THEN
RESPONSE #100
ActionOverride(Player2,AddKit(BERSERKER))
    ReallyForceSpellRES("IKitAno2",Myself)
    SetGlobal("S9KITTOM","GLOBAL",0)
ActionOverride(Player2,DestroyItem("S9TOME02"))
END

 

::Well, I guess I'll just code up an invisible creature and see how that goes I guess.....   Must be the only way unless I want to only have one at a time it seems.


Edited by smeagolheart, 11 May 2013 - 11:47 AM.


#19 Ulb

Ulb
  • Modder
  • 373 posts

Posted 11 May 2013 - 12:13 PM

The 'summon limit' is (as far as I know) some artificial limit imposed by the summoning spells themselves or their 2da files.

 

Anyway, the invisible creature doesn't even have the same allegiance than the player. You shouldn't run into any problems there.



#20 The Imp

The Imp

    Not good, see EVIL is better. You'll LIVE.

  • Member
  • 5155 posts

Posted 11 May 2013 - 12:22 PM

The 'summon limit' is (as far as I know) some artificial limit imposed by the summoning spells themselves or their 2da files.

Nope, it's hard coded to the bgmain.exe, the thing controlling is the "summoned" gender id the .cre file has assigned to them. So what ever you do, don't assign that to the invisible ... and alswys make sure to self destroy them at the end of their script.


Edited by The Imp, 11 May 2013 - 12:40 PM.

Yep, Jarno Mikkola. my Mega Mod FAQ. Use of the BWS, and how to use it(scroll down that post a bit). 
OK, desert dweller, welcome to the sanity, you are free to search for the limit, it's out there, we drew it in the sand. Ouh, actually it was still snow then.. but anyways.