Jump to content


Miloch

Member Since 20 Oct 2006
Offline Last Active Yesterday, 09:55 AM

Topics I've Started

How to change colours

29 January 2012 - 08:08 AM

I'm writing this by request to show how to change NPC colours. Actually, it will work for any creatures that have palettable animations (like humans, elves and hobgoblins). It won't affect non-palettable animations (like orcs and lizardmen). Most typically, this shows how to make sure NPC avatars and paperdolls match mods that give them different portraits. It also demonstrates some basic WeiDU modding fundamentals, though there are other tutorials for that (particularly in the WeiDU documentation).

First, some basics. This is a typical header for a mod's .tp2 installer. This text file is called something like setup-mymod.tp2 or just mymod.tp2. It is executed by a copy of WeiDU.exe renamed to the .tp2 name (setup-mymod.exe).
BACKUP ~adjports/backup~ //Where the mod backs up files
AUTHOR ~www.shsforums.net/forum/584-portrait-mods/~ //Where to submit error reports
VERSION ~v1~
README ~adjports/adjports.html~
BACKUP and AUTHOR are mandatory. VERSION is optional but recommended. It prints the version number in the WeiDU.log file that keeps track of all mods installed. README will ask the user whether to view the readme.

There is also a subheader for each component. Some mods will have only one component; others will have many. In simple form, a component for changing an NPC's colours would look something like this:
BEGIN ~My Portrait Mod~
DESIGNATED 100

ACTION_FOR_EACH npc IN ~aerbod01~ ~aerie12~ ~cwsaer~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%npc%.cre~ BEGIN
    COPY_EXISTING ~%npc%.cre~ ~override~ //Aerie
	  WRITE_BYTE 0x2c 67 //Metal color (shiny gold, was 27 gray)
	  WRITE_BYTE 0x2d 47 //Minor color (pure dark red, was 41 dark brown)
	  WRITE_BYTE 0x2e 2 //Major color (dark gold, was 37 dark dirty yellow)
	  WRITE_BYTE 0x2f 12 //Skin color (light carnation pink)
	  WRITE_BYTE 0x30 16 //Leather color (silver gold, was 93 dark cement gray)
	  WRITE_BYTE 0x31 30 //Armor color (light iron gray)
	  WRITE_BYTE 0x32 115 //Hair color (sunkissed, was 3 light gold)
	BUT_ONLY_IF_IT_CHANGES
  END
END
BEGIN specifies the component name when installing; it is mandatory. DESIGNATED is optional but highly recommended - it hardcodes a component number as appears in the WeiDU.log. It also allows other mods to detect the component and automated programs (such as the BiG World Project) to install the component. If you don't use DESIGNATED, your component numbers will run consecutively from zero. Thus, they will change as you add and remove new components, which isn't a good thing for automation.

The main block is a loop consisting of ACTION_FOR_EACH, ACTION_IF FILE_EXISTS_IN_GAME and COPY_EXISTING. In layman's terms, this feeds a list of filenames to WeiDU (ACTION_FOR_EACH) and says: if each file exists in the game (ACTION_IF ...) then copy it to the override folder (COPY_EXISTING) and make some changes. As for those changes, we are making a series of one-byte changes to the file (WRITE_BYTE). We use an editor (either Near Infinity or DLTCEP) to look up the existing values if we want, the IESDP to find the offsets and the desired colour gradients and their numeric values. Once that is done, we simply plug all that into our patch.

BUT_ONLY_IF_IT_CHANGES (BUT_ONLY for short) says only to copy the file if it is modified by the patches. If, for example, it already has the colour values specified, it will simply be skipped. Two ENDs close out our ACTION loops. That is all you need to do to change an NPC's colours in its simplest form. Like other mods, this will not change any NPC who has already joined the party, as they are stored in the save game.

