Jump to content


Photo

BG1 coding tutorial


48 replies to this topic

#31 Miloch

Miloch

    Barbarian

  • Modders
  • 4720 posts
  • Gender:Male
  • Location:At Large

Posted 06 December 2010 - 06:48 PM

Edit: I notice there are two GLOBALs called before the CreateCreature command. I don't find them created or set anywhere. Are they created when called, or do I need to create the GLOBALs somewhere?

Game variables are assumed to be 0 if they haven't been set. All I can think is maybe the CRE isn't getting copied properly, or maybe BG1 doesn't like it for some reason, but I doubt it.

Also, this code makes no sense at all to me:
COPY_EXISTING ~ar2301.bcs~ ~override~
				~ar4809.bcs~ ~override~
				~ar0705.bcs~ ~override~
It does nothing, except possibly fail if the scripts don't exist. Whereas EXTEND_BOTTOM will automatically create the scripts if they don't exist, so you don't need the COPY_EXISTING. In BG1, the area scripts should be set in the .are files, so that shouldn't be a problem either.
Mod Contributions
Aurora (new release!) * BG1 NPC * Gnomes * Haiass * Level 1 NPCs * Lost Items * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * In Progress: Adjusted Portraits * DSotSC (Tutu)
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * PSPad Highlighters * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Wherefore do ye toil; is it not that ye may live and be happy? And if ye toil only that ye may toil more,
when shall happiness find you?" -H.P. Lovecraft, The Quest of Iranon

#32 grogerson

grogerson

    Blithering Idiot and BG1 Tweaks Scavanger

  • Members
  • 758 posts
  • Gender:Male
  • Location:Near Salt Lake City, UT

Posted 10 December 2010 - 08:49 PM

Thanks for the explanation, Miloch. The tp2 is updated.

I finally got the bard to spawn in an unmodded game. I was running Zed's area check emulation, and when I removed it he appeared. I tried it in a modded game (with the area check emulation running) and no spawn occurs. I'll do some more checking, see if installing before the emulation to see if it will run if it's before the emulation in the baf file or not. If the former, then I can still incorporate it, but if the latter, then there may be a problem to work out.

Edit: It seems my character spawning is blocked by the area check emulator somehow - if it's after the code in the bcs file. It runs fine if before. It's something that may need looking into. Can someone validate this result, or get the opposite result?

Edited by grogerson, 11 December 2010 - 10:07 AM.

It is an outrage that they should be commonly spoken of as Intellectuals. This gives them the chance to say that he who attacks them attacks Intelligence. It is not so. . . . It is not excess of thought but defect of fertile and generous emotion that marks them out. Their heads are no bigger than the ordinary: it is the atrophy of the chest beneath that makes them seem so.

And all the time, such is the tragi-comedy of our situation, we continue to clamour for those very qualities we are rendering impossible. . . . In a sort of ghastly simplicity we remove the organ and demand the function. We make men without chests and expect of them virtue and enterprise. We laugh at honour and are shocked to find traitors in our midst. We castrate and bid the geldings be fruitful.

C.S. Lewis, The Abolition of Man

#33 Miloch

Miloch

    Barbarian

  • Modders
  • 4720 posts
  • Gender:Male
  • Location:At Large

Posted 12 December 2010 - 08:57 PM

I don't know how "X#TT1Deactivate" gets set to 1 in the first place, if the problem is with the spawn deactivating immediately - you might have to post more code to analyse that.
Mod Contributions
Aurora (new release!) * BG1 NPC * Gnomes * Haiass * Level 1 NPCs * Lost Items * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * In Progress: Adjusted Portraits * DSotSC (Tutu)
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * PSPad Highlighters * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Wherefore do ye toil; is it not that ye may live and be happy? And if ye toil only that ye may toil more,
when shall happiness find you?" -H.P. Lovecraft, The Quest of Iranon

#34 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 08 January 2012 - 02:12 PM

