Jump to content

Adding a trigger to an existing map via WeiDU

Recommended Posts

Foreword: it's my first attempt on creating tutorials of any kind, so any corrections or advices on improving it are welcome.


Acknowledgements: I stole original code from Ghreyfain, who stole it from SimDing0, who in turn supposingly stole it from either CamDawg or CBisson :D, though I make further efforts on improving, simplifying and streamlining it as well as adding few dozens of comments to augment Ghrey' ones.

Original Ghreyfain's post




How to add trigger to an area without overwriting it for WeiDU newbies :p


1. What you should prepare before tinkering with .tp2:

First and foremost - you should get a list of vertices' coordinates for your trigger. Vertices is a set of points defining outlines of your new trigger. If you look at existing areas with triggers in Infinity Explorer you'll notice that number of vertices could vary from 4 for basic quadrangular trap or door to a whole lot for, like, a pile of dead bodies in Candlekeep catacombs. If you have (or could draw yourself) modified area with new trigger you want to convert to WeiDU, just open it with NI and copy list of vertices from there. As an alternative you could go in-game to desired area, decide on what shape do you want your trigger to be, point cursor upon each vertex of your planned trigger, press "X" key and write down pairs of coordinates. That's it, either way you're having a set of vertices now.


2. How to use example template:

Quite simple - as you could see, there's comments that are placed in between code lines and comments that are shifted to the second column on the right of code lines. Those in second column marks everything that you ever need to change with explanations where needed, while left-side comments are geared towards further explanation for those who wish to fully understand how the damn thing is working :p


OK, most of necessary comments are included in template, but there's few things that could use more explaining.


3. Flags setting with WeiDU:

Perhaps it's obvious for someone, but it wasn't obvious for me, so I write it for those who aren't programmers as well. There's offsets where combinations of flags should be set. In trigger case it's offset 60xh, for example. So how to add flags, say, #1, #3 & #8 while you're allowed to write only 1 number per offset? That's what should be done:

- get the list of possible flags for this offset (IESDP or IE are a good sources)

- decide what flags do you want to use

- write down in a string "1" for each flag you want to use and "0" for each flag you don't need from right to left (Chinese-like). So, if you having array of 10 flags of which you want to activate 1st, 3rd & 8ht ones, you should get something like 0010000101 in the end. Now convert this binary number to decimal. You'll get 133, which is what you should write to the offset.


4. In this example I'm adding new trap, so should you want to add Info Point or Exit you'll find need to change some flags, use some unused entries and vice versa. There should be nothing difficult - if you are unsure what to set and where just check some existing triggers of same kind in NI and what flags and entries they use. Most difficult things like shifting some parts of file and adding vertices will remain the same.


5. Don't forget to create and compile script for your trigger if it's a trap.



COPY_EXISTING ~AR4101.are~ ~override/AR4101.are~      //Area to be modifyed


  //Prepare for the area modification.


//Read info on current numbers of triggers and vertices

READ_SHORT ~0x05a~ ~#ofTrigg~

READ_SHORT ~0x080~ ~#ofVerti~


//Read current address marks for all parts that will be shifted by new content

READ_SHORT ~0x05c~ ~triggOff~

READ_SHORT ~0x060~ ~spawnOff~

READ_SHORT ~0x068~ ~entraOff~

READ_SHORT ~0x070~ ~contaOff~

READ_SHORT ~0x078~ ~itemsOff~

READ_SHORT ~0x084~ ~ambiaOff~

READ_SHORT ~0x0A8~ ~doorsOff~

READ_SHORT ~0x07c~ ~vertiOff~

READ_SHORT ~0x0B0~ ~animaOff~

READ_SHORT ~0x0BC~ ~songsOff~

READ_SHORT ~0x0C0~ ~restcOff~

READ_SHORT ~0x0C4~ ~automOff~


//Increase the number of triggers (adding one more)