Here is a slightly more complex example. This component gives two choices for changing Aerie's garb, thus uses SUBCOMPONENT.
BEGIN ~Aerdrie's Garb~
SUBCOMPONENT ~Aerie as Priestess of Aerdrie/Baervan~
DESIGNATED 50
REQUIRE_PREDICATE ((NOT FILE_EXISTS_IN_GAME ~_plat06.itm~) AND ((FILE_EXISTS_IN_GAME ~aerie12.cre~) OR (FILE_EXISTS_IN_GAME ~cwsaer.cre~))) ~Aerie not available~
In this case, SUBCOMPONENT actually indicates the component name, and BEGIN indicates one of several choices the user has. Other choices will follow with their own BEGIN/SUBCOMPONENT sections.

REQUIRE_PREDICATE is a good way to ensure the NPC is present. If the conditions aren't fulfilled, the installer will skip the component and go to the next one. In this case, we want to skip the component if Tutu. Aerie is present but not joinable on Tutu (all BG2 files are). Therefore, we give it a Tutu item _plat06.itm and NOT FILE_EXISTS_IN_GAME for the condition. With the AND we also make sure at least version of Aerie is present (either aerie12 or cwsaer) and pair those with an OR. The whole condition looks like this in simpler terms: (NOT Tutu) AND (aerie12 OR cwsaer). This is followed by a text message (~Aerie not available~) that will display when the installer skips the component.
COPY ~adjports/bmp/t-aeri1l.bmp~ ~override~
	 ~adjports/bmp/t-aeri1m.bmp~ ~override~
	 ~adjports/bmp/t-aeri1s.bmp~ ~override~
The section above copies the portraits for this component. Most people don't do it this way - they overwrite the existing portraits. This demonstrates a way of avoiding that to keep the previous portraits available for other purposes.
ACTION_FOR_EACH tda IN ~aeriend1~ ~aeriend2~ ~aerifnd1~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%tda%.2da~ BEGIN
	COPY_EXISTING ~%tda%.2da~ ~override~ //ToB epilogue tables
	  SET_2DA_ENTRY 1 0 1 ~*T-AERI1L~
	BUT_ONLY
  END
END
That section replaces Aerie's Throne of Bhaal epilogue portrait in the relevant tables. It is only relevant for ToB NPCs, and then only if you don't overwrite the existing portrait.
COPY_EXISTING ~spin745.spl~ ~override~ //Aerie Portrait Spell
  PATCH_IF SOURCE_SIZE > 0x71 BEGIN
	READ_LONG 0x64 hf //Extended header offset
	READ_SHORT 0x68 hc //Extended header count
	READ_LONG 0x6a fb //Feature block offset
	FOR (i1 = 0; i1 < hc; i1 += 1) BEGIN //Cycle through extended headers
	  READ_SHORT (0x28 * i1 + hf + 0x1e) fc //Feature count
	  READ_SHORT (0x28 * i1 + hf + 0x20) fs //Feature offset
	  FOR (i2 = fs; i2 < (fs + fc); i2 += 1) BEGIN //Cycle through ability effects
		READ_SHORT (i2 * 0x30 + fs) opcode
		READ_LONG (i2 * 0x30 + fs + 8) param2
		PATCH_IF (opcode = 107) AND (param2 = 0) BEGIN //If small portrait
		  WRITE_ASCII (i2 * 0x30 + fs + 0x14) ~t-aeri1s~ #8
		END
		PATCH_IF (opcode = 107) AND (param2 = 1) BEGIN //If large portrait
		  WRITE_ASCII (i2 * 0x30 + fs + 0x14) ~t-aeri1m~ #8
		END
	  END
	END
  END
BUT_ONLY
The above section is relevant only to Aerie, as there is a spell effect that morphs her back into avariel form after being an ogre. It specifies her small and medium portraits. I won't detail the code, but it basically loops through all effects attached to the spell and changes those where it finds portraits.
ACTION_FOR_EACH npc IN ~aerbod01~ ~aerie12~ ~cwsaer~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%npc%.cre~ BEGIN
	COPY_EXISTING ~%npc%.cre~ ~override~ //Aerie
	  PATCH_IF SOURCE_SIZE > 0x2d3 BEGIN //Ensures valid .cre file size
		WRITE_BYTE 0x2c 67 //Metal color (shiny gold, was 27 gray)
		WRITE_BYTE 0x2d 47 //Minor color (pure dark red, was 41 dark brown)
		WRITE_BYTE 0x2e 2 //Major color (dark gold, was 37 dark dirty yellow)
		WRITE_BYTE 0x2f 12 //Skin color (light carnation pink)
		WRITE_BYTE 0x30 16 //Leather color (silver gold, was 93 dark cement gray)
		WRITE_BYTE 0x31 30 //Armor color (light iron gray)
		WRITE_BYTE 0x32 115 //Hair color (sunkissed, was 3 light gold)
	  END
	BUT_ONLY_IF_IT_CHANGES
  END
