Jump to content

Search the Community

Showing results for tags 'weidu tp2 coding'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General Discussion
    • G3 News and Announcements
    • Infinity Engine Modding News
    • General Mod Discussion
    • Fan Fiction
    • Noobermeet
  • Tools & Resources
    • DLTCEP
    • GemRB
    • The Gibberlings Three Debugging Suite for BG2
    • IESDP Updates and Info
    • Modding How-Tos and Tutorials
    • Modding Q&A
    • Multi-Install Tool
    • Widescreen Mod
  • Released Projects
    • Miscellaneous Released Mods
    • Ajantis
    • Alternatives
    • Amber
    • Angelo
    • Ascension
    • Auren Aseph
    • BG1 NPC Project
    • Baldur's Gate Mini Quests and Encounters
    • The Beaurin Legacy
    • BG2 Fixpack - General Discussion
    • Calin
    • The Calling
    • Cirerrek's AI Scripts
    • Coran's Friendship Mod
    • Crossmod Banter Pack
    • Divine Remix
    • Enhanced Edition Trilogy
    • Evandra
    • Full Plate & Packing Steel
    • Garrick's Infatuation
    • Gavin
    • The Gibberlings Three Anniversary Mod
    • Glam's NPC Pack
    • Icewind Dale Mod Roundup
    • Icewind Dale in Baldur's Gate II
    • Imoen 4 Ever
    • Item Randomiser
    • Item Revisions
    • IWD2 NPC Project
    • IWDification
    • Keeping Yoshimo
    • Kivan and Deheriana Companions for BG2
    • Level One NPCs
    • Mur'Neth
    • NPC Kitpack
    • NPC Strongholds
    • NPC Tweak for BG2
    • Oversight
    • Romantic Encounters (BG)
    • Romantic Encounters (BG2)
    • Sarah
    • Song and Silence
    • Spell Revisions
    • Sword and Fist
    • Sword Coast Stratagems
    • Tweaks Anthology Forum
    • Tyris Flare
    • Wheels of Prophecy
    • Yoshimo's Remorse
  • Unreleased Projects
    • Aklon
    • Balduran's Seatower
    • Baldur's Gate: Shadow Hand TC
    • Aran Whitehand
    • Delainy
    • IWD Tutu
    • Kit Revisions
    • Inactive Projects
  • NWN2 Modding
  • Mod Workrooms

Categories

  • NPCs
  • Quests and Others
  • Tweaks & Fixes
  • Items/Kits/Spells
  • Portrait Packs
  • Mini Mods
  • Tools
  • In Progress

Categories

  • Fixes
  • Items
  • Kits
  • NPCs
  • Quests
  • Spells
  • Tweaks
  • Other
  • Tools

Product Groups

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Discord


Website URL


Skype


AIM


MSN


ICQ


Yahoo


Jabber


Location


Interests


Mods Worked On