EscapeAreaMove(S:Area*,I:X*,I:Y*,I:Face*) does not exist. A very simple work around for unjoinable NPCs would be, to destroy the creature at one place and recreate it at another, using for example
~MoveToPoint(), Destroyself()~ and then ~CreateCreature()~ at the new location (remember that possible local variables of the first encounter are lost then, like "NumTimesTalkedTo").
Zed Nocear suggests the following for BG1:TotSC: ~RunAwayFrom(LastTalkedToBy,60) LeaveAreaLUA("AR4801","",[284.454],0)~
I don't know whether LeaveAreaLUA() would work in BG1 (without TotSC), though.

I can't get "LeaveAreaLUA" to work for a non-party member in BG1:TotSC. Anyone having any experience with this?

#35 Miloch

Miloch

    Barbarian

  • Modders
  • 4720 posts
  • Gender:Male
  • Location:At Large

Posted 05 March 2012 - 07:29 PM

I can't get "LeaveAreaLUA" to work for a non-party member in BG1:TotSC. Anyone having any experience with this?

I hope it works, because that sucks if not. It seems to be used in BG1V but only in cutscenes - e.g. bragecut.bcs has LeaveAreaLUA("AR4802","TRBRACAP",[325.469],12). But again, these all seem to change the focus to players rather than NPCs. Not sure if there's another way to get a creature to change areas in BG1 other than EscapeArea() or DestroySelf() and recreating it in another area (assuming even that works). At least it works for the party - I would give up on all this hackery to get something working for BG1 if that didn't work.

In the progress of looking at this, I figured out what that second parameter "parchment" is. It points to a game-transition-like parchment in the form of a .mos file. In this case, trbracap.mos is a parchment of presumably Brage surrendering to someone, so that's what it can display during cutscene area changes.
Mod Contributions
Aurora (new release!) * BG1 NPC * Gnomes * Haiass * Level 1 NPCs * Lost Items * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * In Progress: Adjusted Portraits * DSotSC (Tutu)
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * PSPad Highlighters * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Wherefore do ye toil; is it not that ye may live and be happy? And if ye toil only that ye may toil more,
when shall happiness find you?" -H.P. Lovecraft, The Quest of Iranon

#36 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 03 April 2012 - 11:01 AM

Eridan reports that dialogue names for NPCs have to be not more than six characters long in BG1. I wasn't aware of this.

#37 plainab

plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 03 May 2012 - 09:15 PM

Eridan reports that dialogue names for NPCs have to be not more than six characters long in BG1. I wasn't aware of this.

actually I was going to report similar however I found it to be no more than 7 characters if you include the level #. also there must be a base character without a level # otherwise there will be a crash. (at least this has been my experience....)

I've also had difficulties with one version in one area intended to be non-joinable with one dialog and another set of creature files intended to be joinable in a different area (similar to what Imoen does). Even tho the proper character file was indicated in the GAM file, I would continue to get initial dialog from the non-joinable version. Easiest solution was to combine the dialog files and adjust states and use variables so the proper states would trigger at the proper time.

(Should note that it is a Tutu mod NPC that I'm converting and there wasn't an NPCLEVEL.2da adjustment done. Wasn't till I'd already merged the dialog files that I learned about the NPCLEVEL.2da file. Perhaps that would have solved the problem for me instead. However, what I have works... so far.)

I also took the code snip-it to add an npc to the game and put it into a tph as a function. Perhaps it could be added to weidu and the older ADD_GAME_NPC removed? Perhaps with a better name LOL
Spoiler
One thing that bothers me about the code from Zed is that it doesn't have the typical read the offset and count and jump to the right spot etc that we normally do for items, creatures, areas etc... however since it adds only 1 npc and at the front of the list, the locations will always be the same even tho they are in relation to the beginning of the file. Guess I'm used to having to be aware that what I want to do could have been previously adjusted by another mod.

Edited by plainab, 03 May 2012 - 09:17 PM.

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

#38 plainab

plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 05 May 2012 - 04:05 PM

out of curiosity how do the the bioware originals in BG/BG:ToTSC perform their banters? I've not seen any scripted method to get them to talk with each other, they just do. Is there some sort of internal banter engine that is hard wired for only the bioware originals?