END
Finally, the code above changes her colours as in the first example. For the second subcomponent, we'd copy and paste the same code above and just change the BEGIN name (e.g. to ~Baervan's Garb~), increase the DESIGNATED component number (e.g. to 60), change all the portraits we're copying (e.g. from t-aeri1 to t-aeri2) and finally, change the colours in the second set of code to match her second portrait, following the techique above (i.e. look them up in the IESDP).

Here's the full code for a slightly simpler example. It provides two different examples for Branwen (based on portraits with either brown or purple robes).

There's no ToB Branwen nor morphing spell for her, so we just need to copy the relevant portraits and assign them and the appropriate colours on her .cre files. We do, however, have to check via REQUIRE_PREDICATE that Branwen is present, so we look for Tutu (_branwe5.cre), BGT (branwe5.cre) and at least 4 different mod versions. Apparently, Branwen is a popular gal - you could in theory have a party with you and 5 other Branwens! Ah, the joys of redundant mods, er, I mean user choices.
BEGIN ~Brown Robe~
SUBCOMPONENT ~Branwen as Priestess of Tempus~
DESIGNATED 100
REQUIRE_PREDICATE ((FILE_EXISTS_IN_GAME ~_branwe5.cre~) OR (FILE_EXISTS_IN_GAME ~branwe5.cre~) OR (FILE_EXISTS_IN_GAME ~cb3513bw.cre~) OR (FILE_EXISTS_IN_GAME ~dl#bwn.cre~) OR (FILE_EXISTS_IN_GAME ~ttbran.cre~) OR (FILE_EXISTS_IN_GAME ~wlbran0.cre~)) ~Branwen not available~

COPY ~adjports/bmp/t-bran1l.bmp~ ~override~
	 ~adjports/bmp/t-bran1m.bmp~ ~override~
	 ~adjports/bmp/t-bran1s.bmp~ ~override~

ACTION_FOR_EACH npc IN ~_branwe~ ~_branwe5~ ~branwe~ ~branwe5~ ~cb3513bw~ ~dl#bwn~ ~ttbran~ ~wlbran0~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%npc%.cre~ BEGIN
	COPY_EXISTING ~%npc%.cre~ ~override~ //Branwen
	  PATCH_IF SOURCE_SIZE > 0x2d3 BEGINWeiDU documentation
		WRITE_BYTE 0x2c 67 //Metal color (shiny gold, was 27 gray)
		WRITE_BYTE 0x2d 47 //Minor color (pure dark red, was 41 dark brown)
		WRITE_BYTE 0x2e 2 //Major color (dark gold, was 37 dark dirty yellow)
		WRITE_BYTE 0x2f 12 //Skin color (light carnation pink)
		WRITE_BYTE 0x30 16 //Leather color (silver gold, was 93 dark cement gray)
		WRITE_BYTE 0x31 30 //Armor color (light iron gray)
		WRITE_BYTE 0x32 115 //Hair color (sunkissed, was 3 light gold)
		WRITE_ASCII 0x34 ~t-bran1s~ #8 //Small portrait
		WRITE_ASCII 0x3c ~t-bran1m~ #8 //Large portrait
	  END
	BUT_ONLY_IF_IT_CHANGES
  END
END

BEGIN ~Purple Robe~
SUBCOMPONENT ~Branwen as Priestess of Tempus~
DESIGNATED 105
REQUIRE_PREDICATE ((FILE_EXISTS_IN_GAME ~_plat06.itm~) OR (FILE_EXISTS_IN_GAME ~plat06.itm~)) ~Branwen not found~

COPY ~adjports/bmp/t-bran2l.bmp~ ~override~
	 ~adjports/bmp/t-bran2m.bmp~ ~override~
	 ~adjports/bmp/t-bran2s.bmp~ ~override~

ACTION_FOR_EACH npc IN ~_branwe~ ~_branwe5~ ~branwe~ ~branwe5~ ~cb3513bw~ ~dl#bwn~ ~ttbran~ ~wlbran0~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%npc%.cre~ BEGIN
	COPY_EXISTING ~%npc%.cre~ ~override~ //Branwen
	  PATCH_IF SOURCE_SIZE > 0x2d3 BEGIN
		WRITE_BYTE 0x2c 67 //Metal color (shiny gold, was 27 gray)
		WRITE_BYTE 0x2d 47 //Minor color (pure dark red, was 41 dark brown)
		WRITE_BYTE 0x2e 60 //Major color (dark purple, was 37 dark dirty yellow)
		WRITE_BYTE 0x2f 12 //Skin color (light carnation pink)
		WRITE_BYTE 0x30 16 //Leather color (silver gold, was 93 dark cement gray)
		WRITE_BYTE 0x31 104 //Armor color (dark chrome purple)
		WRITE_BYTE 0x32 115 //Hair color (sunkissed, was 3 light gold)
		WRITE_ASCII 0x34 ~t-bran2s~ #8 //Small portrait
		WRITE_ASCII 0x3c ~t-bran2m~ #8 //Large portrait
	  END
	BUT_ONLY_IF_IT_CHANGES
  END
END
And that's it for a simple component with two different portrait options.

Folks have also asked me how to change the colours of items. Say you've changed the hue of an NPC's special armour in your portrait and you want the item to follow suit. I won't get into how to change the icons. BAM Batcher and your favourite graphics program can do that easily enough, and there are probably other tutorials for that. This changes the colours on the paperdoll and animation or avatar when equipping the item.
BEGIN ~Ankheg Plate matches its icon~
DESIGNATED 25

ACTION_FOR_EACH ank IN ~_plat06~ ~plat06~ BEGIN
  ACTION_IF FILE_EXISTS_IN_GAME ~%ank%.itm~ BEGIN
	COPY_EXISTING ~%ank%.itm~ ~override~ //Ankheg Plate
	  PATCH_IF SOURCE_SIZE > 0x71 BEGIN //Ensures valid .itm file size
		READ_LONG 0x6a eq_off //Equipped effects offset
		READ_SHORT 0x70 eq_cnt //Equipped effects count
		FOR (i1 = 0; i1 < eq_cnt; i1 += 1) BEGIN
		  READ_SHORT (i2 * 0x30 + eq_off) opcode
		  READ_LONG (i2 * 0x30 + eq_off + 8) param2
		  PATCH_IF (opcode = 7) AND (param2 = 5) BEGIN //If armor color
			WRITE_SHORT (i2 * 0x30 + eq_off + 4) 7 //Dark metallic green
		  END
		  PATCH_IF (opcode = 7) AND (param2 = 4) BEGIN //If strap color
			WRITE_SHORT (i2 * 0x30 + eq_off + 4) 1 //Light pure gold
		  END
		  PATCH_IF (opcode = 7) AND (param2 = 0) BEGIN //If belt color
			WRITE_SHORT (i2 * 0x30 + eq_off + 4) 36 //Light dirty yellow
		  END
		END
	  END
	BUT_ONLY
  END
END
Fairly straightforward example for the Ankheg Plate. Following the ACTION... logic described above, the code loops through each version of the item, looks for equipped effects matching certain conditions (opcode 7 for colour effects) and sets them to the relevant colours when it finds the right effects (for armour, strap and belt in this case).

[ART] Undead Sketch

30 September 2011 - 05:49 PM

I would like to commission a sketch of a living undead creature in a tomb - most would recognise it as a "barrow-wight" (actually a Norse draugr). This drawing would be used in a possible book. It needn't be coloured; in fact, black-and-white is better (a high-contrast "pencil" sketch). It should depict a gaunt corpse-like, almost vampiric being in ancient armour (if you know Tolkien, it'd look like one of his "wights" from the Barrow Downs in The Fellowship of the Ring - these creatures were actually based on the draugar from Norse myth). The sketch should depict a passage from the Norse saga of Egil and Asmund. This relates the death of the hero Aran and his subsequent interment in a barrow-mound along with his horse, hawk and hound (extra credit if you can depict those in the background). Asmund enters the barrow mound by rope to watch over the corpse of Aran:

Quote

On the second night he [Aran] got up again from his chair, killed the horse and tore it to pieces; then he took great bites of the horse flesh with his teeth, the blood streaming down from his mouth all the while he was eating. He offered to let Asmund share his meal, but Asmund said nothing. The third night Asmund became very drowsy, and the first thing he knew, Aran had got him by the ears and torn them off. Asmund drew his short-sword and sliced off Aran’s head, then he got some fire and burnt Aran to ashes. Asmund went to the rope and was hauled out of the mound, which was then covered up again.
There is a lot of artistic license there, but I'd like it to look both "Norse" and slightly "vampiric." A successful representation will get the art printed in the book with due credit (and possibly some royalty though I can't guarantee that at this point, as book publication and sales are beyond my control).