Found 15 results

  1. We have found out in other threads that some "awareness" of things presented in mod-added content can be scripted directly into your mod without any troubles. For example, Aran can reference any existing DV, so !Inparty("mynpc") checks will not fail on install, and the strings referenced will be available if the mod-added NPC shows up in-game later on, regardless of install order. This works with globals, too, so in other threads progress to certain points in other mods allows "side talk" - not directly bantering with an NPC or using an item, but acknowledging their presence, either by use of <PLAYER3> tokens in dialog, or with direct checks for globals and DVs. Any way we cut this, we are still talking about having Aran (or your NPC) having some of his talks and paths refer to outside events created by other mods, and being able to install that content as part of Aran's mod. The presence of the global variable or DV being active in a game then "activates" that content passively - no need for messing about with other folk's files, etc. We have taken this a step further with looking at player responses by mod-added kit, in the thread regarding "what happens when..."; here, we found that when Divine Remix was not installed and we wanted to reference the kits added, we had a problem. Compiling a reference to a non-pre-existing kit left the engine with only one choice, "0". Which caused all sorts of problems if DR was not installed, and even worse had no "repair" effect on installed files - unlike GTIMES.IDS or other "engine lookup by handle" things, KIT.IDS references have to be built *after* the kits have been placed on an install, because of the way the files are created and referenced. We get around that by creating an independent "patch", ARAN_AWARE, which so far just swaps "dummy" variables that will compile at install but never be triggered (a very old idea in terms of shutting down content, the equivalent of adding False() to a trigger so a dialog will never play, except reversing a False() is a PITA, whereas setting a never-reached variable to 1 is a much more compatibility - friendly way of coding it - a SetGlobal, and the original block plays.) with the wanted content using good old fashioned REPLACE_TEXTUALLY operation: /* HEARTWARDER OF SUNE - Sune Firehair, Lady Firehair : Global("c-heartwarder","GLOBAL",1) */ ACTION_IF FILE_EXISTS_IN_GAME nmsune.2da BEGIN ACTION_FOR_EACH ~dialog_file~ IN ~c-aranj.dlg~ ~c-aranp.dlg~ ~c-arn25j.dlg~ ~c-arn25a.dlg~ BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%dialog_file%~ THEN BEGIN COPY_EXISTING ~%dialog_file%~ ~override~ DECOMPILE_DLG_TO_D REPLACE_TEXTUALLY ~Global("c-heartwarder","GLOBAL",1)~ ~Kit(Player1,NMSUNE) OR(6) Class(Player1,CLERIC) Class(Player1,FIGHTER_CLERIC) Class(Player1,CLERIC_MAGE) Class(Player1,CLERIC_THIEF) Class(Player1,FIGHTER_MAGE_CLERIC) Class(Player1,CLERIC_RANGER)~ REPLACE_TEXTUALLY ~Global("c-aranheartwarder","GLOBAL",1)~ ~Kit("c-aran",NMSUNE) OR(6) Class("c-aran",CLERIC) Class("c-aran",FIGHTER_CLERIC) Class("c-aran",CLERIC_MAGE) Class("c-aran",CLERIC_THIEF) Class("c-aran",FIGHTER_MAGE_CLERIC) Class("c-aran",CLERIC_RANGER)~ COMPILE_D_TO_DLG BUT_ONLY_IF_IT_CHANGES END END END So far so good. We know that using this after Divine Remix is installed means that the correct reference gets swapped into Aran's files. If a player installs the "patch" mod, the new content is activated. If they don't their game still works, and there is no problem. So, what else would need this kind of handling?
  2. We will insert the GitHub link once it is up right <<here>>, but for now, let's take inventory and start setting up for the documentation. Material written and integrated so far (except for the Gavin crossmod stuff that Berelinde and I are still tinkering with): Divine Remix aranw_aware will open pathways that recognize if your PC is using one of the Cleric Kits from Divine Remix. Kits Recognized: Heartwarder of Sune Feywarden of Correlon Strifeleader of Cyric Painbearer of Ilmater Lorekeeper of Oghma Firewalker of Kossuth Silverstar of Selune Holy Strategist of the Red Knight Nightcloak of Shar Battleguard of Tempus Authlim of Iyachtu Xvim NPC Mod Banters aranw_aware will add banters between Aran and the NPC in question if both Aran Whitehand and the other NPC mod are installed before running aranw_aware. NPC Mods Recognized: Laufey's Edwin Romance (one interjection in a conflict between Edwin and Anomen) "unauthorized" Angelo (two banters in SoA, two in ToB) "authorized", by Sister Vigilante and cmorgan; sound clips by Sister Vigilante Kivan (two banters in SoA) - "authorized" and "unauthorized" one by Domi and cmorgan, another by cmorgan (and hopefully she will ok it when she has the chance). Saerileth (three banters and one comment in SoA) "unauthorized", by cmorgan - if they stink, blame me and not Netharin/Sillara Tashia Remix, by Michael "Arian" Lyashenko, Bri, and Lord Ernie (two banters in SoA, two in ToB) "unauthorized", by cmorgan - if they stink, blame me and not Bri, Lord Ernie, or the original author, Michael "Arian" Lyashenko Tsujatha NPC MOD For Baldur’s Gate 2 (TOB Required) by Sillara of the Tamari (two banters in SoA) "unauthorized", by cmorgan - if they stink, blame me and not Sillara Solaufein Romance Mod Pack, by Westley Weimer (two banters in SoA) "unauthorized", by cmorgan - if they stink, blame me and not Westley Weimer Rather than filling the forum up with code, I will link the materials to github, so folks can see the .tp2 materials that way.
  3. OK, long faculty meeting, and no access to stuff I am supposed to be working on, or even modding stuff - and most of all, a long pointless argument raging over "No Child Left Behind"'s merits, which really is moot - it isn't as if we can choose to ignore it. So, I already have a bunch of stuff done on soundsets - I'll scribble while Rome burns. The soundset. Straightforward stuff like .cre files, etc., really are not a concern until later. I am working from a "character first" perspective, and BG2 graphics are not Oblivion stuff; we can build that stuff later. So, sounds - recorded lines or not? Argument for: everyone has 'em. They help some people characterize the NPC and fill them out in their brain. Argument against, thousands - including tons of time, energy, and work balancing the sounds, only to have a bunch of folks who had supplied the voice and accent in their heads think "hey - that is not how Aran should sound". In fact, I often rip the soundfiles out of mods before playing them - my inner voice is much more comfortable to me than an outsider's interpretation. I like bg1npc's idea of "soundtracks" for speakers, called by script, but that is a whole other topic, and weeks away. But you know what, it doesn't matter at this point - until Aran is 90% or more done, taking the time to record (or hire someone to record) a soundset and/or lines is silly. Things may will change, and perhaps the entire characterization will shift slightly. So the sound recordings themselves, next to last to do. Let's move on to the text strings, and set them up to handle sound when it is eventually recorded and added. Note: This looks like just a quick couple of days to whip through this, but actually took place over several weeks, and the final draft was vetted by berelinde and Amaurea to make sure I wrote something that fit my idea. Unfortunately, we all write from within our own heads. While I'm not writing Aran for anyone but my personal enjoyment, it is nice to check to see if the communication moves off the page to other folks, or if it ends up being stilted/odd. Some soundreferences with tobbacco use got nixed because the ladies (quite rightly) pointed out that it was a potential turn-off for some readers, while adding nothing really to his character - so I blatantly stole berelinde's rephrase of it into "twig chewing". This stuff is tougher than it looks, because we all want the character to have what comes up in our head during fanfic-like daydreams; unfortunately, if you create a line like La Traviata for dying, it will stink as a soundset: This might be fun to envision in my head, but really, soundset entries are supposed to be very quick, or the lines will trip over others. Wicked short, to the point - that's why they are some of the toughest writing out here. "Characterize your NPC's reactions in less than four words.... GO!" But, we have caught a break with it, because we have a format to work in, and we know the parameters. Short, simple, to the point, in character. And, WeiDU has taken the work out of all the coding completely. A standard setup in the .tp2 will install the right strings in the right places - and the i.e. engine has a simple format for strings that deal with sound. STTREF/OFFSET ~[comment] text string~ [sOUNDREF] Here, STTREF/OFFSET is where in the .cre file the string reference in dialog.tlk is stored. This is why soundsets can get scrambled, and other lines, too - the .cre file carries only a reference number, or index lookup to dialog.tlk. Technically, you could go all fancy hard-core Old Skool here and tell WeiDu the specific offset for the .cre sound, but why when WeiDU does the work for you: SAY MORALE The next, the actual string created in dialog.tlk, ~[comment] text string~ well, that's pretty straightforward - the [comment] will not be seen by the player. In fact, it is where I picked up the idea to try to use this to help translators - when Smoketest, devSin, and Grim Squeaker patiently led me through how sound works in i.e. games, it was there for the BioWare developers. Every soundset in BG carries the referenced sound file in the test string in this format. It is especially useful for usually "no word" things, like "Hurt" and Dying" - the blank sound reference can be labled and searched for by the comment, like this: SAY DAMAGE ~[c-aran13]~ [c-aran13] sounds like "Ah!", but carries no text - and would get skipped in traification if it were traified as this: SAY DAMAGE ~~ [c-aran13] So, last part - [sOUNDREF]. Here, the .wav (or wavc, acm) that we will eventually place in the game override file is referenced. It can only be 8 characters long, and looking at other folk's mods there are lots of ways to label this stuff - BioWare had an odd numbering system that is consistent but does not match .cre ordering - so i am going to arbitrarily label these c-aran## and use the comment as the soundreference. The game won't care if there is no sound matching in the override - it will silently skip it. And then, if I get a soundset recorded and dropped into the override, it will be picked up when that particular string is called by the engine. Here is the blank template that can be applied for all BG2 engine games (not BG, etc - they have the same structure, but the .cre file has less of these enabled.) COPY_EXISTING ~myMod/myFolder/myCre.cre~ ~override/myCre.cre~ SAY NAME1 ~ << Full Name Of Creature >> ~ SAY NAME2 ~ << Short (tooltip hovering) Name Of Creature >> ~ SAY MORALE ~[sOUNDREF] << Morale Failure >> ~ [sOUNDREF] SAY HAPPY ~[sOUNDREF] << When Happy on .2da >> ~ [sOUNDREF] SAY UNHAPPY_ANNOYED ~[sOUNDREF] << When Annoyed on .2da >> ~ [sOUNDREF] SAY UNHAPPY_SERIOUS ~[sOUNDREF] << When Close to leaving on .2da >> ~ [sOUNDREF] SAY UNHAPPY_BREAKING_POINT ~[sOUNDREF] << When leaving on .2da >> ~ [sOUNDREF] SAY LEADER ~[sOUNDREF] << Moved to Leader >> ~ [sOUNDREF] SAY TIRED ~[sOUNDREF] << Tired >> ~ [sOUNDREF] SAY BORED ~[sOUNDREF] << Bored >> ~ [sOUNDREF] SAY BATTLE_CRY1 ~[sOUNDREF] << Attack Commanded >> ~ [sOUNDREF] SAY BATTLE_CRY2 ~[sOUNDREF] << Attack Commanded >> ~ [sOUNDREF] SAY BATTLE_CRY3 ~[sOUNDREF] << Attack Commanded >> ~ [sOUNDREF] SAY BATTLE_CRY4 ~[sOUNDREF] << Attack Commanded >> ~ [sOUNDREF] SAY DAMAGE ~[sOUNDREF] << Hit by other >> ~ [sOUNDREF] SAY DYING ~[sOUNDREF] << Toast >> ~ [sOUNDREF] SAY HURT ~[sOUNDREF] << Low HP >> ~ [sOUNDREF] SAY AREA_FOREST ~[sOUNDREF] << in area flagged with Forest bit >> ~ [sOUNDREF] SAY AREA_CITY ~[sOUNDREF] << in area flagged with City bit >> ~ [sOUNDREF] SAY AREA_DUNGEON ~[sOUNDREF] << in area flagged with Dungeon bit >> ~ [sOUNDREF] SAY AREA_DAY ~[sOUNDREF] << Daytime >> ~ [sOUNDREF] SAY AREA_NIGHT ~[sOUNDREF] << Nighttime >> ~ [sOUNDREF] SAY SELECT_COMMON1 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_COMMON2 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_COMMON3 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_COMMON4 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_COMMON5 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_COMMON6 ~[sOUNDREF] << Select the .cre >> ~ [sOUNDREF] SAY SELECT_ACTION1 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION2 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION3 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION4 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION5 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION6 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_ACTION7 ~[sOUNDREF] << Action >> ~ [sOUNDREF] SAY SELECT_RARE1 ~[sOUNDREF] << rare sound >> ~ [sOUNDREF] SAY SELECT_RARE2 ~[sOUNDREF] << rare sound >> ~ [sOUNDREF] SAY CRITICAL_HIT ~[sOUNDREF] << successful critical roll >> ~ [sOUNDREF] SAY CRITICAL_MISS ~[sOUNDREF] << dysmal critical roll >> ~ [sOUNDREF] SAY TARGET_IMMUNE ~[sOUNDREF] << Up the creek without a paddle >> ~ [sOUNDREF] SAY INVENTORY_FULL ~[sOUNDREF] << dropping items >> ~ [sOUNDREF] SAY SPELL_DISRUPTED ~[sOUNDREF] << hit wile casting >> ~ [sOUNDREF] SAY SET_A_TRAP ~[sOUNDREF] << successful trap set >> ~ [sOUNDREF] SAY HIDDEN_IN_SHADOWS ~[sOUNDREF] << successful attempt to hide >> ~ [sOUNDREF] SAY PICKED_POCKET ~[sOUNDREF] << successful pickpocket attempt >> ~ [sOUNDREF] SAY BIO ~[DUMMYREF] << character screen, no sound - text with blank sound reference >> ~ [bLANK] Well, here goes - in file aranw.tp2, right now empty, we toss in the set of references: COPY_EXISTING ~aranw/cre/c-aran.cre~ ~override/c-aran.cre~ SAY NAME1 ~Aran Whitehand~ SAY NAME2 ~Aran~ SAY MORALE ~[c-aran01] Helm's bones - RETREAT!~ [c-aran01] SAY HAPPY ~[c-aran02] Aye, 'tis a fair group. 'Tis better than a clear day on Trade Way.~ [c-aran02] SAY UNHAPPY_ANNOYED ~[c-aran03] By Tymorra's bright coin, you make some strange decisions. I don't rightly agree.~ [c-aran03] SAY UNHAPPY_SERIOUS ~[c-aran04] I gave up some serious opportunities to travel with you. Wasn't expectin' this kind of 'adventure'. Stop this, or I'll dissolve th' contract.~ [c-aran04] SAY UNHAPPY_BREAKING_POINT ~[c-aran05] I'll see you in the hands o' Kelemvor, but not one second before.~ [c-aran05] SAY LEADER ~[c-aran06] I'll lead, but 'tisn't my strong point.~ [c-aran06] SAY TIRED ~[c-aran07] Time to make camp. This gear is startin' to chafe.~ [c-aran07] SAY BORED ~[c-aran08] By Torm's Blood, are we beggin' to be ambushed? Standin' 'round with our swords up our...~ [c-aran08] SAY BATTLE_CRY1 ~[c-aran09] Archers to th' rear!~ [c-aran09] SAY BATTLE_CRY2 ~[c-aran10] Spellcasters die first!~ [c-aran10] SAY BATTLE_CRY3 ~[c-aran11] By Tymorra's Luck!~ [c-aran11] SAY BATTLE_CRY4 ~[c-aran12] By Sune's Bottom!~ [c-aran12] SAY DAMAGE ~[c-aran13]~ [c-aran13] //ah... SAY DYING ~[c-aran14]~ [c-aran14] //aarrgh... SAY HURT ~[c-aran15] Send the rest o' them to hell for me...~ [c-aran15] SAY AREA_FOREST ~[c-aran16] Need less trees, more road. Too many places for enemies to hide.~ [c-aran16] SAY AREA_CITY ~[c-aran17] Trade time! Some trade, then some drinkin', then some sleep... or more drinkin'.~ [c-aran17] SAY AREA_DUNGEON ~[c-aran18] I gave up comfortable inns an' guardin' simple caravans to poke around this dank musty place. I'm a bloody idiot.~ [c-aran18] SAY AREA_DAY ~[c-aran19] Lathander's fat arse is up at last. 'Bout time he shed some light around here.~ [c-aran19] SAY AREA_NIGHT ~[c-aran20] Bloody dark. Good for coverin' enemies an' ambushes. Someone light a torch, eh?~ [c-aran20] SAY SELECT_COMMON1 ~[c-aran21] Yep?~ [c-aran21] SAY SELECT_COMMON2 ~[c-aran22] What's to be done?~ [c-aran22] SAY SELECT_COMMON3 ~[c-aran23] Do I needs lead?~ [c-aran23] SAY SELECT_COMMON4 ~[c-aran24] Aye?~ [c-aran24] SAY SELECT_COMMON5 ~[c-aran25] Yes?~ [c-aran25] SAY SELECT_COMMON6 ~[c-aran26] I'm listenin'.~ [c-aran26] SAY SELECT_ACTION1 ~[c-aran27] Got it.~ [c-aran27] SAY SELECT_ACTION2 ~[c-aran28] Sune's sweet cheeks, I heard.~ [c-aran28] SAY SELECT_ACTION3 ~[c-aran29] On it.~ [c-aran29] SAY SELECT_ACTION4 ~[c-aran30] Understood~ [c-aran30] SAY SELECT_ACTION5 ~[c-aran31] Sune's Bosom, I'm movin', already!.~ [c-aran31] SAY SELECT_ACTION6 ~[c-aran32] Ilmater's Blood. I said I'd do it.~ [c-aran32] SAY SELECT_ACTION7 ~[c-aran33] Less talk, more action.~ [c-aran33] SAY SELECT_RARE1 ~[c-aran34] Watch where you point that thing.~ [c-aran34] SAY SELECT_RARE2 ~[c-aran35] Aye, I'm here.~ [c-aran35] SAY CRITICAL_HIT ~[c-aran36] Good.~ [c-aran36] SAY CRITICAL_MISS ~[c-aran37] Cyric's Black Heart!~ [c-aran37] SAY TARGET_IMMUNE ~[c-aran38] Bounced off. Damn.~ [c-aran38] SAY INVENTORY_FULL ~[c-aran39] I'm already carryin' more than my share.~ [c-aran39] SAY SPELL_DISRUPTED ~[c-aran40] Never did get that one right...~ [c-aran40] SAY SET_A_TRAP ~[c-aran41] Try that, you bugger.~ [c-aran41] SAY HIDDEN_IN_SHADOWS ~[c-aran42] Huntin'...~ [c-aran042] SAY PICKED_POCKET ~[c-aran043] Hey, look what I found.~ [c-aran43] SAY BIO ~[c-aranbio] When you ask him about his past, ARAN WHITEHAND grasps at a nearby twig to chew on. He explains that he grew up in a small independent family-run Coster plying the Trade Way and Coast Way from Waterdeep both north and south. Working as both Pen and Sword (scribe and fighting guard) made him attractive as an independent, since he could balance accounts, keep inventory, and still operate as a sellsword. A few campaigns with mercenary companies, a few battles, and lots of wandering about has brought him to Amn. He hastens to note that he is not the man to send in to negotiate anything, preferring to wield weapons rather than the spoken word - but if you want a trading contract written up, he's the right man for the job.~ [c-aran44] Later on, the sound references will be c-aran01.wav to c-aran43.wav, and weeks/months from now when we get there we can deal with how to set the darned thing up to install on Windows/OS X/Linux and play in-game. Ok, the faculty talk is back to reality-based stuff, like what we are doing with dress-code this year, and how the heck us male teacher-dudes are supposed to inform a 14 year old that her underwear is showing and not get arrested... and worse, how to not insult the mom that sent the girl to school in one of those new thigh-length baby-doll tops designed for use over a pair of shorts, sans shorts. I'd better pay attention again. I'll type this stuff up later, and post it up on an odd moment. Well, technically, if you are reading this, I already did.
  4. Set up here with inlined just for reporting here - the related .baf is an independent file. CODE ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB dialog file COMPILE ~aranw/dialog/c-arantobdialog.d~ // USING ~aranw/dialog/%s/setup.tra~ /* ToB Scripts */ COMPILE ~aranw/baf/c-aranx.baf~ COMPILE ~aranw/baf/c-arn25.baf~ // USING ~aranw/dialog/%s/setup.tra~ /* Epilogues : Script */ <<<<<ar6200_epilog_ext.baf /* Epilogue: PC Refused Godhood, Low Rep, regardless of friendship or romance status */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") !Global("PlayerChoseEssence","GLOBAL",1) ReputationLT(Player1,10) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE0") SmallWait(1) Continue() END /* PC Refused Godhood, Friendship */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") ReputationGT(Player1,9) !Global("PlayerChoseEssence","GLOBAL",1) !Global("c-aranrom","GLOBAL",2) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE2") SmallWait(1) Continue() END /* PC Refused Godhood, Romance */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") ReputationGT(Player1,9) !Global("PlayerChoseEssence","GLOBAL",1) Global("c-aranrom","GLOBAL",2) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE3") SmallWait(1) Continue() END /* PC Became God, Friendship */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") ReputationGT(Player1,9) Global("PlayerChoseEssence","GLOBAL",1) !Global("c-aranrom","GLOBAL",2) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE2") SmallWait(1) Continue() END /* PC Accepted Godhood, Romance, Good or Neutral */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") Global("PlayerChoseEssence","GLOBAL",1) !GlobalGT("PPEvilChoices","GLOBAL",2) Global("c-aranrom","GLOBAL",2) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE4") SmallWait(1) Continue() END /* PC Accepted Godhood, Romance, Evil */ IF Global("StartEndBios","AR6200",1) InPartyAllowDead("c-aran") Global("PlayerChoseEssence","GLOBAL",1) GlobalGT("PPEvilChoices","GLOBAL",2) Global("c-aranrom","GLOBAL",2) Global("c-aranbio","GLOBAL",0) THEN RESPONSE #100 SetGlobal("c-aranbio","GLOBAL",1) TextScreen("C-ARANE5") SmallWait(1) Continue() END >>>>> EXTEND_TOP ~AR6200.bcs~ ~aranw/baf/ar6200_epilog_ext.baf~ /* Epilogue 1: Low Rep, regardless of friendship or romance status */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE0.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~The years of following in <CHARNAME>'s shadow took their toll on Aran, though not a single instance of him complaining is recorded. After a time, he withdrew from <PRO_HISHER> side, claiming injury, and set out for the wild coast of Maztican. Rejoining the Flaming Fist there gave him one last brush with glory - his name still graces the List of Brotherhood in the Flaming Fist training facilities there. Discovering new love with a Cleric of Sune Firehair, his sons and daughters grew up listening to bard's tales of the adventures of <CHARNAME> and <PRO_HISHER> followers, but their persistence in trying to get Aran to speak of those days went unanswered. Of <CHARNAME> <PRO_HIMHER>self, Aran refused to speak.~ /* PC Refused Godhood, Friendship */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE1.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~There are few places in history for followers and companions, and Aran was no exception. He traveled the breadth and depth of Toril in service to <CHARNAME>, often dispatched to assist other companions and causes dear to <CHARNAME>'s heart. Discovering new love with a Cleric of Sune Firehair, his sons and daughters grew up listening to bard's tales of the adventures of <CHARNAME> and <PRO_HISHER> followers. As Aran tells it, the greatest moment in Aran's life came when his eldest daughter took up the way of the sword and pledged herself to <CHARNAME>'s protection. The second best moment was when his new wife finally managed to teach him to speak with correct pronunciation (though she never did erase his swearing completely).~ /* PC Became God, Friendship */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE2.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~There are few places in history for followers and companions, and Aran was no exception. He traveled the breadth and depth of Toril in service to <CHARNAME>, often dispatched to assist other companions and causes dear to <CHARNAME>'s heart. Discovering new love with a Cleric of Sune Firehair, his sons and daughters grew up listening to bard's tales of the adventures of <CHARNAME> and <PRO_HISHER> followers. Though he never claimed worship of <CHARNAME>, his children relate that the new oaths and blasphemies used when they did something particularly right or particularly wrong seemed to indicate he was profoundly aware of <CHARNAME>'s godhood.~ /* PC Refused Godhood, Romance */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE3.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~Aran's depth of devotion to <CHARNAME> continued to grow, serving for the following years without question or complaint. Though the histories never indicate precisely the nature of their romance, there is no question of his loyalty. His final act of devotion came giving up his life in order to protect her. There are no reliable sources, but bard's tales say that his last words were "Blighted hells, <CHARNAME>... did we have to come Planewalkin' here?"~ /* PC Accepted Godhood, Romance, Good or Neutral */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE4.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~Aran's depth of devotion to <CHARNAME> continued to grow, serving as Her right hand on Faerun. His constant work furthering her causes helped develop a respectable following, and his willingness to travel anywhere in Her name led others to regard him as some sort of high priest... a notion that often was dispelled in a barrage of blasphemy and cursing. As the histories recount, his last days on this mortal plane were spent comfortably on Evermeet, attempting to arrange a joint project between the followers of <CHARNAME> and Hanali Celanil's Order of the Ruby Rose to commemorate what would have been <CHARNAME>'s eightieth mortal birth-day celebration.~ /* PC Accepted Godhood, Romance, Evil */ COPY ~aranw/media/blankepilogue.2da~ ~override/C-ARANE5.2da~ REPLACE_TEXTUALLY ~PORTRAIT~ ~C-ARANWL~ REPLACE 99999 ~Aran's depth of devotion to <CHARNAME> continued to grow, serving for the following years without question or complaint. His constant work furthering her causes eventually corrupted him completely, though later writings indicate growing fear and desolation as his mortality left him increasingly unable to serve <CHARNAME> in the manner she wished. It is a mark of their love that when a Paladin of Helm finally ended Aran's life, <CHARNAME> herself personally blasted the woman into nothingness, causing a minor skirmish in the wars of the gods.~ END /* of ToB installation */
  5. Nix has created Aran's first portrait set, for which I am very grateful! Option #1: aransportraits.rar
  6. No time to type much; will fill in more details later. Short course: Timers are set for FTs, LTs, NPC-Initiated flirts. Staggering content so they don't bunch up is relatively simple... until you give players choices on how long the timers work. Unsolvable problem in the long run, as starting/stopping flirts, starting/stopping romances, and talks that require specific conditions to fire will all throw them off, and the engine itelf seems to like to randomly wait much longer than the actual established timer (observation only, not proven). But, a partial solution, coded and installed in Aran's latest pre-Beta stuff: set everything up using OUTER_SET depending on the player choice. in c-aran.baf CODE /* ROMANCE TALKS */ /* * Romance Match and Initiation (He is not picky...) * One new thing here - Aran is ok if a friend switches genders - * but not so much on the romance side. So, we add a blocking variable * to make sure nothing progresses while that silly Girdle is in place. * He can have some special lines to play during the FT sequence on that. */ IF Global("c-aranmatch","GLOBAL",0) // Not evaluated Gender(Player1,FEMALE) // Player1 is female InParty(Myself) // Aran is here !StateCheck(Myself,CD_STATE_NOTVALID) // Aran is ok !StateCheck(Player1,CD_STATE_NOTVALID) // Player1 is ok !HasItemEquiped("belt05",Player1) // Girdle of sex change not on Player1 THEN RESPONSE #100 // 100% of the time SetGlobal("c-aranmatch","GLOBAL",1) // Matched SetGlobal("c-aranrom","GLOBAL",1) // Aran is interested END /* Berelinde: Please consider staggering your flirts and your dialogues. Flirts are nice when they break up long stretches between LTs. * cmorgan: OK, great idea - let's make it really complicated, and base the first timer on the player's choice of overall speed of progress... */ IF Global("c-aranmatch","GLOBAL",1) // Matched Global("c-aransetupromtimers","GLOBAL",0) // Not evaluated GlobalGT("c-aranfriendbg2","GLOBAL",5) // FT 3 has played Gender(Player1,FEMALE) // Player1 is female InParty(Myself) // Aran is here !StateCheck(Myself,CD_STATE_NOTVALID) // Aran is ok !StateCheck(Player1,CD_STATE_NOTVALID) // Player1 is ok !HasItemEquiped("belt05",Player1) // Girdle of sex change not on Player1 THEN RESPONSE #100 SetGlobal("c-aransetupromtimers","GLOBAL",1) RealSetGlobalTimer("c-aranromtimer","GLOBAL",%choseninitialrom%) // Minimum Real Time until first LT RealSetGlobalTimer("c-aranflirttimer","GLOBAL",%choseninitialflirt%) // Tee up flirt timer END in setup-aranw.tp2 CODE OUTER_FOR( aran_timer_choice = 0; ~%aran_timer_choice%~ STRING_COMPARE_REGEXP ~^[12]$~; )BEGIN PRINT ~Set Talk and Flirt Timers [1] Install Default Timers [2] Customize Timers Please type 1 or 2 and press enter.~ ACTION_READLN aran_timer_choice END // of O_F ACTION_IF ("aran_timer_choice" = 1) THEN BEGIN /* .ids patching with player choice: set talk timers */ APPEND ~gtimes.ids~ ~3600 ARAN_FTT~ APPEND ~gtimes.ids~ ~3600 ARAN_LTT~ APPEND ~gtimes.ids~ ~3600 ARAN_FLIRT~ PRINT ~Speed: minimum 1 hour real time between dialogues (Default, recommended)~ OUTER_SET choseninitialrom = 2400 PRINT ~Initial Lovetalk offset by 40 minutes~ OUTER_SET choseninitialflirt = 1200 PRINT ~Initial NPC-Initiated Flirt offset by 20 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start hourly FT, NPC Flirt 20 minutes later, and RT 20 minutes after that, then 20 minutes later the next FT fires. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits.~ END ACTION_IF ("aran_timer_choice" = 2) THEN BEGIN PRINT ~Select Aran's Talk timers:~ PRINT ~Please choose one of the following: [1] approximately 1 hour real time minimum between friendship dialogues (recommended, default) [2] approximately 15 minutes real time minimum between friendship dialogues [3] approximately 30 minutes real time minimum between friendship dialogues [4] approximately 45 minutes real time minimum between friendship dialogues [5] approximately 1 hour 30 minutes real time minimum friendship between dialogues [6] approximately 2 hours real time minimum between friendshipdialogues~ OUTER_SPRINT ~friendshiptimer~ ~placeholder_value~ OUTER_WHILE (!(IS_AN_INT ~friendshiptimer~) OR (~friendshiptimer~ > 0x6) OR (~friendshiptimer~ < 0x1)) BEGIN PRINT ~Please type 1, 2, 3, 4, 5 or 6 and press enter.~ ACTION_READLN ~friendshiptimer~ END ACTION_IF ("friendshiptimer" = 1) THEN BEGIN APPEND ~gtimes.ids~ ~3600 ARAN_FTT~ APPEND ~gtimes.ids~ ~3600 ARAN_LTT~ APPEND ~gtimes.ids~ ~3600 ARAN_FLIRT~ PRINT ~Speed: minimum 1 hour real time between dialogues (Default, recommended)~ OUTER_SET choseninitialrom = 2400 PRINT ~Initial Lovetalk offset by 40 minutes~ OUTER_SET choseninitialflirt = 1200 PRINT ~Initial NPC-Initiated Flirt offset by 20 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start hourly FT, NPC Flirt 20 minutes later, and RT 20 minutes after that, then 20 minutes later the next FT fires. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits.~ END ACTION_IF ("friendshiptimer" = 2) THEN BEGIN APPEND ~gtimes.ids~ ~900 ARAN_FTT~ APPEND ~gtimes.ids~ ~900 ARAN_LTT~ APPEND ~gtimes.ids~ ~900 ARAN_FLIRT~ PRINT ~Speed: minimum 15 minutes real time between dialogues~ OUTER_SET choseninitialrom = 600 PRINT ~Initial Lovetalk offset by 10 minutes~ OUTER_SET choseninitialflirt = 300 PRINT ~Initial NPC-Initiated Flirt offset by 5 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start 15 minute FT, NPC-initiated Flirt 5 minutes later, and RT 5 minutes after that, then 5 minutes later the next FT. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits... especially when you run out of timered content!~ END ACTION_IF ("friendshiptimer" = 3) THEN BEGIN APPEND ~gtimes.ids~ ~1800 ARAN_FTT~ APPEND ~gtimes.ids~ ~1800 ARAN_LTT~ APPEND ~gtimes.ids~ ~1800 ARAN_FLIRT~ PRINT ~Speed: minimum 30 minutes real time between dialogues~ OUTER_SET choseninitialrom = 1200 PRINT ~Initial Lovetalk offset by 20 minutes~ OUTER_SET choseninitialflirt = 600 PRINT ~Initial NPC-Initiated Flirt offset by 10 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start 30 minute FT, NPC-initiated Flirt 10 minutes later, and RT 10 minutes after that, then 10 minutes later the next FT. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits... especially when you run out of timered content!~ END ACTION_IF ("friendshiptimer" = 4) THEN BEGIN APPEND ~gtimes.ids~ ~2700 ARAN_FTT~ APPEND ~gtimes.ids~ ~2700 ARAN_LTT~ APPEND ~gtimes.ids~ ~2700 ARAN_FLIRT~ PRINT ~Speed: minimum 45 minutes real time between dialogues~ OUTER_SET choseninitialrom = 1800 PRINT ~Initial Lovetalk offset by 30 minutes~ OUTER_SET choseninitialflirt = 900 PRINT ~Initial NPC-Initiated Flirt offset by 15 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start 45 minute FT, NPC-initiated Flirt 15 minutes later, and RT 15 minutes after that, then 15 minutes later the next FT. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits... especially when you run out of timered content!~ END ACTION_IF ("friendshiptimer" = 5) THEN BEGIN APPEND ~gtimes.ids~ ~5400 ARAN_FTT~ APPEND ~gtimes.ids~ ~5400 ARAN_LTT~ APPEND ~gtimes.ids~ ~5400 ARAN_FLIRT~ PRINT ~Speed: minimum 1 hour 30 minutes real time between dialogues~ OUTER_SET choseninitialrom = 3600 PRINT ~Initial Lovetalk offset by 60 minutes~ OUTER_SET choseninitialflirt = 1800 PRINT ~Initial NPC-Initiated Flirt offset by 30 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start 90 minute FT, NPC-initiated Flirt 30 minutes later, and RT 30 minutes after that, then 30 minutes later the next FT. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits... especially when you run out of timered content!~ END ACTION_IF ("friendshiptimer" = 6) THEN BEGIN APPEND ~gtimes.ids~ ~7200 ARAN_FTT~ APPEND ~gtimes.ids~ ~7200 ARAN_LTT~ APPEND ~gtimes.ids~ ~7200 ARAN_FLIRT~ PRINT ~Speed: minimum 2 hours real time between dialogues~ OUTER_SET choseninitialrom = 4800 PRINT ~Initial Lovetalk offset by 80 minutes~ OUTER_SET choseninitialflirt = 2400 PRINT ~Initial NPC-Initiated Flirt offset by 40 minutes~ PRINT ~So if you are in a romance with him and never stop the romance, after the lovetalks start (after friendship talk 3), the timer sequence will start 120 minute FT, NPC-initiated Flirt 40 minutes later, and RT 40 minutes after that, then 40 minutes later the next FT. Please note that the timers are not exact, and variations within the game may mean bursts of activity followed by long waits... especially when you run out of timered content!~ END END and when compiling the two scripts that have blocks like this in the .tp2, farther down, use CODE COMPILE EVALUATE_BUFFER ~aranw/baf/c-aran.baf~ // override script ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB dialog file PRINT ~Installing ToB scripts...~ COMPILE EVALUATE_BUFFER ~aranw/baf/c-arn25.baf~ // joined ToB script The result of timer choices are hidden in the PRINT stuff, detailed out for anyone who looks at the .DEBUG file.
  7. Troubleshooting a Stutter or Constant PID (Player-Initiated-Dialog, or "Force Click") (If you are a player who just wants the troubleshooter and how to use it, skip to post #2!) The problem It happens. Your NPC looks nice, and installs fine. But suddenly, out of nowhere, he starts constantly coming up to the PC and trying to initiate conversation. Or he keeps bugging another NPC, over and over again, without actually saying anything, bogging down your game. Or he stops every few seconds, fidgets as if about to say something, and then moves on. Games slow down. Bleh. This is usually caused by a script block being triggered, but not being able to close. The ultimate "get the annoying stutter" would be to have a block that looks like this in your mod: IF InParty(Myself) THEN RESPONSE #100 StartDialogNoSet(Player1) END This block always fires if the dude running the script is in the party. And with no conditions, it runs every script cycle. So you get the ultimate Noober/Neeber character, and lots of hate mail. Your NPC starts initiating conversations with PC non-stop, for as long as his script is active, everywhere... the ultimate kid sister following you around, tugging on your sleeve every second or so. Common reasons that this might happen in your mod: Typos in timer or var. The block might be triggering on "my_variable" but then closing on "my_vraiable" Differences in variable scope. The block might be triggering on "myvar","LOCALS" and trying to close on "myvar","GLOBAL" Another mod interfering. Mod B may have come along and put something that changes either script or dialog or DV or something that results in your code not working as tested. Which can lead us to... Weighting. The block may be evaluating true, but can't resolve because the dialog or action that it is trying to launch is being blocked by another. A simple example in a dialog file, setting up for a script stutter: IF ~InParty("cmorgan")~ THEN BEGIN heya SAY ~[CMORGAN] I am conditioned broadly, so I will always evaluate true when the script tries to look for what it wants. I take priority each and every time, no matter how hard you try to clear me. Nothing that weights below me will ever be called by the script - I run instead.~ IF ~~ THEN EXIT END IF ~Global("myvar","GLOBAL",1)~ THEN BEGIN what_the_script_is_looking_for SAY ~[CMORGAN] I am conditioned narrowly, so I will only evaluate true when a very specific global is set. The script looking for me starts at the top of the dialog and works downwards until it finds me... unless it finds something else that is true, and fires it instead.~ IF ~~ THEN DO ~SetGlobal("myvar","GLOBAL",2)~ EXIT END In this configuration, if you wanted to turn the narrowly-conditioned block into a showstopper, just leave off the DO, and voila - that line, even though narrowly conditioned, just became an "always true" when the variable is set to 1. And anything downstream of it will never play. reminder - - scripts evaluate top to bottom, stopping when something evaluates true, and jumping back to the top again (unless you add Continue() ) - dialog files are called by scripts or the "hidden" scripts inside the engine, and evaluate top down... except when you set up WEIGHT that changes the evaluation order, making a talk rise to the top of the evaluation order (or lowering it, whichever you set - you can manipulate the thing to top or bottom of the stack of everything that has been installed before it. After that, other mods can do the same, but the newcomer can change things; you can't). - dialog TRANSITIONS are evaluated BOTTOM UP. So, while the state is evaluated from the top of the file down, once a state is called, the transitions are checked from the bottom card in the deck to the top one, and the first one is taken - or in the case of REPLY, every statement that returns true is displayed. The Challenge On your own install, this is a PITA to troubleshoot, but it is eminently do-able. You have full access to your own unique install, you have NI, DLTCEP, WeiDU, text editors, ways of searching all of your project at once for matching variables, and the knowledge of your own code. But. When it hits the field, all of this changes. Because every modded install is slightly different, you can't just grab a .bcs or .dlg file from a player experiencing a problem and decompile it yourself on your own install and have it help. You can do some of the investigation with tools like Vlasák's Variable Checker from The Black Wyrm's Lair, which features savegame compares, or manual comparisons with WeiDu and NI and DLTCEP - in this case, tools like CamDawg's Debugger is not as useful because we are not dealing with possible file corruption or problem areas/assignments, we are dealing strictly with script evaluation. In this day and age of BWP and BiG World installs, troubleshooting stutters and weighting issues and such becomes an impossible task, because it is 99% likely that even if you replicated the install as closely as possible, it would never get troubleshot, for a very simple reason - limited modding time, and huge amounts of time installing and uninstalling to replicate. Even more importantly, all of these tools have the disadvantage of working from a snapshot instead of real-time, on the actual install having the problem. So, either have a player .zip up between 2 and 5 GB of their entire game folder so you have their entire install and pay for the upload/download, troubleshooting on their actual game, or ... The Solution The Bigg came up with a reasonable way of checking to see what script block is firing but failing to resolve itself mod to find the problem. Berelinde adapted it and used it to troubleshoot Gavin. And now I have shamelessly copied and pasted and modified it to work with Aran. Basically, all it does is take whatever in-game .bcs files you point it to, and look for the RESPONSE section, number each one, and set up a DisplayStringHead() on PC. in the old days, we did this manulaly, which was horrible. It was even more horrible when it was just manually. Nothing like numbering and identifying each and every block and dialog, then having to go back and remove all that before giving it out... Now, through WeiDU-foo, you can have a user experiencing the problem go back to an earlier save, install a mod, run through to the problem, and report the number. Eventually, someone will whip up a good way of decompiling the resulting file and sending you the info in text, but for now, the safest thing to do is have the player read off which block of which .bcs is firing in the dialog window, and have them decompile and send you the problem file. Then have them uninstall the mod. Good news - it can go on the very end of the install with no problems! Here is the base code: BACKUP ~aran_troubleshoot/backup~ AUTHOR ~berelinde~ BEGIN ~Troubleshooting Aran's stutter with Shamelessly Re-Appropriated Code from Gavin~ COPY_EXISTING ~c-aran.bcs~ ~override~ // be sure to change the file names to point to the relevant ones ~c-arand.bcs~ ~override~ ~c-ar01.bcs~ ~override~ ~baldur.bcs~ ~override~ // use either baldur.bcs or baldur25.bcs whether you're in SoA or in ToB. ~player1d.bcs~ ~override~ ~c-arn25.bcs~ ~override~ ~c-arn25d.bcs~ ~override~ SET x = 0 - 1 DECOMPILE_BCS_TO_BAF REPLACE_EVALUATE ~\(RESPONSE #[0-9]+\)~ BEGIN x += 1 END "\1 ActionOverride(Player1,DisplayString(Myself,~Running block %x% of %SOURCE_RES%.BCS~))" COMPILE_BAF_TO_BCS So, to copy it and use it yourself, you just need to identify what scripts you touch and swap them in the .tp2.
  8. Discussion started from Aran Whitehand development - Synopsis: AreaCheck() does not cover mod added areas without specific addition AreaType() does not cover mod added areas without specific addition AreaType(CITY) was intended to cover city outdoor areas Looking for a way of getting all areas, vanilla and modded, to be able to be checked for being in a city and an inn, so that the appropriate movie can be triggered and content can be tailored and still make sense Suggestions so far: Worse: Research and create mass "MYAREA" script extensions for all such areas Better: Create and identify new AreaType()s and set them up as community resources [-cmorgan AreaType() checks fail. Keep that in mind. You will need a more robust check than AreaType(CITY) to determine where the party is sleeping and cue the appropriate cutscene. You may need to do an extensive OR() block area check for this. Just saying. I've got the code up elsewhere and can post it here if you need it.
  9. In <<this thread>> we were tracing ways of adding in install choices for players. in the meantime, the bigg has come up with some new WeiDU possibilities that allow some interesting ways of "swinging" code into separate branches based on setting/reading variables and matching against their values. Basically, the same kind of thinking that PATCH_IF statements use, but on a larger scale. Never one to do something and let it just sit, let's recast the player choices on install using this new method. He has a bunch of these new commands that might be interesting to heavy coders, but for gadabouts like me, ACTION_MATCH is the simplest to understand and shows basically what he is allowing in various forms by supporting this kind of code behavior. note: Doing this is fun for me, but in this particular case it is hitting a fly with an ICBM. I suspect other code which relies on massive internal checking and patching based on a whole series of variables could be cleaned up using this kind of construction, done better - the code below is very clunky and linear, and does not take advantage of the heaviest potential gains, where separate 'building blocks" could be swapped in based on multiple matches or "guarding conditions" or whatever the big Boyz and Girlz use for terminology. Basically, stuff like IF (A) AND (NOT B) AND © AND (D) AND (NOT E) IF (NOT A) AND (NOT B) AND © AND (D) AND (NOT E) IF (NOT A) AND (B) AND © AND (NOT D) AND (NOT E) etc. etc. can be set up with a series of individual matched blocks of code, and put into play that way rather than creating a whole series of individual 'cases'. The end Result of This As Applied To Aran CODE BEGIN ~Aran Whitehand, "No Choices Wanted" (Fighter)~ FORCED_SUBCOMPONENT ~Choose Which Aran Configuration to install...~ REQUIRE_COMPONENT ~setup-aranw.tp2~ ~0~ ~Aran Whitehand must be installed for this to work.~ OUTER_SET class_choice = 5 LAUNCH_ACTION_MACRO customized_cre_choice ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB .cre file COPY_EXISTING ~c-aran7.cre~ ~override/c-aran13.cre~ WRITE_LONG 0x18 2500000 // current XP 2500000, ToB start WRITE_ASCII 0x2cc ~C-ARN25A~ #8 /* dialogue */ WRITE_ASCII 0x280 ~C-ARAN~ #32 /* DV */ WRITE_ASCII 0x248 ~C-ARN25~ #8 /* override script */ END BEGIN ~Aran Whitehand, Mage Dual-Class stats configuration (Tinker)~ FORCED_SUBCOMPONENT ~Choose Which Aran Configuration to install...~ REQUIRE_COMPONENT ~setup-aranw.tp2~ ~0~ ~Aran Whitehand must be installed for this to work.~ OUTER_SET class_choice = 1 LAUNCH_ACTION_MACRO customized_cre_choice ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB .cre file COPY_EXISTING ~c-aran7.cre~ ~override/c-aran13.cre~ WRITE_LONG 0x18 2500000 // current XP 2500000, ToB start WRITE_ASCII 0x2cc ~C-ARN25A~ #8 /* dialogue */ WRITE_ASCII 0x280 ~C-ARAN~ #32 /* DV */ WRITE_ASCII 0x248 ~C-ARN25~ #8 /* override script */ END BEGIN ~Aran Whitehand, Cleric Dual-Class stats configuration (Tailor)~ FORCED_SUBCOMPONENT ~Choose Which Aran Configuration to install...~ REQUIRE_COMPONENT ~setup-aranw.tp2~ ~0~ ~Aran Whitehand must be installed for this to work.~ OUTER_SET class_choice = 2 LAUNCH_ACTION_MACRO customized_cre_choice ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB .cre file COPY_EXISTING ~c-aran7.cre~ ~override/c-aran13.cre~ WRITE_LONG 0x18 2500000 // current XP 2500000, ToB start WRITE_ASCII 0x2cc ~C-ARN25A~ #8 /* dialogue */ WRITE_ASCII 0x280 ~C-ARAN~ #32 /* DV */ WRITE_ASCII 0x248 ~C-ARN25~ #8 /* override script */ END BEGIN ~Aran Whitehand, Fighter stats configuration (Soldier)~ FORCED_SUBCOMPONENT ~Choose Which Aran Configuration to install...~ REQUIRE_COMPONENT ~setup-aranw.tp2~ ~0~ ~Aran Whitehand must be installed for this to work.~ OUTER_SET class_choice = 3 LAUNCH_ACTION_MACRO customized_cre_choice ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB .cre file COPY_EXISTING ~c-aran7.cre~ ~override/c-aran13.cre~ WRITE_LONG 0x18 2500000 // current XP 2500000, ToB start WRITE_ASCII 0x2cc ~C-ARN25A~ #8 /* dialogue */ WRITE_ASCII 0x280 ~C-ARAN~ #32 /* DV */ WRITE_ASCII 0x248 ~C-ARN25~ #8 /* override script */ END BEGIN ~Aran Whitehand, Thief Dual-Class stats configuration (Spy)~ FORCED_SUBCOMPONENT ~Choose Which Aran Configuration to install...~ REQUIRE_COMPONENT ~setup-aranw.tp2~ ~0~ ~Aran Whitehand must be installed for this to work.~ OUTER_SET class_choice = 4 LAUNCH_ACTION_MACRO customized_cre_choice ACTION_IF FILE_EXISTS_IN_GAME ~ar6111.are~ THEN BEGIN // ToB .cre file COPY_EXISTING ~c-aran7.cre~ ~override/c-aran13.cre~ WRITE_LONG 0x18 2500000 // current XP 2500000, ToB start WRITE_ASCII 0x2cc ~C-ARN25A~ #8 /* dialogue */ WRITE_ASCII 0x280 ~C-ARAN~ #32 /* DV */ WRITE_ASCII 0x248 ~C-ARN25~ #8 /* override script */ END For an "allow me to choose" subcomponent, or we let players just skip all the crap: ACTION_READLN and Other Macros as Building Blocks Instead of the code in the previous thread, first we pull everything we can out into discreet blocks and turn them into "get information from the user" macros and "work on the .cre" macros. That allows us to individualize the class choice ones, change the order, and most of all get everything set up, then copy the .cre once and apply all the changes in one swoop. CODE DEFINE_ACTION_MACRO aran_wealth_selection BEGIN OUTER_FOR( aran_wealth = 0; ~%aran_wealth%~ STRING_COMPARE_REGEXP ~^[123]$~; )BEGIN PRINT ~Please choose from the following choices to modify starting armor and weapons available to him: [1] Aran is down-and-out poor and has sold off most of his good equipment. [2] Aran has kept most of his good gear. [3] Aran has kept the best gear available to a successful mercenary. Please select 1, 2, or 3 and press enter.~ ACTION_READLN aran_wealth END END DEFINE_ACTION_MACRO aran_armor_choice BEGIN OUTER_FOR( aran_armor_choice = 0; ~%aran_armor_choice%~ STRING_COMPARE_REGEXP ~^[12345]$~; )BEGIN PRINT ~Please choose from the following starting armor choices for Aran: [1] Leather [2] Studded Leather [3] Chain [4] Splint [5] Plate Please select 1, 2, 3, 4, or 5 and press enter.~ ACTION_READLN aran_armor_choice END END DEFINE_ACTION_MACRO aran_mage_choice BEGIN OUTER_FOR( weapon_choices = 0; ~%weapon_choices%~ STRING_COMPARE_REGEXP ~^[123]$~; )BEGIN // one way of setting up for READLN PRINT ~You are probably going to Dual-Class Aran to Mage. He currently has proficiencies as follows: ** Long Sword ** Quarterstaff ** Dagger Please choose from the following starting weapon choices and press enter: [1] Long Sword, Shield, Dagger [2] Long Sword, Shield, Quarterstaff [3] Long Sword, Shield, Potions of healing~ ACTION_READLN ~weapon_choices~ END END DEFINE_ACTION_MACRO aran_cleric_choice BEGIN OUTER_FOR( weapon_choices = 0; ~%weapon_choices%~ STRING_COMPARE_REGEXP ~^[1234]$~; )BEGIN // one way of setting up for READLN PRINT ~You are probably going to Dual-Class Aran to Cleric. He currently has proficiencies as follows: * Long Sword * Hammer * Mace * Flail ** Sword and Shield Style Please choose from the following starting weapon choices: [1] Long Sword, Shield, Mace [2] Long Sword, Shield, Quarterstaff [3] Long Sword, Shield, Hammer [4] Long Sword, Shield, Flail~ ACTION_READLN ~weapon_choices~ END END DEFINE_ACTION_MACRO aran_fighter_choice BEGIN OUTER_FOR( weapon_choices = 0; ~%weapon_choices%~ STRING_COMPARE_REGEXP ~^[123456]$~; )BEGIN // one way of setting up for READLN PRINT ~You are probably going to leave Aran as a fighter. He currently has proficiencies as follows: ** Long Sword ** Bastard Sword * Long Bow * Sword and Shield Please choose from the following starting weapon choices: [1] Long Sword, Shield, Dagger [2] Long Sword, Shield, Long Bow [3] Long Sword, Shield, Potions of healing [4] Bastard Sword, Shield, Dagger [5] Bastard Sword, Shield, Long Bow [6] Long Sword, Shield, Hammer~ ACTION_READLN ~weapon_choices~ END END DEFINE_ACTION_MACRO aran_thief_choice BEGIN OUTER_FOR( weapon_choices = 0; ~%weapon_choices%~ STRING_COMPARE_REGEXP ~^[12345]$~; )BEGIN // one way of setting up for READLN PRINT ~You are probably going to Dual-Class Aran as a Thief. He currently has proficiencies as follows: ** Long Sword ** Short Sword * Dagger * Crossbow Please choose from the following starting weapon choices: [1] Long Sword, Shield, Dagger [2] Long Sword, Shield, Crossbow [3] Long Sword, Shield, Potions of healing [4] Short Sword, Shield, Dagger [5] Short Sword, Shield, Crossbow~ ACTION_READLN ~weapon_choices~ END END Now, we have user choices defined, and we can apply them in a new macro, customized_cre_choice. Here, we are looking to "swing" the code into different branches based on the class, chosen, because we are working with two unique building blocks. While wealth and armor are the same for each, we need to bring a different base .cre into play, and the proficiency set (and weapons choices) vary by the base .cre chosen. So we need to a. look at what the player chose, b. swing a block of code temporarily down an alternate track based on that c. remind the player what they chose (and list it in the .DEBUG for troubleshooting) d. then bring everything back to order. So, CODE ACTION_MATCH ~var~ WITH 1 BEGIN <<do case 1 >> END 2 BEGIN <<or else do case 2 >> END DEFAULT <<or if neither 11 nor 2, then do case 3/default actions >> END In Aran's implementation (tested and works; horribly clumsy though), instead of talking I commented stuff: CODE /* Installing one of the 5 forced subcomponents does OUTER_SET class_choice = 1 or 2 or 3 or 4 or 5 (5 = no player choices wanted). */ DEFINE_ACTION_MACRO customized_cre_choice BEGIN // define the instruction set to be called in other places ACTION_MATCH ~%class_choice%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 1 // the first check. If %class_choice% = 1, the next stuff will work, else check the next BEGIN /* mage dual-class build */ LAUNCH_ACTION_MACRO aran_wealth_selection LAUNCH_ACTION_MACRO aran_mage_choice LAUNCH_ACTION_MACRO aran_armor_choice ACTION_MATCH ~%aran_wealth%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 3 BEGIN PRINT ~Aran is successful~ END 2 BEGIN PRINT ~Aran is of average wealth~ END DEFAULT PRINT ~Aran is down-and-out poor~ END ACTION_MATCH ~%aran_armor_choice%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 1 BEGIN PRINT ~Leather Armor~ END 2 BEGIN PRINT ~Studded Leather Armor~ END 3 BEGIN PRINT ~Chain Mail~ END 4 BEGIN PRINT ~Splint Mail~ END DEFAULT PRINT ~Plate Armor~ END /* we are using READLN values to set a variable - the mod range of possible combos is 1 to 15 inclusive, so we can't just read it directly */ ACTION_MATCH ~%weapon_choices%~ // check this value WITH // against the following 3 cases, so 1 BEGIN OUTER_SET ~aran_weapon_set~ = 1 // Long Sword, Shield, Dagger PRINT ~Long Sword, Shield, Dagger~ PRINT ~~ END 2 BEGIN OUTER_SET ~aran_weapon_set~ = 2 // Long Sword, Shield, Quarterstaff PRINT ~Long Sword, Shield, Quarterstaff~ PRINT ~~ END 3 BEGIN OUTER_SET ~aran_weapon_set~ = 3 // Long Sword, Shield, Potions of healing PRINT ~Long Sword, Shield, Potions of Healing~ PRINT ~~ END DEFAULT // this should never run, but as an emergency fallback OUTER_SET ~aran_weapon_set~ = 6 // Long Sword, Shield, Long Bow PRINT ~Long Sword, Shield, Long Bow~ PRINT ~~ END COPY ~aranw/cre/c-arnmge.cre~ ~override/c-aran7.cre~ // copy the base .cre into the game, and LAUNCH_PATCH_MACRO ~aran_cre_setup~ // patch in player choices using this pre-defined code END // of dual-to-mage swing 2 // the second check. If %class_choice% = 2, the next stuff will work, else check the next BEGIN /* cleric dual-class build */ LAUNCH_ACTION_MACRO aran_wealth_selection LAUNCH_ACTION_MACRO aran_cleric_choice LAUNCH_ACTION_MACRO aran_armor_choice ACTION_MATCH ~%aran_wealth%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 3 BEGIN PRINT ~Aran is successful~ END 2 BEGIN PRINT ~Aran is of average wealth~ END DEFAULT PRINT ~Aran is down-and-out poor~ END ACTION_MATCH ~%aran_armor_choice%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 1 BEGIN PRINT ~Leather Armor~ END 2 BEGIN PRINT ~Studded Leather Armor~ END 3 BEGIN PRINT ~Chain Mail~ END 4 BEGIN PRINT ~Splint Mail~ END DEFAULT PRINT ~Plate Armor~ END ACTION_MATCH ~%weapon_choices%~ // check this value WITH // against the following 3 cases, with 4 or anything else defaulting to a '"standard choice" 1 BEGIN OUTER_SET ~aran_weapon_set~ = 4 // Long Sword, Shield, Mace PRINT ~Long Sword, Shield, Mace~ PRINT ~~ END 2 BEGIN OUTER_SET ~aran_weapon_set~ = 2 // Long Sword, Shield, Quarterstaff PRINT ~Long Sword, Shield, Mace~ PRINT ~~ END 3 BEGIN OUTER_SET ~aran_weapon_set~ = 12 // Long Sword, Shield, Hammer PRINT ~Long Sword, Shield, Mace~ PRINT ~~ END DEFAULT // this will run on 4, or as an emergency fallback OUTER_SET ~aran_weapon_set~ = 5 // Long Sword, Shield, Flail PRINT ~Long Sword, Shield, Flail~ PRINT ~~ END COPY ~aranw/media/c-arnclr.cre~ ~override/c-aran7.cre~ // the cleric stat L7 .cre LAUNCH_PATCH_MACRO ~aran_cre_setup~ // patch in player choices using this pre-defined code END // of dual-to-cleric swing 3 // the third check. If %class_choice% = 3, the next stuff will work, else check the next BEGIN /* fighter single-class build */ LAUNCH_ACTION_MACRO aran_wealth_selection LAUNCH_ACTION_MACRO aran_fighter_choice LAUNCH_ACTION_MACRO aran_armor_choice ACTION_MATCH ~%aran_wealth%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 3 BEGIN PRINT ~Aran is successful~ END 2 BEGIN PRINT ~Aran is of average wealth~ END DEFAULT PRINT ~Aran is down-and-out poor~ END ACTION_MATCH ~%aran_armor_choice%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 1 BEGIN PRINT ~Leather Armor~ END 2 BEGIN PRINT ~Studded Leather Armor~ END 3 BEGIN PRINT ~Chain Mail~ END 4 BEGIN PRINT ~Splint Mail~ END DEFAULT PRINT ~Plate Armor~ END ACTION_MATCH ~%weapon_choices%~ // check this value WITH // against the following 3 cases, with 4 or anything else defaulting to a '"standard choice" 1 BEGIN OUTER_SET ~aran_weapon_set~ = 1 // Long Sword, Shield, Dagger PRINT ~Long Sword, Shield, Dagger~ PRINT ~~ END 2 BEGIN OUTER_SET ~aran_weapon_set~ = 6 // Long Sword, Shield, Long Bow PRINT ~Long Sword, Shield, Long Bow~ PRINT ~~ END 3 BEGIN OUTER_SET ~aran_weapon_set~ = 3 // Long Sword, Shield, Potions of healing PRINT ~Long Sword, Shield, Potions of healing~ PRINT ~~ END 4 BEGIN OUTER_SET ~aran_weapon_set~ = 7 // Bastard Sword, Shield, Dagger PRINT ~Bastard Sword, Shield, Dagger~ PRINT ~~ END 5 BEGIN OUTER_SET ~aran_weapon_set~ = 8 // Bastard Sword, Shield, Long Bow PRINT ~Bastard Sword, Shield, Long Bow~ PRINT ~~ END DEFAULT // this will run on 6, or as an emergency fallback OUTER_SET ~aran_weapon_set~ = 12 // Long Sword, Shield, Hammer PRINT ~Long Sword, Shield, Hammer~ PRINT ~~ END COPY ~aranw/cre/c-arnftr.cre~ ~override/c-aran7.cre~ // the fighter stat L7 .cre LAUNCH_PATCH_MACRO ~aran_cre_setup~ // patch in player choices using this pre-defined code END // of just-a-fighter swing 4 // the second check. If %class_choice% = 4, the next stuff will work, else check the next BEGIN /* thief dual-class build */ LAUNCH_ACTION_MACRO aran_wealth_selection LAUNCH_ACTION_MACRO aran_thief_choice LAUNCH_ACTION_MACRO aran_armor_choice ACTION_MATCH ~%aran_wealth%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 3 BEGIN PRINT ~Aran is successful~ END 2 BEGIN PRINT ~Aran is of average wealth~ END DEFAULT PRINT ~Aran is down-and-out poor~ END ACTION_MATCH ~%aran_armor_choice%~ // the thing we are checking to allow the code to "swing" to variants, the "case" WITH 1 BEGIN PRINT ~Leather Armor~ END 2 BEGIN PRINT ~Studded Leather Armor~ END 3 BEGIN PRINT ~Chain Mail~ END 4 BEGIN PRINT ~Splint Mail~ END DEFAULT PRINT ~Plate Armor~ END ACTION_MATCH ~%weapon_choices%~ // check this value WITH // against the following 3 cases, with 4 or anything else defaulting to a '"standard choice" 1 BEGIN OUTER_SET ~aran_weapon_set~ = 1 // Long Sword, Shield, Dagger PRINT ~Long Sword, Shield, Dagger~ PRINT ~~ END 2 BEGIN OUTER_SET ~aran_weapon_set~ = 9 // Long Sword, Shield, Crossbow PRINT ~Long Sword, Shield, Crossbow~ PRINT ~~ END 3 BEGIN OUTER_SET ~aran_weapon_set~ = 3 // Long Sword, Shield, Potions of healing PRINT ~Long Sword, Shield, Potions of healing~ PRINT ~~ END 4 BEGIN OUTER_SET ~aran_weapon_set~ = 10 // Short Sword, Shield, Dagger PRINT ~Short Sword, Shield, Dagger~ PRINT ~~ END DEFAULT // this will run on 5, or as an emergency fallback OUTER_SET ~aran_weapon_set~ = 11 // Short Sword, Shield, Crossbow PRINT ~Short Sword, Shield, Crossbow~ PRINT ~~ END COPY ~aranw/cre/c-arnthf.cre~ ~override/c-aran7.cre~ // the thief stat L7 .cre LAUNCH_PATCH_MACRO ~aran_cre_setup~ // patch in player choices using this pre-defined code END // of dual-to-thief swing DEFAULT // the fall-through check. If %class_choice% was not 1, 2, 3, or 4, the default code will run PRINT ~No class choice was chosen... installing Aran's Default (Fighter, moderate wealth, long sword and bow)~ /* Set up the variables for a default .cre so BWP folks don't have to deal with READLN */ OUTER_SET ~aran_wealth~ = 2 // experienced mercenary with some resources OUTER_SET ~aran_weapon_set~ = 6 // Long Sword, Shield, Long Bow OUTER_SET ~aran_armor_choice~ = 4 // splint COPY ~aranw/cre/c-arnftr.cre~ ~override/c-aran7.cre~ // the fighter stat L7 .cre LAUNCH_PATCH_MACRO ~aran_cre_setup~ // patch in player choices using this pre-defined code END // of default swing END // of define action macro This usage is interesting to me in that it shows how you can nest both macros and ACTION_MATCH WITH . It is a criminal waste of space to use this for just PRINT materials the way I have; the better usage would be to fully convert the various PATCH_IF statements and that whole pyramid of materials found in aran_cre_setup into a better/tighter logic chain, so that i could do away with SUBCOMPONENT entirely. Using this idea, the whole thing could be built into one component, and we could ask "Default, or choice?" and then if a person chose choice, they could run everything through a single run of code that asked and adjusted for responses. To do this, instead of using LAUNCH_PATCH_MACRO ~aran_cre_setup~ the currently unchanged contents of aran_cre_setup's PATCH_IF statements would be integrated into the above.
  10. One fun thing about RP that BG2 blows completely out of the water is equipment choice, level, and relative wealth. Well, OK, so there are many areas where it differs from a P&P AD&D game, but there are lots of mods out there to fix some of this... but for Aran, let's give the players some choice. From a RP perspective, it is silly for a L7 fighter to not have a decent magical weapon, good armor, and perhaps even some supplies. I have never been a mercenary, but I would assume that they are like musicians in one respect - a horn player will eat nothing but crackers for days/weeks/months/years before giving up his horn. After all, how are you going to work your way out of debt if you have a garbage old beat-up single Conn, and everyone else is showing up with pro equipment, well maintained and well rehearsed in its strengths and weaknesses in relation to your playing style? And that is not a matter of life and death, like a good shield or sword might be. So we can mess about with helping Aran have gear. We can even let players decide: Is Aran down-and-out poor, having sold off his best gear? Is Aran treasure-poor but equipped with decent L7 equipment? Is Aran equipped with the best equipment possible, because I am going to dual-class him and take his gear so I can be L33T and overpowered, at least up until I run into the first SCSII-enhanced gibberling? Heck, we can take that one step farther. We can set up those four choices of stats with appropriate proficiencies, and give players choice over what gear he has. That could be modified by what RP option was chosen about his relative equipment wealth; if he is poor and down-and-out, he might have a regular mundane long sword, but if he is average that will be a +1 long sword, and if he has been successful he may be starving but he won't stop gripping the pommel of that +2 long sword until he is forced to. OK, lots of fun - lots of choice; that brings up two additional considerations. Q. Why not give the player full choice of everything? A. I've watched Nythrun, and I'm no Nythrun. Between eric, miloch, and Nythrun, Level1NPCs will eventually allow people to completely respec Aran any way they want. I'm counting on that - why else would I be adding dialog options that check to see if Aran is CLERIC_ALL, or MAGE_ALL, or KIT:HEARTWARDER_OF_SUNE and such? Plus, there is a defining of character that can take place. If Aran is setting up to Dual to Cleric, my take is that he would be messing around with many different cleric-able weapons, but not specializing in any of them. After all, his primary start is sword and board, and he is not driven to excel in one specific focused area. Aran as a Kensai? Have you heard him talk? The level of precision and self-control necessary for Bushido does not seem likely to be something Aran would be able to handle. So from a RP standpoint, keeping within character, I can set up some baselines that fit his personality, confident that eventually folks will get to L1NPC him into that magical Kensai->Mage dual class for their power-gaming run. Q. What about the confusing raft of choices? I just want to play - worse, I have a BWP install, and I don't understand all the custom install templates. Why can't I just install him and be done with it? A. Good point. BWP has solved user input at install through scripting, but it can be a huge job to understand what is going on. So, a 'default' configuration needs to be available, so the user does not have to make tons of choices if they don't want to. OK, so on to implementing this mess of choices. MARCO-ME (ok, ok, pun intended. Macrame. Feeble humor, but that's what I got.) Before we get started on implementing this, though, let's mess around with a fancy thing called DEFINE_PATCH_MACRO. Say I have 4 or 5 .cres (or even more) that have the same stuff done to them, with very minor variations. The regular way is to declare everything out front - 5, or 6 variations on CODE /* Area C-AW01 Entry Point - Bouncer on Promenade */ COPY_EXISTING ~kpgrd01.cre~ ~override/c-aw01ep.cre~ SAY NAME1 ~Manson~ SAY NAME2 ~Manson~ REMOVE_CRE_ITEM ~rndtre02~ WRITE_LONG INITIAL_MEETING (BNOT 0x0) WRITE_LONG DIALOGUE_HOSTILE (BNOT 0x0) WRITE_LONG MORALE (BNOT 0x0) WRITE_LONG HAPPY (BNOT 0x0) WRITE_LONG UNHAPPY_ANNOYED (BNOT 0x0) WRITE_LONG UNHAPPY_SERIOUS (BNOT 0x0) WRITE_LONG UNHAPPY_BREAKING (BNOT 0x0) WRITE_LONG LEADER (BNOT 0x0) WRITE_LONG TIRED (BNOT 0x0) WRITE_LONG BORED (BNOT 0x0) WRITE_LONG BATTLE_CRY1 (BNOT 0x0) WRITE_LONG BATTLE_CRY2 (BNOT 0x0) WRITE_LONG BATTLE_CRY3 (BNOT 0x0) WRITE_LONG BATTLE_CRY4 (BNOT 0x0) WRITE_LONG BATTLE_CRY5 (BNOT 0x0) WRITE_LONG HURT (BNOT 0x0) WRITE_LONG AREA_FOREST (BNOT 0x0) WRITE_LONG AREA_CITY (BNOT 0x0) WRITE_LONG AREA_DUNGEON (BNOT 0x0) WRITE_LONG AREA_DAY (BNOT 0x0) WRITE_LONG AREA_NIGHT (BNOT 0x0) WRITE_LONG SELECT_COMMON1 (BNOT 0x0) WRITE_LONG SELECT_COMMON2 (BNOT 0x0) WRITE_LONG SELECT_COMMON3 (BNOT 0x0) WRITE_LONG SELECT_COMMON4 (BNOT 0x0) WRITE_LONG SELECT_COMMON5 (BNOT 0x0) WRITE_LONG SELECT_COMMON6 (BNOT 0x0) WRITE_LONG SELECT_ACTION1 (BNOT 0x0) WRITE_LONG SELECT_ACTION2 (BNOT 0x0) WRITE_LONG SELECT_ACTION3 (BNOT 0x0) WRITE_LONG SELECT_ACTION4 (BNOT 0x0) WRITE_LONG SELECT_ACTION5 (BNOT 0x0) WRITE_LONG SELECT_ACTION6 (BNOT 0x0) WRITE_LONG SELECT_ACTION7 (BNOT 0x0) WRITE_LONG SELECT_RARE1 (BNOT 0x0) WRITE_LONG SELECT_RARE2 (BNOT 0x0) WRITE_LONG CRITICAL_HIT (BNOT 0x0) WRITE_LONG CRITICAL_MISS (BNOT 0x0) WRITE_LONG TARGET_IMMUNE (BNOT 0x0) WRITE_LONG INVENTORY_FULL (BNOT 0x0) WRITE_LONG PICKED_POCKET (BNOT 0x0) WRITE_LONG HIDDEN_IN_SHADOWS (BNOT 0x0) WRITE_LONG SPELL_DISRUPTED (BNOT 0x0) WRITE_LONG SET_A_TRAP (BNOT 0x0) WRITE_LONG BIO (BNOT 0x0) WRITE_EVALUATED_ASCII 0x34 ~%DEST_RES%~ #8 /* small portrait */ WRITE_ASCII 0x248 ~None~ #8 /* override AI script */ WRITE_ASCII 0x250 ~None~ #8 /* disable class AI script */ WRITE_ASCII 0x258 ~None~ #8 /* disable race AI script */ WRITE_ASCII 0x260 ~None~ #8 /* disable general AI script */ WRITE_ASCII 0x268 ~None~ #8 /* disable default AI script */ WRITE_EVALUATED_ASCII 0x2cc ~%DEST_RES%~ #8 /* dialogue */ WRITE_EVALUATED_ASCII 0x280 ~%DEST_RES%~ #32 /* death variable */ But what if I could work this out with just one line, instead of everything? I can... CODE COPY_EXISTING ~kpgrd01.cre~ ~override/c-aw01ep.cre~ /* Area C-AW01 Entry Point - Bouncer on Promenade */ SAY NAME1 ~Manson~ SAY NAME2 ~Manson~ REMOVE_CRE_ITEM ~rndtre02~ LAUNCH_PATCH_MACRO ~support_cre_cleanup~ ... if I set up what I want to happen in a macro, like this... CODE DEFINE_PATCH_MACRO ~support_cre_cleanup~ BEGIN WRITE_LONG INITIAL_MEETING (BNOT 0x0) WRITE_LONG DIALOGUE_HOSTILE (BNOT 0x0) WRITE_LONG MORALE (BNOT 0x0) WRITE_LONG HAPPY (BNOT 0x0) WRITE_LONG UNHAPPY_ANNOYED (BNOT 0x0) WRITE_LONG UNHAPPY_SERIOUS (BNOT 0x0) WRITE_LONG UNHAPPY_BREAKING (BNOT 0x0) WRITE_LONG LEADER (BNOT 0x0) WRITE_LONG TIRED (BNOT 0x0) WRITE_LONG BORED (BNOT 0x0) WRITE_LONG BATTLE_CRY1 (BNOT 0x0) WRITE_LONG BATTLE_CRY2 (BNOT 0x0) WRITE_LONG BATTLE_CRY3 (BNOT 0x0) WRITE_LONG BATTLE_CRY4 (BNOT 0x0) WRITE_LONG BATTLE_CRY5 (BNOT 0x0) WRITE_LONG HURT (BNOT 0x0) WRITE_LONG AREA_FOREST (BNOT 0x0) WRITE_LONG AREA_CITY (BNOT 0x0) WRITE_LONG AREA_DUNGEON (BNOT 0x0) WRITE_LONG AREA_DAY (BNOT 0x0) WRITE_LONG AREA_NIGHT (BNOT 0x0) WRITE_LONG SELECT_COMMON1 (BNOT 0x0) WRITE_LONG SELECT_COMMON2 (BNOT 0x0) WRITE_LONG SELECT_COMMON3 (BNOT 0x0) WRITE_LONG SELECT_COMMON4 (BNOT 0x0) WRITE_LONG SELECT_COMMON5 (BNOT 0x0) WRITE_LONG SELECT_COMMON6 (BNOT 0x0) WRITE_LONG SELECT_ACTION1 (BNOT 0x0) WRITE_LONG SELECT_ACTION2 (BNOT 0x0) WRITE_LONG SELECT_ACTION3 (BNOT 0x0) WRITE_LONG SELECT_ACTION4 (BNOT 0x0) WRITE_LONG SELECT_ACTION5 (BNOT 0x0) WRITE_LONG SELECT_ACTION6 (BNOT 0x0) WRITE_LONG SELECT_ACTION7 (BNOT 0x0) WRITE_LONG SELECT_RARE1 (BNOT 0x0) WRITE_LONG SELECT_RARE2 (BNOT 0x0) WRITE_LONG CRITICAL_HIT (BNOT 0x0) WRITE_LONG CRITICAL_MISS (BNOT 0x0) WRITE_LONG TARGET_IMMUNE (BNOT 0x0) WRITE_LONG INVENTORY_FULL (BNOT 0x0) WRITE_LONG PICKED_POCKET (BNOT 0x0) WRITE_LONG HIDDEN_IN_SHADOWS (BNOT 0x0) WRITE_LONG SPELL_DISRUPTED (BNOT 0x0) WRITE_LONG SET_A_TRAP (BNOT 0x0) WRITE_LONG BIO (BNOT 0x0) WRITE_EVALUATED_ASCII 0x34 ~%DEST_RES%~ #8 /* small portrait */ WRITE_ASCII 0x248 ~None~ #8 /* override AI script */ WRITE_ASCII 0x250 ~None~ #8 /* disable class AI script */ WRITE_ASCII 0x258 ~None~ #8 /* disable race AI script */ WRITE_ASCII 0x260 ~None~ #8 /* disable general AI script */ WRITE_ASCII 0x268 ~None~ #8 /* disable default AI script */ WRITE_EVALUATED_ASCII 0x2cc ~%DEST_RES%~ #8 /* dialogue */ WRITE_EVALUATED_ASCII 0x280 ~%DEST_RES%~ #32 /* death variable */ END Easy, huh? With this predefined snippet of code I can slap most of the .cre silent, set the portrait and dialog and dv and anything else I want to the name of the .cre, disabled the scripts I don't want - everything in one swoop. DEFINE_PATCH_MACRO basically says "here is a list of things I want to do within a patching operation". Putting it at the top of your mod or component means later on, instead of writing it all out or copying and pasting blocks, you can refer to it buy using LAUNCH_PATCH_MACRO. Now, how can we leverage this a bit more, to make life easier? We have to come up with a way to set some of the choices above to "variables", so we can... duh... vary them. We actually already have, because we have leveraged the bigg's WeiDU variables, %DEST_RES%, which equals the name of the resource being worked on by the code at the moment (See Mike1072's post below for a clearer explanation of this). Let's play with this idea for Aran. First off, we want 4 basic choices, as we have said before - Tinker, Tailor, Soldier, Spy (Dual-Classable stats for Ftr->Mage, Ftr->Cleric, Fighter, Ftr->Thief). We would also like to be able to choose some basic equipment and armor, and perhaps roleplay the level of gear he has. We also need a "yeah, whatever - stop messing about and just install the damned NPC and let's get on with it" option. But we can make it much more far-reaching than that. We can let the user choose some of the input.
  11. Well, I started awhile ago on this, asking folks for input, and got some, so it is probably time to figure out where he really goes. Synopsis We want to tell the game where Aran is supposed to meet the party - where he "spawns" in-game. To do that, we use WeiDU to add him in, first having researched area, x.y coordinates, and extended that area's script with the instructions to do so. In addition, we want to allow players to choose where he goes, but they have to choose one area out of the pool of choices, and the instructions must be run out (can' be skipped or uninstalled without replacement, or he will never spawn for players). Starting at Providing Choices In The .tp2 There are some cool ways of getting player input, including very customizable things like ACTION_READLN and setting up multiple components. There are some advantages to READLN we have already discussed, so let's go to a simple way of adding a player choice to an install - SUBCOMPONENT and FORCED_SUBCOMPONENT. Regular WeiDU installation Choices; Simple. Effective. And They Can Roll Back. In our regular WeiDU installation, the easiest way to let things work is to create a separate component and let players choose what they want to install, like this: BEGIN ~This is the first component in my mod.~ BEGIN ~This is the second component in my mod.~ Simple enough, though sometimes it feels odd to do a BEGIN without an END, but don't complain to the bigg - that is way way legacy stuff that can't be changed without messing up about everything out there already coded. He didn't write it like that - it came that way from back in the day, and we need it to say how the game will play. Darn - almost made that work, but it got confusing. Basically, if we want to be able to use older mods, we need backwards compatibility, and the bigg has to stick within certain constraints, this being one of them. With this example above, all we are saying is "WeiDU, do this first set of instructions." "WeiDU, do this second set of instructions." So, a mod .tp2 might have something like BEGIN ~This is the first coponent in my mod. Aran is starting in Candlekeep.~ EXTEND_BOTTOM ~CANDLEKEEP.ARE~ ~aranw/baf/starting_area.baf~ BEGIN ~This is the second coponent in my mod. Aran is starting in East Timbuktoo~ EXTEND_BOTTOM ~EAST_TIMBUKTOO.ARE~ ~aranw/baf/starting_area.baf~ This lets the player choose to install component 1, Candlekeep start, or to install component 2, African Safari start, and we have accomplished our mission. Except... under this configuration, the player could choose 1 AND 2. They could choose 1 OR 2.They could choose 1. They could choose 2. Or they could skip both. Worst of all from a mod author's standpoint, they could choose both, then uninstall them both, and then come complaining when Aran doesn't show up in the game... so we probably do not want to do the installation choice this way. HEY - why don't we use READLN? I mean, it is simple enough - the code is out there, and wee have already gone through it in another post - why would we *not* use that fancy way of creating choice for the player in this instance? Two words... Weidu. Log. When WeiDU puts out the central log of everything, it sees components that are installed. The .DEBUG created from your mod install has lots of cool information for troubleshooting, but standard practice for troubleshooting is to get the big, obvious text file in the game folder named "weidu.log" and use it to determine if things have gone right or wrong in a player's game. Those entries are *only* mod components installed, not the READLN choices, because the WeiDU.log serves a cool purpose - it helps weidu operate. Cluttering it up with inner actions of a component would mess it up, as will PRINT and other commands within your .tp2. Basically, it is an index of mod components, not a listing of every single change to your game in great detail. Here is a sample entry in the weidu.log after installation: Now, I can go with a "list every component approach, like Fixpack: but we just figured out I don't want that approach, because with Fixpack we want players to be able to install and uninstall various things as they choose. With the spawining area, this is not such a good idea. Not only do we want players to choose one, we want them to be required to choose one of several choices, or have the mod pull itself out - because if you can't spawn him, it is just as bad if you have him popping up in a dozen areas, all coming up to various versions of himself like in Multiplicity, saying "Hey, you look familiar - what a handsome dude you are. You got any work?" And READLN doesn't leave a clue in the weidu.log as to which choice the player has made, so 3/4 of the way through a Mega-BGT-BP, when a player is completely confsed, and wants to go pick up Aran, We can't go "gee... do you remember where you told him to spawn, three months ago, while you were spending hours staring at your computer screen willing the installation to move faster?" So we want 1. a way that weidu will ask the player to choose from a panel of choices 2. allow weidu the ability to report which choice was made 3. require/demand/insist/not proceed until the player chooses one of the panel of choices. Enter the world of SUBCOMPONENT | FORCED_SUBCOMPONENT (tadaa!) Let's go back to Grim Squeaker's Tyris Flare mod for a second. I only posted a portion of the Weidu.log. The full entry for Tyris looks like this: Now, that is pretty cool. Grim Squeaker has a second component, that allows players to choose an alternate portrait. Let's look at how it got coded: BEGIN ~Alternate Portrait 1~ DESIGNATED 101 REQUIRE_COMPONENT ~Setup-TyrisFlare.tp2~ ~0~ ~NPC is not installed, therefore skipping alternate portraits...~ SUBCOMPONENT ~Alternate Tyris Portraits~ COPY ~TyrisFlare/Portraits/Alternate1/G#TYRISL.bmp~ ~override/G#TYRISL.bmp~ ~TyrisFlare/Portraits/Alternate1/G#TYRISM.bmp~ ~override/G#TYRISM.bmp~ ~TyrisFlare/Portraits/Alternate1/G#TYRISS.bmp~ ~override/G#TYRISS.bmp~ BEGIN ~Alternate Portrait 2~ SUBCOMPONENT ~Alternate Tyris Portraits~ COPY ~TyrisFlare/Portraits/Alternate2/G#TYRISL.bmp~ ~override/G#TYRISL.bmp~ ~TyrisFlare/Portraits/Alternate2/G#TYRISM.bmp~ ~override/G#TYRISM.bmp~ ~TyrisFlare/Portraits/Alternate2/G#TYRISS.bmp~ ~override/G#TYRISS.bmp~ BEGIN ~Alternate Portrait 3~ SUBCOMPONENT ~Alternate Tyris Portraits~ COPY ~TyrisFlare/Portraits/Alternate3/G#TYRISL.bmp~ ~override/G#TYRISL.bmp~ ~TyrisFlare/Portraits/Alternate3/G#TYRISM.bmp~ ~override/G#TYRISM.bmp~ ~TyrisFlare/Portraits/Alternate3/G#TYRISS.bmp~ ~override/G#TYRISS.bmp~ BEGIN ~Alternate Portrait 4~ SUBCOMPONENT ~Alternate Tyris Portraits~ COPY ~TyrisFlare/Portraits/Alternate4/G#TYRISL.bmp~ ~override/G#TYRISL.bmp~ ~TyrisFlare/Portraits/Alternate4/G#TYRISM.bmp~ ~override/G#TYRISM.bmp~ ~TyrisFlare/Portraits/Alternate4/G#TYRISS.bmp~ ~override/G#TYRISS.bmp~ The initial DESIGNATED 101 is a way of telling weidu that the modder wants this component to be labled 101, even if it is component 2 of 2. Ordinarily, Weidu decides component numbers on the fly, based on what it sees - a component can get swapped around in install order over the course of development, etc. This DESIGNATED locks the component number. You might want to do this if you are making sure things remain available to check for over time by other modders, so that if they put something like line 2, REQUIRE_COMPONENT, or FORBID_COMPONNT, or anything else in that series of choices, the numbering is right. Here, an example. Pretend I made a mod that Grim Squeaker had contributed to that already had Tyris' portarit choice in it. Because he put DESIGNATED 101, I can use that number to avoid duplication - FORBID_COMPONENT ~Setup-TyrisFlare.tp2~ ~101~ ~Tyris Flare's Alternate Portraits are already installed, therefore skipping alternate Tyris portraits...~ and he he could add [FORBID_COMPONENT ~setup-cmorgans_massive_portrait_pack.tp2~ ~27~ ~Sorry, you already chose Tyris' portrait, therefore skipping alternate portraits...~ Of course, if I did not use DESIGNATED 27, and I added another component, it would become component 28, and then Grim is messed up bad - so usig DESIGNATED can help with things like this. Why not just do it Old Skool, and go with BEGIN ~Alternate Portrait 1~ BEGIN ~Alternate Portrait 2~ BEGIN ~Alternate Portrait 3~ BEGIN ~Alternate Portrait 4~ Well... becuse players dont want to be bothered with picking and choosing components for every mod. Some folks would just install everything. Under that setup, Tyris would have her original portrait. Then Alternate 1 would be added. Then Alternate 2, then 3, then 4, each overwriting the last. And the end result would be that most installs of Tyris Flare would use Alternate Portrait v4, and there would be a bunch of extra lines in the weidu.log, and it would be silly. So, putting these into So, next line is already covered. He has 4 components, BEGIN ~Alternate Portrait 1~ BEGIN ~Alternate Portrait 2~ BEGIN ~Alternate Portrait 3~ BEGIN ~Alternate Portrait 4~ Why not just do it Old Skool, and go with this as is? Well... because players don't want to be bothered with picking and choosing components for every mod. Or reading README's and figuring out that they are installing something that does exactly the same thing over the top of what they just chose. Some folks would just install everything. Under that setup, Tyris would have her original portrait. Then Alternate 1 would be added. Then Alternate 2, then 3, then 4, each overwriting the last. And the end result would be that most installs of Tyris Flare would use Alternate Portrait v4, and there would be a bunch of extra lines in the weidu.log, and it would be silly. So, putting these into a new format wuill avoid this. As a side note, he has made them all dependent on Tyris being installed, which is generally a good thing for mod-specific content changes. You don't want players adding stuff that has no use in-game, or worse - if this component had tried to edit Tyris' .cre, the mod component would fail and stop installation with an error message about missing the .cre. So, a line that requires that the central component of Tyris Flare be installed, looking for component ~0~. Adding this line back into our deconstruction - BEGIN ~Alternate Portrait 1~ DESIGNATED 101 REQUIRE_COMPONENT ~Setup-TyrisFlare.tp2~ ~0~ ~NPC is not installed, therefore skipping alternate portraits...~ BEGIN ~Alternate Portrait 2~ BEGIN ~Alternate Portrait 3~ BEGIN ~Alternate Portrait 4~ Now things get fancy. He makes each of these components into be a subset of another component, so that what we originally had as four separate install choices become one of a small group of choices: BEGIN ~Alternate Portrait 1~ DESIGNATED 101 REQUIRE_COMPONENT ~Setup-TyrisFlare.tp2~ ~0~ ~NPC is not installed, therefore skipping alternate portraits...~ SUBCOMPONENT ~Alternate Tyris Portraits~ BEGIN ~Alternate Portrait 2~ SUBCOMPONENT ~Alternate Tyris Portraits~ BEGIN ~Alternate Portrait 3~ SUBCOMPONENT ~Alternate Tyris Portraits~ BEGIN ~Alternate Portrait 4~ SUBCOMPONENT ~Alternate Tyris Portraits~ So far, beautiful. I can adapt the same idea, and go crazy! Except... why SUBCOMPONENT? What happened to the FORCED_ ? Well, Grim Squeaker sent Tyris Flare out into the world with an existing portrait. No player *has* to install *any* of the alternate portrait choices. So under this configuration, the player can choose to skip the whole thing, or choose one of the portraits. I can't do that for Aran's spawning - I only want one of him, and I insist that the player choose one. So, simple enough edit - with Tyris, all I would have to do to make a player not be able to complete the install without the choice being made, is change that SUBCOMPONENT into FORCED_SUBCOMPONENT. Logical, huh.
  12. I have a bunch of macro, written for myself, maybe they might be useful for others. Actually, I'm quite surprised why isn't there a community resourse that would hold a variety of them yet. Macro names are intuitive, required and optional variables are listed in relevant .txt files. Obviously, I don't guarantee anything, anyone can use them in any way and form. Basically, all that needed to use them is to put a line in .tp2, like "INCLUDE ~mymod/lib/g_itm.lib~", and they will be available. They work, but they ARE NOT heavily tested, particularly g_eff.lib (unlikely I will heavily test them myself ever), so use them on your own risk. Tell me if you find a bug, please. Hopefully they will save some time to somebody, at least. edit: the link contains the updates ones, with readme formatting like in weidu readme archive with libs(9 kb) There are 3 libs, see more detailed descriptions in .txt files in the archive: g_itm.lib - item management. Macro: DELETE_CRE_ITEM DELETE_STORE_ITEM DELETE_AREA_ITEM REPLACE_CRE_ITEM REPLACE_STORE_ITEM REPLACE_AREA_ITEM ADD_AREA_ITEM ADD_CRE_ITEM_FLAGS REMOVE_CRE_ITEM_FLAGS g_eff.lib - effect management DEL_SPL_EFF DEL_ITM_EFF DEL_ITM_EQEFF DEL_CRE_EFF DEL_SPL_EFF_ALL DEL_ITM_EFF_ALL ITEM_EFF_TO_SPL ADD_SPL_EFF ADD_ITM_EFF ADD_ITM_EQEFF ADD_CRE_EFF g_cre.lib - only 2 macro so far READ_SOUNDSET WRITE_SOUNDSET
  13. The GROUP flag came about in discussing component management with an abnormally large number of independent components, e.g. BG2 Tweaks, and was added as a feature in WeiDU v192. Previously WeiDU lacked a satisfactory way to organize such a modâ€"the closest feature would be the top level ASK_EVERY_COMPONENT, which only allows for a single all-or-none approach. The solution is a new component flag, GROUP, with the following syntax (and example): GROUP string BEGIN ~100% Learn Spells~ GROUP ~Convenience Tweaks~ // component code BEGIN ~Identify All Items~ GROUP ~Convenience Tweaks~ // component code BEGIN ~Give Edwin his BG2 Stats~ GROUP ~NPC Tweaks~ // component code BEGIN ~ Give Jaheira her BG2 Stats~ GROUP ~NPC Tweaks~ // component code Upon installing the mod, the player is now presented with meta-options on each group at a high level: Would you like to display the category [Convenience Tweaks]? [Y]es/[N]o Would you like to display the category [NPC Tweaks]? [Y]es/[N]o Selecting [N]o on any group suppresses those options from being displayed, leading to a simpler and more controlled installer experience for the player. In the provided example, selecting [N]o to Convenience Tweaks and [Y]es to NPC Tweaks would result in WeiDU starting installation by asking to install the Give Edwin his BG2 Stats component. GROUP operates independently of SUBCOMPONENT, meaning you can use both to organize the mod as needed. A few other items of note: A component can belong to multiple GROUPs; a component is not offered for install if and only if none of its member groups are selected You could, in theory, have two components in the same SUBCOMPONENT grouping but different GROUPs. Don't do this. If some components of a mod are in a GROUP, but others are not, the non-GROUPed components will always be presented. Using a GROUP anywhere in your mod will act as an implied ASK_EVERY_COMPONENT tp2 flag.
  14. The issue here, budding modders and modstresses out there, is that if you use any sort of WEIGHTing for creating new entries in Biobanter DLGs, you have to be sure that you weight beneath all of the states in that DLG which are called by script: such as LOVETALKs, somebody died/somebody was raised talks, etc. Those values are reasonably easy to find using InfExp/NI/DLTCEP's editor (actually, NI's Edit mode in the state trigger list is probably the best way to locate it quickly.) You can also glance at the Banter Packs for "safe" zones for weighting.
  15. SUBCOMPONENTs allow to group together a set of mutually exclusive mod components into a single menu-style selection. The primary purpose of SUBCOMPONENTs is to streamline mod installation and to make life easier for end users. For example, SUBCOMPONENTS are ideal if you wish to provide multiple portrait selections for an NPC mod, have several kits available to one NPC, or for changes that conflict with one another (i.e. raising an XP cap to 10 million or raising it to 20 million). We’ll use the first oneâ€"multiple portrait optionsâ€"as an example. Without SUBCOMPONENTs, the install dialogue would look something like this: Install Component [Delainy Portrait 1 by Bob] [Y]es, [N]o, or [Q]uit Install Component [Delainy Portrait 2 by Fred] [Y]es, [N]o, or [Q]uit Install Component [Delainy Portrait 3 by Wilhelmus] [Y]es, [N]o, or [Q]uit The end user would need to click through the options each time. Worse, conflicting components could be installed. These problems can be limited somewhat by judicious use of predicates, but taking advantage of the SUBCOMPONENT feature yields far superior results: Install Component [Delainy Portrait] [N]o, [Q]uit, or choose one: 1] Portrait 1 by Bob 2] Portrait 2 by Fred 3] Portrait 3 by Wilhelmus Only one of these options can be installed at any time; re-installing and selecting a different SUBCOMPONENT will automatically uninstall the previously installed one. Setting this up is dead simple: BEGIN ~Portrait 1 by Bob~ /* The string above is displayed in the subcomponent listing, i.e. the list with 1] 2] 3] etc. You can, of course, use TRA references instead for this and the SUBCOMPONENT string below. */ SUBCOMPONENT ~Delainy Portrait~ /* The string above is displayed as the component listing and must be the same for each SUBCOMPONENT. The tp2 code that follows is only executed if this SUBCOMPONENT is selected. */ COPY ~Delainy/portraits/opt1G.bmp~ ~override/CDDELAIG.bmp~ COPY ~Delainy/portraits/opt1M.bmp~ ~override/CDDELAIM.bmp~ COPY ~Delainy/portraits/opt1S.bmp~ ~override/CDDELAIS.bmp~ BEGIN ~Portrait 2 by Fred~ SUBCOMPONENT ~Delainy Portrait~ COPY ~Delainy/portraits/opt2G.bmp~ ~override/CDDELAIG.bmp~ COPY ~Delainy/portraits/opt2M.bmp~ ~override/CDDELAIM.bmp~ COPY ~Delainy/portraits/opt2S.bmp~ ~override/CDDELAIS.bmp~ BEGIN ~Portrait 3 by Wilhelmus~ SUBCOMPONENT ~Delainy Portrait~ COPY ~Delainy/portraits/opt3G.bmp~ ~override/CDDELAIG.bmp~ COPY ~Delainy/portraits/opt3M.bmp~ ~override/CDDELAIM.bmp~ COPY ~Delainy/portraits/opt3S.bmp~ ~override/CDDELAIS.bmp~ Any REQUIRE_FILEs or other module requirements for the whole group should be put with the first subcomponent. If such a requirement fails, none of the subcomponents can be installed. In addition, each individual subcomponent can be guarded by its own predicate. If that predicate fails, that particular subcomponent cannot be installed. One note about SUBCOMPONENTs and mod ordering: WeiDU will display SUBCOMPONENTs in a single grouping no matter if they fall consecutively in the tp2 or not. However, the component number (the one that gets placed in weidu.log and the one you check for in REQUIRE_COMPONENT et al) is still based on their tp2 order. Discussion and comments can be handled in this thread.
×
×
  • Create New...