WRITE_SHORT 0x05a (~%#ofTrigg%~ + 1)


//Correct address marks for offsets shifted by new trigger

WRITE_SHORT 0x060 (~%spawnOff%~ + 196)

WRITE_SHORT 0x068 (~%entraOff%~ + 196)

WRITE_SHORT 0x070 (~%contaOff%~ + 196)

WRITE_SHORT 0x078 (~%itemsOff%~ + 196)

WRITE_SHORT 0x084 (~%ambiaOff%~ + 196)

WRITE_SHORT 0x0A8 (~%doorsOff%~ + 196)

WRITE_SHORT 0x07c (~%vertiOff%~ + 196)


//Adding a bunch of blank bytes as a new trigger placeholder

INSERT_BYTES (~%triggOff%~ + ~%#ofTrigg%~ * 196) 196


//Set up the vertices you'll be adding.

SET ~newVert~ = 6          //write here number of vertices you're adding

WRITE_SHORT 0x080 (~%#ofVerti%~ + ~%newVert%~)

//where last number in argument being the quantity of vertices you're adding


INSERT_BYTES (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196) (~%newVert%~ * 4)

//where argument equals four times number of vertices


//Correct address marks for offsets shifted by both new trigger and new vertices

WRITE_SHORT 0x0B0 (~%animaOff%~ + 196 + (~%newVert%~ * 4)) 

WRITE_SHORT 0x0BC (~%songsOff%~ + 196 + (~%newVert%~ * 4))

WRITE_SHORT 0x0C0 (~%restcOff%~ + 196 + (~%newVert%~ * 4))

WRITE_SHORT 0x0C4 (~%automOff%~ + 196 + (~%newVert%~ * 4))

//where last part of argument being 196 (bytes for trigger) plus four times number of added vertices


  //Prep work is done.


  //Now, you can start adding in the actual code for new trigger



WRITE_ASCII (~%triggOff%~ + ~%#ofTrigg%~ * 196) ~CRTrap01~  //Name of your trigger


//Trigger Type

WRITE_SHORT (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 32) 0    //where 0 stands for Proximity, 1 for Info Point and 2 for Travel (aka Exit) trigger


//Define bounding box:

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 34) 555  //Bounding box points:

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 36) 490    //Take them from modded in usual way (created in IETME and wieved in NI) area

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 38) 665    //OR find manually by checking your vertices coords: this 4 entries is organized

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 40) 592    //in following order: smallest X, smallest Y, largest X, largest Y of all new vertices


//Set number of vertices for a new trigger.

WRITE_SHORT (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 42) ~%newVert%~


//Index of first vertex for this info point (no +1 adding because index of first vertex is 0)

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 44) ~%#ofVerti%~


//Trigger Icon

WRITE_SHORT (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 52) 0    //where 22 stands for Info Question Mark, 28 for Inside Exit (stair) and 30 for Outside Exit (door)

//All possible icons could be find in cursors.bam that is the part of GUIbam.bif  file.


//Destination Area RESREF

WRITE_ASCII  (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 56) ~None~  //Resref of the destination area, if this is an exit. Unused for other object types.


//Where we will appear if we pass through this door

WRITE_ASCII (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 64) 0    //Name of the entrance within the destination area. Only used for "exit" objects.



WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 96) 08    //08 - detectable trap


//Trigger Text

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 100) 0    //The text associated with this "info point", if this is actually an "info point" (i.e. if type==01).

//Replace the argument with your chosen dialog string for Info Points.

//You can use SAY here, just replace "WRITE_LONG" with "SAY" and "5185" with "@#"


WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 104) 40    //Trap Detection - % of difficulty


WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 106) 50    //Trap Removal - % of difficulty


WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 108) 01    //Is Trapped Flag: 00 - No, 01 - Yes


WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 110) 00    //Trap Already Detected Flag: 00 - No, 01 - Yes


//Trap spell will be launched from there when the trap is activated:

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 112) 805    //Launcher X coord

WRITE_LONG (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 114) 463    //Launcher Y coord


WRITE_ASCII  (~%triggOff%~ + ~%#ofTrigg%~ * 196 + 124) ~crtrpsc1~  //Associated Script - resref without extention


//Now, write the new vertices.

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196) 555    //This is an array of points which are used to create the outlines of trigger/info/exit regions

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 2) 517  //Format is point 1 X coord, point 1 Y coord, point 2 X coord, point 2 Y coord etc

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 4) 602  //

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 6) 490  //Take them from modded in usual way (created in IETME and wieved in NI) area

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 8) 661  //OR find manually:

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 10) 516  //by launching game, finding required area manually by setting cursor over

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 12) 665  //desired point and pressing "x" key

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 14) 557  //

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 16) 611  //Of course, you can change number of vertices to match your trigger

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 18) 592  //just follow this pattern of increasing offset for each entry for 2 bytes

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 20) 560

WRITE_SHORT (~%vertiOff%~ + ~%#ofVerti%~ * 4 + 196 + 22) 568


P.S. This code was thoroughly tested for BG1 and, to a lesser extent, in BG2.


P.P.S. I just noticed that SirBillyBob's revision of CoM's mod Desecration of Souls (download here) uses similar technique to add Exit point to an existing map as well as to add new container (not covered in this tutorial but based upon same method), so you could check DoS's .tp2 if you need more examples :D

Link to comment


This topic is now archived and is closed to further replies.

  • Create New...