If you are interested, please respond to me either via PM or by posting here. Also, if anyone knows of other art forums I could post this on, please let me know.

Edit: As to size, it can be a page or half page of regular paper (A4 or Letter) depending on whether you want to do it "portrait" or "landscape" style (either is fine). Obviously, it can be larger too, since it's easy to downsize if necessary but not upsize images. As to deadlines, by the end of the year hopefully, but the sooner the better.

How to add rumours

06 August 2011 - 01:56 AM

Thought I'd try to post my rumour-adding code (originally used in the Gavin mod) as an actual tutorial. It's fairly straightforward to add tavern rumours, but it requires a bit of hackery to work with BG2. BG1/Tutu rumours are easy, because apparently they have a built in randomiser, but BG2 rumour .dlg files have a hardcoded randomness. So we have to read that and increment it by the number of rumours we're adding, something like this:
//! Dialogue and script compiling (BG2 and BGT) /////////////////////////////
  OUTER_SET t-rda = 14 //Variables that get replaced by random numbers
  OUTER_SET t-rdb = 14
  OUTER_SET t-rdc = 13

  COPY_EXISTING ~rumora.dlg~ ~override~ //Athkatla rumors
    PATCH_IF SOURCE_SIZE > 0x34 BEGIN
      DECOMPILE_DLG_TO_D
        REPLACE_TEXTUALLY CASE_SENSITIVE EXACT_MATCH ~,GLOBAL~ ~,"GLOBAL~
        REPLACE_EVALUATE CASE_INSENSITIVE ~RandomNum(\([0-9]+\),~ BEGIN
          t-rdm = %MATCH1%
          PATCH_IF t-rdm > 11 BEGIN
            t-rda = %MATCH1% + 2
            t-rdb = %MATCH1% + 2
            t-rdc = %MATCH1% + 1
          END ELSE BEGIN
            t-rda = %MATCH1%
          END
        END ~RandomNum(%t-rda%,~
      COMPILE_D_TO_DLG
    END
  BUT_ONLY

  COPY ~mymod/compile/t-rumora.d~ ~mymod/compile/t-rumora.d~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rdb~ ~%t-rdb%~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rdc~ ~%t-rdc%~

  COPY_EXISTING ~rumori.dlg~ ~override~ //Imnesvale rumors
    PATCH_IF SOURCE_SIZE > 0x34 BEGIN
      DECOMPILE_DLG_TO_D
        REPLACE_EVALUATE CASE_INSENSITIVE ~RandomNum(\([0-9]+\),~ BEGIN
          t-rda = %MATCH1% + 2
          t-rdb = %MATCH1% + 1
        END ~RandomNum(%t-rda%,~
      COMPILE_D_TO_DLG
    END
  BUT_ONLY

  COPY ~mymod/compile/t-rumori.d~ ~mymod/compile/t-rumori.d~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rda~ ~%t-rda%~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rdb~ ~%t-rdb%~

  COPY_EXISTING ~rumort.dlg~ ~override~ //Trademeet rumors
    PATCH_IF SOURCE_SIZE > 0x34 BEGIN
      DECOMPILE_DLG_TO_D
        REPLACE_EVALUATE CASE_INSENSITIVE ~RandomNum(\([0-9]+\),~ BEGIN
          t-rda = %MATCH1% + 2
          t-rdb = %MATCH1% + 1
        END ~RandomNum(%t-rda%,~
      COMPILE_D_TO_DLG
    END
  BUT_ONLY

  COPY ~mymod/compile/t-rumort.d~ ~mymod/compile/t-rumort.d~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rda~ ~%t-rda%~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rdb~ ~%t-rdb%~

  COPY_EXISTING ~rumoru.dlg~ ~override~ //Underdark rumors
    PATCH_IF SOURCE_SIZE > 0x34 BEGIN
      DECOMPILE_DLG_TO_D
        REPLACE_EVALUATE CASE_INSENSITIVE ~RandomNum(\([0-9]+\),~ BEGIN
          t-rda = %MATCH1% + 2
          t-rdb = %MATCH1% + 1
        END ~RandomNum(%t-rda%,~
      COMPILE_D_TO_DLG
    END
  BUT_ONLY

  COPY ~mymod/compile/t-rumort.d~ ~mymod/compile/t-rumort.d~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rda~ ~%t-rda%~
    REPLACE_TEXTUALLY CASE_INSENSITIVE ~t-rdb~ ~%t-rdb%~

  COMPILE ~mymod/compile~
The actual dialogues we're compiling look like this (well, they don't really - I've substituted generic text here to avoid spoiling actual mods):
APPEND rumora //Athkatla rumors

IF ~RandomNum(t-rdb,t-rdc)
~ THEN BEGIN t-ath1
  SAY @0 /* ~I heard this about that. Possibly an old wives' tale, but there may be something to it... a traveler from Trademeet said something about this or that too, it seems.~ */
  IF ~~ THEN EXIT
END

//Enables a rumour for all Athkatla rumourmongers *except* Aurora
IF ~RandomNum(t-rdb,t-rdb)
!Dead("agaurora")
!Name("agaurora",Myself)
~ THEN BEGIN t-ath2
  SAY @1 /* ~Think there's a lot of gossip in the taverns? Ha! Go talk to the boot-vendor Aurora in the Bridge District.~ */
  IF ~~ THEN EXIT
END

END

APPEND rumori //Imnesvale rumors

IF ~RandomNum(t-rda,t-rdb)
Global("t-gnome2","GLOBAL",0)
~ THEN BEGIN t-imn1
  SAY @0 /* ~Some damn fool went up north and did something foolish. The fool's been gone for a while now. If the wandering monsters didn't get him, he probably slipped and broke his head.~ */
  IF ~~ THEN EXIT
END

IF ~RandomNum(t-rda,t-rda)
~ THEN BEGIN t-imn2
  SAY @1 /* ~Local legends something about some brave so-and-so and some bad guy who was terrorizing these parts.~ */
  IF ~~ THEN EXIT
END

END

APPEND rumort //Trademeet rumors

IF ~RandomNum(t-rda,t-rdb)
~ THEN BEGIN t-tr1
  SAY @0 /* ~Might want to check the stock in some shop or other, I'd give you more details if this were a real rumor.~ */
  IF ~~ THEN EXIT
END

IF ~RandomNum(t-rda,t-rdb)
!Dead("agkaraea")
~ THEN BEGIN t-tr2
  SAY @1 /* ~This is yet another potentially bogus rumor.~ */
  IF ~~ THEN EXIT
END

END

APPEND rumoru //Underdark rumors

IF ~RandomNum(t-rda,t-rdb)
~ THEN BEGIN t-ud1
  SAY @0 /* ~Dark times indeed, dark even for the Underdark.~ */
  IF ~~ THEN EXIT
END

IF ~RandomNum(t-rda,t-rda)
~ THEN BEGIN t-ud2
  SAY @1 /* ~Blah, blah blah.~ */
  IF ~~ THEN EXIT
END

END
There's one each for Athkatla, Imnesvale, Trademeet and the Underdark. Tutu/BG1/BGT rumours are a bit more straightforward (there are examples of this in the Gavin mod). But it's similar to BG2. You can cover Tutu/BGT/BG1 by using a "tutu_var" that is set to ~_~ if GAME_IS ~tutu tutu_totsc~ but ~~ otherwise (plenty of mods that use this, also covered in posts on gibberlings3.net).

//Baldur's Gate rumours
APPEND %tutu_var%rbaldu

IF ~True()~ THEN BEGIN t-bald1
  SAY @0 /* ~I heard this about that, or maybe that about this.~ */
  IF ~~ THEN EXIT
END
END

//Beregost rumours
APPEND %tutu_var%rbereg

IF ~Global("myvar","GLOBAL",0)
~ THEN BEGIN t-ber1
  SAY @0 /* ~Local legends say that someone vanished to do this, that or perhaps something else entirely.~ */
  IF ~~ THEN UNSOLVED_JOURNAL @1 /* ~Journal heading

We heard about a possible quest to do this and that.~ */ EXIT
END
END

//Candlekeep rumours
APPEND %tutut_var%rcandl

IF ~True()~ THEN BEGIN t-can1
  SAY @0 /* ~I shouldn't be tellin' you much about anything at this point, you neophyte.~ */
  IF ~~ THEN EXIT
END
END

//Friendly Arm rumours
APPEND %tutu_var%rfrien

IF ~Global("myvar2","GLOBAL",0)
~ THEN BEGIN ag_frn1
  SAY @0 /* ~Yet another lead for your foolish band to investigate goes here.~ */
  IF ~~ THEN UNSOLVED_JOURNAL @1 /* ~Journal entry

Sigh, I'm getting sick of these quests, but we heard about this or that again.~ */ EXIT
END
END

//Nashkel rumours
APPEND %tutu_var%rnashk

IF ~True()~ THEN BEGIN t-nsh1
  SAY @0 /* ~There's something odd going on hereabouts, or haven't you heard yet?~ */
  IF ~~ THEN EXIT
END
END
Apparently you can just COMPILE BG1 rumours without doing the fancy jiggling to append random numbers in BG2. (Presumably, these files handle the random weighting internally, though I haven't tested that extensively.) Note that these examples assume you're using .tra files and AUTO_TRA as the WeiDU documentation details. If not, you can omit the @ references and comments and just use plain text (so SAY ~Blah blah blah.~ instead of SAY @1 /* ~Blah blah blah.~ */). Use your own modder's prefix instead of t- and your own mod name instead of mymod, etc. (Also real rumour text instead of generic rubbish heh.)

Iylos CRE file glitches

18 July 2011 - 09:39 PM

Another report from L1NPCs updates. Iylos has a number of questionable EFFs on his CRE file (says Cuv built this but I don't know how or why, unless he was experimenting). For example there are several movement modifiers (opcodes 126 and 176) where I think there should just be one at +2 for monks (and should be opcode 176 to avoid Free Action glitches). Then there are several bogus EFFs of opcode 0 and odd modifiers at the end - normally this is AC bonus which I don't think you want (the engine applies this for monks automatically). There's at least one duplicate opcode 101 with parameter 25 (protection from poison) which also probably duplicates opcode #173. Is he supposed to have immunity to poison? Maybe others - just thought you might want to review it. If you want, I can fix it and attach the update CREs too.

Nephele kit glitch

18 July 2011 - 09:36 PM

I reported this a while back but I'm not sure if you ever saw it - stumbled across it in connection with updating Level 1 NPCs. Nephele gets an applied ability via her kit's CLAB table (lk#neph) that does not exist in your mod - cdhlysym. Almost looks like something from Divine Remix (CamDawg's prefix). If your goal was to grant a holy symbol ability at a certain level, you should substitute a spell of your own. If it's granted via quest or the like, you could omit it entirely.