I've only ever gotten the fight between Jaheria/Khalid & Xzar/Montaron once and I interrupted it cause I didn't know what it was. LOL been trying to get it to repeat and there is no noticeable way to get them to do so.

anywho... off to figure out how to convert tutu style banters into BG:ToTSC style... i think i have a nightmare ahead of me :p

***************************
on interjections... after the compiling does the 'dump' file actually get used or does it end up being left over cruft? If it's left over cruft then my little idea to try and make a function for a more streamlined process has merit. If it's actually used in game, then I can't do what I'm thinking of doing....

Edited by plainab, 05 May 2012 - 04:55 PM.

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

#39 Echon

Echon

    Planewanker

  • Members
  • 306 posts
  • Gender:Male
  • Location:Denmark

Posted 06 May 2012 - 07:02 AM

out of curiosity how do the the bioware originals in BG/BG:ToTSC perform their banters? I've not seen any scripted method to get them to talk with each other, they just do. Is there some sort of internal banter engine that is hard wired for only the bioware originals?


Yup. http://iesdp.gibberl...ts/interact.htm

#40 plainab

plainab

    Sasha al'Therin

  • Members
  • 1717 posts
  • Gender:Male
  • Location:Lost on the Sword Coast

Posted 06 May 2012 - 09:55 AM

I believe I have successfully streamlined the ICT workaround and in the process removed the need for a 'stupid passback' line

to quote Kulyok "watch my hands closely" :p

Example will be in regards to using an ICT from Tutu Finch in BG:ToTSC

First we need to establish whether or not Finch can talk. Best thing to do is let Finch tell us this, so we add a few blocks to her override script file
IF
  StateCheck("sufinch",CD_STATE_NOTVALID)
  InParty("sufinch")
  Global("abFinchCanTalk","GLOBAL",1)
THEN
  RESPONSE #100
    SetGlobal("abFinchCanTalk","GLOBAL",0)
    Continue()
END
IF
  !InParty("sufinch")
  Global("abFinchCanTalk","GLOBAL",1)
THEN
  RESPONSE #100
    SetGlobal("abFinchCanTalk","GLOBAL",0)
    Continue()
END
IF
  InParty("sufinch")
  Detect("sufinch")
  !StateCheck("sufinch",CD_STATE_NOTVALID)
  Global("abFinchCanTalk","GLOBAL",0)
THEN
  RESPONSE #100
    SetGlobal("abFinchCanTalk","GLOBAL",1)
    Continue()
END
Since variables are value 0 if never set what this does is if Finch never joined the party the variable "abFinchCanTalk" will automatically be = 0 and so when Finch joins we change that value to = 1. So after she has joined, if she leaves the party it gets reset to 0 and if she becomes unable to talk it also gets set to 0.
If you think about it, whenever this value is 0 there is no need to check and see if she is actually present via Detect(), See() or Exists(). She only needs to be there for her interjection to work. She can be there outside of the party, or in an unable to talk state, her interjection will still not be triggered.

Enter the workhorse. This is a function which will insert one triple file workaround ICT at a time. You can launch the function & define the variables directly in the TP2 or use an external TPH, your call
DEFINE_ACTION_FUNCTION ~ab_BG_Interject~ BEGIN
ACTION_IF (FILE_EXISTS_IN_GAME ~%ab_dialog%.dlg~) THEN BEGIN
<<<<<<<< dump.d
BEGIN ab_dump
IF ~~ 0   SAY ~%ab_tempDialogText%~ IF ~~ THEN EXIT END
>>>>>>>>
<<<<<<<< replace.d
REPLACE ab_dump IF ~~ THEN 0   SAY ~%ab_tempDialogText%~ COPY_TRANS %ab_dialog% %ab_statenum%  END END
ADD_TRANS_TRIGGER %ab_dialog% %ab_statenum%  ~%ab_canTalkVarAt0%~
>>>>>>>>
<<<<<<<< interjections.d
EXTEND_BOTTOM %ab_dialog% %ab_statenum%
IF ~%ab_pos_trigger% %ab_interjectVarAt0%~ EXTERN %ab_npc_dialog% ab_newstate
END
CHAIN %ab_npc_dialog% ab_newstate
%ab_interject%
END
COPY_TRANS ab_dump 0
>>>>>>>>
  COMPILE dump.d  EVALUATE_BUFFER
  COMPILE replace.d  EVALUATE_BUFFER
  COMPILE interjections.d  EVALUATE_BUFFER
END
END

Here is an example of launching the function & defining the variable
INCLUDE ~finch/lib/ab_BG_Interject.tph~
//since weidu doesn't like multiple sets of ~ & " together need to assign certain global variables outside of the LAF definitions
OUTER_SPRINT ab_interjectVarAt1 ~Global("abFinchTalkedAlatos","GLOBAL",1)~
LAUNCH_ACTION_FUNCTION ~ab_BG_Interject~
    INT_VAR
    ab_statenum = 0 //---------------------------------------------------- state number of the state that is being interjected into
    STR_VAR
    ab_tempDialogText = Finch //------------------------------------------ use npc's name so don't make another strref for crap
    ab_dialog = ALATOS //------------------------------------------------- file name of dialog to be interjected into
    ab_interjectVarAt0 = ~Global("abFinchTalkedAlatos","GLOBAL",0)~ //---- global variable to indicate the interjection has not happened
    ab_canTalkVarAt0 = ~Global("abFinchCanTalk","GLOBAL",0)~  //---------- npc cannot interject  set via npc's script
    ab_pos_trigger = ~InParty("sufinch")
					 Detect("sufinch")
					 !StateCheck("sufinch",CD_STATE_NOTVALID)~ //--------- positive checks by npc being spoken to to make sure that joined npc is present
    ab_npc_dialog = SUFINCHJ //------------------------------------------- file name of dialog file used by joined npc
    ab_interject = EVALUATE_BUFFER "@813 DO ~Set%ab_interjectVarAt1%~" //- list of text & actions that make up the chain part of the interjection
END
You only need to INCLUDE the definition once. It could be in the ALWAYS section of the TP2 or as I did it via an external tph

The resultant output of the state in question from the decompiled alatos.dlg after installation:
IF WEIGHT #0 ~NumTimesTalkedTo(0)
~ THEN BEGIN 0 // from:
  SAY #2783 /* ~Welcome my little friends!  Please relax, and keep your weapons at your sides.  No need for hostility.~ */
  IF ~  Global("abFinchCanTalk","GLOBAL",0)
~ THEN DO ~SetGlobal("TalkedToThief","GLOBAL",1)
SetGlobal("TalkedToAlatos","GLOBAL",1)
~ GOTO 1
  IF ~  InParty("sufinch")
Detect("sufinch")
!StateCheck("sufinch",CD_STATE_NOTVALID)
Global("abFinchTalkedAlatos","GLOBAL",0)
~ THEN EXTERN ~SUFINCHJ~ 68
END
As you can see, If Finch said she couldn't talk OR she never joined the party then the original transition occurs. IF she is in the party she will do her bit. Note I could have used the can talk variable at value 1 along with the Detect() check. However, I wanted the talking NPC to check for themselves since due to needing to use Continue() on the blocks in Finch's override script there could be a possible delay in the proper variable being set. Therefore the NPC checks for themselves at the moment of need.

Feel free to nitpick it apart.

I even checked it out by adding in a fake interjection for a fake npc name Fred. Everything looked good in that, if both Fred & Finch had their talk variable at 0 the original state would fire. If Fred's state was at 0 and Finch was present and able to talk Finch would do hers. If Fred was present & able to talk he would do his. Only concern I see (and would be true even outside of the function) if both Fred & Finch are there. Only first one installed gets to say their banter....
Perhaps it is a good thing... idk.
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

#41 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 20 January 2013 - 07:33 AM

Thank you, plainab, I will comment if I took the time to read it carefully.

-

3. Actions

DestroyItem() doesn't seem to be executed if triggered via script. In BG1 (+TotSC), no DestroyItem is used via script, and it doesn't work if used, either. Has to be used via dialogue transaction.

Can anyone confirm?

Edited by jastey, 20 January 2013 - 07:33 AM.


#42 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 20 January 2013 - 11:50 AM

What I can confirm is that something like this:

CHAIN
IF ~~ THEN C#Q01001 alanna_04
@12
== %IMOEN_JOINED% IF ~Global("C#BGQE_NPCReactions","GLOBAL",1)
InParty("IMOEN") Detect("IMOEN") !StateCheck("IMOEN",CD_STATE_NOTVALID)~ THEN @111
== %JAHEIRA_JOINED% IF ~Global("C#BGQE_NPCReactions","GLOBAL",1)
InParty("JAHEIRA") Detect("JAHEIRA") !StateCheck("JAHEIRA",CD_STATE_NOTVALID)
InParty("IMOEN") Detect("IMOEN") !StateCheck("IMOEN",CD_STATE_NOTVALID)~ THEN @112
END
++ @70 DO ~SetGlobal("C#Q01_TalkedToAlanna","GLOBAL",2)~ + alanna_04_2
++ @71 DO ~SetGlobal("C#Q01_TalkedToAlanna","GLOBAL",2)~ + alanna_04_1
++ @72 DO ~SetGlobal("C#Q01_TalkedToAlanna","GLOBAL",2)~ EXIT

Doesn't work as intended: The interjections of the NPCs don't play. The reply options are shown directly, and the button sais "continue", but the interjections don't play. The CHAIN has to end with transitions only, no reply options, then the interjections play as intended.

This is also true if an extra line is added via I_C_T, which actually functions for BG1 under some special cases, as to: No reply options (same problam as above) and best only one transition, e.g. this works:

I_C_T %tutu_var%COKSMTH 3 C#Q04_WyvernDeliverer
== %tutu_var%COKSMTH @0
END
The original state from the COKSMTH is:
IF ~~ THEN BEGIN 3 // from: 1.2 0.2
  SAY #10820 /* ~I see that you have no use for beating around the bush. Well, so be it. I cast aside my master woodsman facade. You have interrupted my little wyvern-training session and likely set my schedule back by days. I have worked long and hard to gain their trust, but if I they are to be ready for duty at the mine I shall have to placate these beasts with meat! Fight, for you shall die if you lose!~ */
  IF ~~ THEN DO ~Enemy()
~ EXIT
END

Edited by jastey, 20 January 2013 - 12:54 PM.


#43 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 20 January 2013 - 12:54 PM

I have to take the last thing back, at least for now, as I have the problem that

I_C_T %tutu_var%drunk 4 c#q12_Drunk
== %tutu_var%drunk @0
END

Will not compile with the error message "Cannot process COPY_TRANS". Anyone having an idea why I_C_T works on one dlg, but not on another, please let me know.

#44 Miloch

Miloch

    Barbarian

  • Modders
  • 4720 posts
  • Gender:Male
  • Location:At Large

Posted 21 January 2013 - 05:45 PM

DestroyItem() doesn't seem to be executed if triggered via script. In BG1 (+TotSC), no DestroyItem is used via script, and it doesn't work if used, either. Has to be used via dialogue transaction.

Pretty sure it works, both in creature and area scripts, e.g.:

ActionOverride("t-ealswi",DestroyItem("t-minhp1")) in an area script, or simply

DestroyItem("t-minhp1") in a creature script.
Mod Contributions
Aurora (new release!) * BG1 NPC * Gnomes * Haiass * Level 1 NPCs * Lost Items * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * In Progress: Adjusted Portraits * DSotSC (Tutu)
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * PSPad Highlighters * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Wherefore do ye toil; is it not that ye may live and be happy? And if ye toil only that ye may toil more,
when shall happiness find you?" -H.P. Lovecraft, The Quest of Iranon

#45 jastey

jastey
  • Gibberlings
  • 5271 posts
  • Gender:Female

Posted 22 January 2013 - 01:01 AM

I used DestroyItem() in the dplayer3.bcs and it was not processed. Everything else in that script block was (creation of a cre and journal entry). I changed the code now so a dialogue pops up (which is better for my purpose) so I would have to recode to check but I did it because the item destruction didn't work in several tries. (Item was in the inventory etc. pp)


Why do I get a "Reply to this topic" window if I cannot post as a guest?



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users