Jump to content


Photo

Area Modding Tool & Tutorial by Qwinn


  • Please log in to reply
164 replies to this topic

#41 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 30 May 2009 - 07:40 PM

That will make the header longer than the mod. Short enough for you...

All lines of code in any .tp* files (or files masquerading as .tp* files) factor into the lines of code count :P.

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#42 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 31 May 2009 - 06:02 AM

// ========================== YOU MUST SET THIS VARIABLE. =======================
// 1 = PST
// 2 = BG2
// 3 = BG1 or IWD
// These macros will NOT work with IWD2, the area file in that game is substantially different.

SET "Q_Game" = 1

Did you know that there is GAME_IS in weidu? You can use it to specify which game platform the file should be modified for.
In your case without having to go through it all and change things again, you could in the first macro called do the following and then the player wouldn't need to set the value, but it would be set based on the game where the macro is being used.

PATCH_IF (GAME_IS ~pst~) BEGIN
 SET Q_GAME = 1
END
PATCH_IF (GAME_IS ~bg2 tob tutu tutu_totsc bgt~) BEGIN
 SET Q_GAME = 2
END
PATCH_IF (GAME_IS ~bg1 totsc iwd how totlm~) BEGIN
 SET Q_GAME = 3
END
I'd check with the bigg to make sure that this would get all instances of the game as he'd made changes to GAME_IS and ENGINE_IS since 208...

Also in looking at Q_AREAdd_Process I believe I see where you determine which offsets get updated. I see a possible issue. Some sections that have no data to begin with share an offset with usually the section after it. There is no error in reading the file because there is no entry for the number of entries in that section. But if you add a new entry to a section that had no entry to begin with and then only update those sections whose offsets are greater you may miss out on that one section which had data and was sharing the same offset as the section which was added to. Changing PATCH_IF "Q_Offset2" > "Q_Offset1" THEN to PATCH_IF "Q_Offset2" >= "Q_Offset1" THEN would solve the updating of other sections whose offsets may have shared the same value. But you then get a new problem: How to prevent the current offset being added to from being updated as well.... In single function patches/macros you can simply leave out that update, but in your macro you can't do that... Something else will need to be figured out...

An example:
The file I want to modify is ar1803.are in BG ToTSC the offset values of each section start are as follows in the unmodded file:
From NI:

Actors offset = 11c h
Info points, trigger points and exits offset = 55c h
Spawn points offset = ab8 h
Entrances offset = ab8 h
Containers offset = b20 h
Items offset = 1360 h
Vertices offset = 17d8 h
Ambients offset = 1568 h
Variables offset = 1710 h
Explored bitmap offset = 4cc0 h
Doors offset = 1710 h
Animations offset = 4cc0 h
Tiled objects offset = 17d8 h
Songs offset = 4cc0 h
Rest spawn creatures offset = 4d50 h
Automap note offset = 0 h <-- this isn't used in BG or BG TOTSC so NI puts in an empty value

You can see the two highlighted offsets have the same location in the file if you look at their quantity you'll see that

# spawn points = 0
# entrances = 1

If for some reason I wanted to add a spawn point using your current macro the entrances offset would not get updated because it is equal to the spawn point offset. While the entrance data gets shifted with the insert bytes the entrance offset does not get updated. You can also see other sections that share the same offset value. If any one of them that was empty gets data added those equal section offsets will not be updated and will point to the wrong information... So in your process if you change those that are equal as well as greater all those other section offsets will be updated but the current offset having bytes added will try to update as well. That too will cause problems with the file....

Does this make sense to you?

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#43 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 31 May 2009 - 08:55 PM

Yes, it does, and good catch. I think we can take your suggestion about making it >= rather than just >, and then just do an additional check to make sure S1 does not equal S2. I think that'll cover your "But you then get a new problem: How to prevent the current offset being added to from being updated as well" concern, right? I'll have to think on it some more before deciding if that'll cover it myself.

EDIT: Yeah, pretty sure that check should solve that problem.

Qwinn

Edited by Qwinn, 31 May 2009 - 08:59 PM.


#44 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 11:53 AM

I added the code to account for adding to an empty section that shares an offset with a non-empty section. Updated the download as well.

Qwinn

#45 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 01 June 2009 - 01:28 PM

Yes, it does, and good catch. I think we can take your suggestion about making it >= rather than just >, and then just do an additional check to make sure S1 does not equal S2. I think that'll cover your "But you then get a new problem: How to prevent the current offset being added to from being updated as well" concern, right? I'll have to think on it some more before deciding if that'll cover it myself.

EDIT: Yeah, pretty sure that check should solve that problem.

Qwinn

Don't forget to update the download link and the post text... Let us know when you've got it fixed and tested. <-- EDIT: You beat me to it while I was putting together this post... :D

Regarding Vertexes.
If I'm reading things correctly...

Your example in the first post adds 10 vertex coordinates. According to the process macro, the offset location is updated by 10 vertex worth of space on those that are > (will be >=) the offset of the vertex offset. Then new bytes are inserted at the vertex offset. It is then at that location that the vertex points will get written.

What happens when...
I add two triggers to a file that has containers, doors and other triggers. My new vertex points are added to the front of the vertex section and I've properly figured out what my vertex index numbers are for the two new triggers. What about the pre-existing containers, doors and other triggers? All their vertex points have been shifted by ("Q_NewSect" * "Q_SizSect") but their index values are not updated. Shouldn't this be added into the main process macro BEFORE this line PATCH_IF "Q_Offset2" >= "Q_Offset1" THEN
PATCH_IF (~%S2%~ STRING_EQUAL_CASE ~Trigg~ ) 
		 OR  (~%S2%~ STRING_EQUAL_CASE ~Conta~ )
		 OR  (~%S2%~ STRING_EQUAL_CASE ~Doors~) 
	   AND (%Q_New_Vertx% > 0) BEGIN
 SET "QV_OffFVI_Trigg"  = 0x2c
 SET "QV_OffFVI_Conta"  = 0x50
 SET "QV_OffFVI_DoorO"  = 0x2c
 SET "QV_OffFVI_DoorC"  = 0x34
 SET "QV_OffFVI_DoorOI" = 0x50
 SET "QV_OffFVI_DoorCI" = 0x48

//move trigger vertex indexes forward by Q_New_Vertex
  FOR ("i2" = 1; "i2" <= "Q_Num_Trigg"; "i2" += 1)  BEGIN
	READ_LONG ("Q_Off_Trigg" + ("Q_Siz_Trigg" * ("i2" - 1)) + "QV_OffFVI_Trigg") "QV_EachFVI"
		WRITE_LONG ("Q_Off_Trigg" + ("Q_Siz_Trigg" * ("i2" - 1)) + "QV_OffFVI_Trigg")  "QV_EachFVI" + %Q_New_Vertx%
  END
//move container vertex indexes forward by Q_New_Vertex
  FOR ("i2" = 1; "i2" <= "Q_Num_Conta"; "i2" += 1)  BEGIN
	READ_LONG ("Q_Off_Conta" + ("Q_Siz_Conta" * ("i2" - 1)) + "QV_OffFVI_Conta") "QV_EachFVI"
		WRITE_LONG ("Q_Off_Conta" + ("Q_Siz_Conta" * ("i2" - 1)) + "QV_OffFVI_Conta")  "QV_EachFVI" + %Q_New_Vertx%
  END
//move door vertex indexes forward by Q_New_Vertex
  FOR ("i2" = 1; "i2" <= "Q_Num_Doors"; "i2" += 1)  BEGIN
	READ_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorO") "QV_EachFVI"
		WRITE_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorO")  "QV_EachFVI" + %Q_New_Vertx%
	READ_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorC") "QV_EachFVI"
		WRITE_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorC")  "QV_EachFVI" + %Q_New_Vertx%
	READ_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorOI") "QV_EachFVI"
	  WRITE_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorOI")  "QV_EachFVI" + %Q_New_Vertx%
	READ_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorOC") "QV_EachFVI"
	  WRITE_LONG ("Q_Off_Doors" + ("Q_Siz_Doors" * ("i2" - 1)) + "QV_OffFVI_DoorOC")  "QV_EachFVI" + %Q_New_Vertx%
  END
END

See all it took was some time, asking questions and being in the code to start to get the hang of what you are doing... Don't give up on me yet. I'll get there eventually....

Edited by Sasha Al'Therin, 01 June 2009 - 01:29 PM.

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#46 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 01 June 2009 - 04:32 PM

Maybe one of you can use the macro(s) as a 'proof of concept' on my code here.

Okay... Did some playing around with that. It's probably longer code than you want but I think it'll do the job. I didn't use Qwinn's macro cause I wasn't sure how to use it to delete so I created my own FUNCTION to do the job, but I slightly modified your code so I could understand what was happening.

Here's your new tp2 code to try:
INCLUDE ~somemode\somedir\DELETE_AMBIENT_ENTRY.tph~
COPY_EXISTING_REGEXP GLOB ~^\([^xX].*\|[xX][^rR].*\|[xX][rR][^2].*\|[xX][rR]2[^46].*\)\.are$~ ~override~
  PATCH_IF SOURCE_SIZE > 0x11b BEGIN //If a valid area
   READ_SHORT 0x82 mc //Ambient count
   READ_LONG 0x84 mf //Ambient offset
   FOR (index=0;index<%mc%;index+=1) BEGIN
	SET mb = (0xd4 * %index%) //index into ambient entries
	READ_SHORT (mf + mb + 0x80) sc //Sound count
	SET ss = 0x30 //start location
	SET sz = 0x8 //size per entry
	FOR (index2=0;index2<%sc%;index2+=1) BEGIN
	 SET si = (%index2% * %sz%) //index into sounds entries in current ambient entry
	 READ_ASCII (mf + mb + %ss% + %si%) sf
	 //blank out non-existant sound file references <-- this is in case other sound file references do exist
	 PATCH_IF (NOT FILE_EXISTS_IN_GAME ~%sf%.wav~) BEGIN
	  WRITE_ASCII (mf + mb + %ss% + %si%) ~~ (8)
	 END
	END
   END
   LAUNCH_PATCH_FUNCTION ~Delete_Ambient_Entry~
  END
BUT_ONLY_IF_IT_CHANGES

Here's the contents of the file to INCLUDE:
////////////////////////////////
//Contents of Delete_Ambient_Entry
DEFINE_PATCH_FUNCTION ~Delete_Ambient_Entry~ BEGIN
 SET off_of_amb_c = 0x82 //set offset value to read ambient count
 SET off_of_amb_o = 0x84 //set offset value to read ambient offset
 READ_SHORT %off_of_amb_c% amb_c //Ambient count
 READ_LONG %off_of_amb_o% amb_o //Ambient offset
 SET amb_s = 0xd4  //set ambient entry size
 FOR (index=0;index<%amb_c%;index+=1) BEGIN
  SET amb_e = (0xd4 * %index%) //set index into ambient entries
//must know if ALL entries are not in game not just the current one.
  SET ss0 = 0x30 //sound 1
  SET ss1 = 0x38 //sound 2
  SET ss2 = 0x40 //sound 3
  SET ss3 = 0x48 //sound 4
  SET ss4 = 0x50 //sound 5
  SET ss5 = 0x58 //sound 6
  SET ss6 = 0x60 //sound 7
  SET ss7 = 0x68 //sound 8
  SET ss8 = 0x70 //sound 9
  SET ss9 = 0x78 //sound 10
  READ_ASCII (%amb_o% + %amb_e% + %ss0%) sound0
  READ_ASCII (%amb_o% + %amb_e% + %ss1%) sound1
  READ_ASCII (%amb_o% + %amb_e% + %ss2%) sound2
  READ_ASCII (%amb_o% + %amb_e% + %ss3%) sound3
  READ_ASCII (%amb_o% + %amb_e% + %ss4%) sound4
  READ_ASCII (%amb_o% + %amb_e% + %ss5%) sound5
  READ_ASCII (%amb_o% + %amb_e% + %ss6%) sound6
  READ_ASCII (%amb_o% + %amb_e% + %ss7%) sound7
  READ_ASCII (%amb_o% + %amb_e% + %ss8%) sound8
  READ_ASCII (%amb_o% + %amb_e% + %ss9%) sound9
  PATCH_IF (NOT FILE_EXISTS_IN_GAME ~sound0~) AND (NOT FILE_EXISTS_IN_GAME ~sound1~) AND (NOT FILE_EXISTS_IN_GAME ~sound2~)
	   AND (NOT FILE_EXISTS_IN_GAME ~sound3~) AND (NOT FILE_EXISTS_IN_GAME ~sound4~) AND (NOT FILE_EXISTS_IN_GAME ~sound5~)
	   AND (NOT FILE_EXISTS_IN_GAME ~sound6~) AND (NOT FILE_EXISTS_IN_GAME ~sound7~) AND (NOT FILE_EXISTS_IN_GAME ~sound8~)
	   AND (NOT FILE_EXISTS_IN_GAME ~sound9~) BEGIN
   DELETE_BYTES (%amb_o% + %amb_e%) %amb_s%
   WRITE_SHORT %off_of_amb_c% (%amb_c% - 1)
   SET del_bytes = 0xd4
//update other offsets
//check other offsets and update as needed
//set these for use with later P_F_E
  SET loc_actor = 0x54
  SET loc_spawn = 0x60
  SET loc_entrance = 0x68
  SET loc_container = 0x70
  SET loc_item = 0x78
  SET loc_vertex = 0x7c
  SET loc_ambient = 0x84
  SET loc_variable = 0x88
  SET loc_door = 0xa8
  SET loc_explored = 0xa0
  SET loc_anim = 0xb0
  SET loc_tiled = 0xb8
  SET loc_song = 0xbc
  SET loc_rest = 0xc0
  PATCH_IF !(GAME_IS ~pst~) BEGIN
   SET loc_amapBG2 = 0xc4
   SET loc_pro_traps = 0xcc
  END
  PATCH_IF (GAME_IS ~pst~) BEGIN
   SET loc_amapPST = 0xc8
  END
//Get the offset entries could use the variables set above instead of the hard set entries, but don't matter
  READ_LONG 0x54 actor_off
  READ_LONG 0x60 spawn_off
  READ_LONG 0x68 entrance_off
  READ_LONG 0x70 container_off
  READ_LONG 0x78 item_off
  READ_LONG 0x7c vertex_off
  READ_LONG 0x84 ambient_off
  READ_LONG 0x88 variable_off
  READ_LONG 0xa8 door_off
  READ_LONG 0xa0 explored_off
  READ_LONG 0xb0 anim_off
  READ_LONG 0xb8 tiled_off
  READ_LONG 0xbc song_off
  READ_LONG 0xc0 rest_off
  PATCH_IF !(GAME_IS ~pst~) BEGIN
   READ_LONG 0xc4 amapBG2_off
   READ_LONG 0xcc pro_traps_off
  END
  PATCH_IF (GAME_IS ~pst~) BEGIN
   READ_LONG 0xc8 amapPST_off
  END
//do a PFE for each section and update if neeeded
//ambients don't mess with vertex points so I don't need to update those indexes
  PATCH_FOR_EACH ~string~ IN
   ~actor~ ~spawn~ ~entrance~ ~container~ ~item~ ~vertex~ ~ambient~ ~variable~ ~door~ ~explored~
   ~anim~ ~tiled~ ~song~ ~rest~ ~amapBG2~ ~pro_traps~ ~amapPST~ BEGIN
  SET offset = $loc(%string%)
  PATCH_IF ($%string%(off) >= %amb_o%) AND (NOT ~%string%~ STRING_EQUAL_CASE ~ambient~) BEGIN
   WRITE_LONG %offset% (%actor_off% - %del_bytes%)
  END
  PATCH_IF !(GAME_IS ~pst~) AND ( (~%string%~ STRING_EQUAL_CASE ~amapBG2~)
								  (~%string%~ STRING_EQUAL_CASE ~pro_traps~) ) BEGIN
   PATCH_IF ($%string%(off) >= %amb_o%) BEGIN
	WRITE_LONG %offset% (%actor_off% - %del_bytes%)
   END
  END
  PATCH_IF (GAME_IS ~pst~) AND (~%string%~ STRING_EQUAL_CASE ~amapPST~) BEGIN
   PATCH_IF ($%string%(off) >= %amb_o%) BEGIN
	WRITE_LONG %offset% (%actor_off% - %del_bytes%)
   END
  END

END //end the FUNCTION definition

Do note: I've not tested this nor do I have a desire to. I'm sure you know enough modding that if weidu spits out an error, you'll be able to locate and fix the problem. Note the usage of PFE. I've learned something in this thread, I think....

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#47 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 01 June 2009 - 05:02 PM

Just thought of something else....

When someone adds a new door in the region triggers section, they must name an entrance in the destination area. Are you leaving it up to the user to remember to modify the destination area to have the new entrance added? It's fine if you are. Perhaps a bit of a reminder concerning that in the documentation would be helpful. I've heard of people forgetting to add one or the other before...

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#48 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 05:05 PM

What happens when...
I add two triggers to a file that has containers, doors and other triggers. My new vertex points are added to the front of the vertex section and I've properly figured out what my vertex index numbers are for the two new triggers.


There is no need to ever do this. You can and should always add your vertexes to the end of the vertex section. This is also true for adding any other records to any other section of the file. If you add them anywhere other than the end, you risk making your mod incompatible with that of others.

EDIT: Wait... what I just said is true for the other sections, but maybe not for vertexes. Lemme look at what you're saying a bit more.

Qwinn

Edited by Qwinn, 01 June 2009 - 05:06 PM.


#49 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 05:09 PM

While I look at it, here is an example from my Fixpack of me modifying the vertexes of an already existing trigger.

COPY_EXISTING ~AR1404.ARE~ ~override~
  LAUNCH_PATCH_MACRO ~Q_ARE_InitVars~
  LAUNCH_PATCH_MACRO ~Q_AREVertex_InitVars~
  SET "QV_Type" = 1 // Trigger
  SET "QV_Offset" = "Q_Off_Trigg" + ("Q_Siz_Trigg" * 4)
  SET "QV_VCount" = 19
  LAUNCH_PATCH_MACRO ~Q_AREVertex_Process~

WRITE_SHORT ("QV_NewVertexOffset" + 0)   467
WRITE_SHORT ("QV_NewVertexOffset" + 2)   688
WRITE_SHORT ("QV_NewVertexOffset" + 4)   778
WRITE_SHORT ("QV_NewVertexOffset" + 6)   604
WRITE_SHORT ("QV_NewVertexOffset" + 8)   970
WRITE_SHORT ("QV_NewVertexOffset" + 10)  929
WRITE_SHORT ("QV_NewVertexOffset" + 12)  943
WRITE_SHORT ("QV_NewVertexOffset" + 14)  929
WRITE_SHORT ("QV_NewVertexOffset" + 16)  911
WRITE_SHORT ("QV_NewVertexOffset" + 18)  959
WRITE_SHORT ("QV_NewVertexOffset" + 20)  916
WRITE_SHORT ("QV_NewVertexOffset" + 22)  981
WRITE_SHORT ("QV_NewVertexOffset" + 24)  934
WRITE_SHORT ("QV_NewVertexOffset" + 26)  983
WRITE_SHORT ("QV_NewVertexOffset" + 28)  938
WRITE_SHORT ("QV_NewVertexOffset" + 30)  974
WRITE_SHORT ("QV_NewVertexOffset" + 32)  928
WRITE_SHORT ("QV_NewVertexOffset" + 34)  974
WRITE_SHORT ("QV_NewVertexOffset" + 36)  938
WRITE_SHORT ("QV_NewVertexOffset" + 38)  957
WRITE_SHORT ("QV_NewVertexOffset" + 40)  954
WRITE_SHORT ("QV_NewVertexOffset" + 42)  956
WRITE_SHORT ("QV_NewVertexOffset" + 44)  950
WRITE_SHORT ("QV_NewVertexOffset" + 46)  946
WRITE_SHORT ("QV_NewVertexOffset" + 48)  940
WRITE_SHORT ("QV_NewVertexOffset" + 50)  946
WRITE_SHORT ("QV_NewVertexOffset" + 52)  943
WRITE_SHORT ("QV_NewVertexOffset" + 54)  929
WRITE_SHORT ("QV_NewVertexOffset" + 56)  970
WRITE_SHORT ("QV_NewVertexOffset" + 58)  929
WRITE_SHORT ("QV_NewVertexOffset" + 60)  1102
WRITE_SHORT ("QV_NewVertexOffset" + 62)  1153
WRITE_SHORT ("QV_NewVertexOffset" + 64)  810
WRITE_SHORT ("QV_NewVertexOffset" + 66)  1251
WRITE_SHORT ("QV_NewVertexOffset" + 68)  705
WRITE_SHORT ("QV_NewVertexOffset" + 70)  1206
WRITE_SHORT ("QV_NewVertexOffset" + 72)  739
WRITE_SHORT ("QV_NewVertexOffset" + 74)  1143
 BUT_ONLY_IF_IT_CHANGES

Qwinn

#50 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 05:22 PM

Okay, yeah, I think my first instincts were correct.

Your example in the first post adds 10 vertex coordinates. According to the process macro, the offset location is updated by 10 vertex worth of space on those that are > (will be >=) the offset of the vertex offset. Then new bytes are inserted at the vertex offset. It is then at that location that the vertex points will get written.


No. If you are simply creating new vertexes for new triggers, not modifying an existing one, then the new vertexes are inserted at the end of the last existing vertex, not at the top of the vertex list. See: SET $Q_NewOffset("%S1%") = "Q_Offset1" + ("Q_NumSect" * "Q_SizSect")

If you are modifying the vertexes attached to an existing trigger, then it's a different ballgame, and a different macro accomplishes that task, not sure if you've looked at it yet.

At any rate, yes, all new records are added at the end of the existing records, never at the beginning. Therefore, there is no need to shift the vertex offsets within existing trigger/container/door records forward. If you ARE changing an existing trigger to have more or less vertexes, then everything does need to be shifted around as you indicate, and that is what the Q_AREVertex_Process Macro is for.

I take it that solves the issues you brought up?

Qwinn

Edited by Qwinn, 01 June 2009 - 05:24 PM.


#51 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 01 June 2009 - 05:32 PM

AND AGAIN... You make a post while I'm putting mine together...

I saw the vertex process macro and after looking at it carefully along with some uses of it in the candlestick.tph I realized it was for editing existing triggers, but not for making sure that new vertex points added didn't mess with current vertex indexes for pre-existing triggers, doors and containers.

Okay, I saw where you were adding the new byte size to the original offset, but missed the insert. Now that I look at it, you do add to the END of each section. I've always added to the beginning perhaps I'll see about adding to the end....

But I'll share something from PPG that touches this topic

From a thread at PPG in Weidu forum pages:

Every structure that has vertex data contains an index into the vertex list for that structure's vertices. So you have to walk through them all (accounting for where in the list you have to add your own vertices) to make sure the index and counts are all correct. Containers doubly so because they also have the item list.

"Tough" as in it's a bitchlot of work to do, not that in it requires any particular skill. And good luck trying to come up with something that does the task and has any semblance of elegance to it.

It's true when adding items into existing containers (which is better be handled by script), or morphing a square into a hexagon, but when adding new polygons? I'm not sure why to inject into the middle of the existing count then, I just add my polygon as the 'last', so for it vertex_index = vertex_offsetnum.

But the list is used for triggers, containers, and doors (in that order, I believe).

It's possible it works to, say, add a trigger but stick your coordinates at the end of the list (past those used for all the containers and doors in the area), but I've never tested it. (It would probably look screwy in NI if you tried it, though; I'm pretty sure we just add the counts up and disregard index entirely when building the associated vertices.)

A macro that worked like that, however, should most definitely get you killed.


So you've added your vertexes to the end of the list, did the game or NI get screwed up at all?
I don't think so cause you wouldn't have published mods that use these techniques if they didn't work right.

If you want to give an 'official' and response citing 'tested' and 'working' proof, I'd more than happy to share the info so that we can all rest easy... 8)

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#52 Sasha Al'Therin

Sasha Al'Therin
  • Modder
  • 615 posts

Posted 01 June 2009 - 05:40 PM

I just realized part of what was getting me confused...

From candlestick.tph
WRITE_LONG  "Q_NewOffset_Trigg" + ("Q_Siz_Trigg" * 0) + 0x2c  "Q_Num_Vertx" - 10  // First Vertex Index
I forgot that the list of writes comes after the macro and that at the end of the macro you re-initialize the variables thus updating Q_Num_Vertx and the others.

My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altheri...s.com/index.htm


#53 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 06:19 PM

Yep, it's tested and works great. For new triggers and vertex lists, I can't imagine doing it any other way than adding at the end, for precisely the reason you point out. At the end, you don't have to worry about reshuffling everything in the world. Anywhere else, you do. Putting them at the end seems quite obvious, as well as most likely not to interfere with other mods.

Now modifying an existing trigger gets trickier, and I had to come up with a different method for that, obviously. I would be curious to know if devsin thinks it passes the "semblance of elegance" test :)

EDIT:

I saw the vertex process macro and after looking at it carefully along with some uses of it in the candlestick.tph I realized it was for editing existing triggers, but not for making sure that new vertex points added didn't mess with current vertex indexes for pre-existing triggers, doors and containers.


Er, well, yes it does. If I'm modifying an existing trigger, I may well have to change the number of vertexes from, say, 8, to say 19. (The example I gave on this page does that, actually). This is essentially adding 11 new vertexes to the middle of the vertex list, and the macro very much does go through a great deal of trouble to make "sure that new vertex points added didn't mess with current vertex indexes for pre-existing triggers, doors and containers." That's practically its entire purpose - to make sure all those index fields get updated properly.

Qwinn

Edited by Qwinn, 01 June 2009 - 06:23 PM.


#54 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 01 June 2009 - 08:38 PM

Every structure that has vertex data contains an index into the vertex list for that structure's vertices. So you have to walk through them all (accounting for where in the list you have to add your own vertices) to make sure the index and counts are all correct. Containers doubly so because they also have the item list.

"Tough" as in it's a bitchlot of work to do, not that in it requires any particular skill. And good luck trying to come up with something that does the task and has any semblance of elegance to it.

A macro that worked like that, however, should most definitely get you killed.

I used the (relatively short if not 'elegant') code on the first page to add successfully a 6-vertex container. Doesn't look wacky in DLTCEP/NI or in-game (though it probably could be drawn more smoothly, with more vertices). Unless I'm misunderstanding and you're talking about something else, or there's something I totally overlooked...

If we can come up with a standard that is better (either shorter, more extensible or more efficient) than that code, I'd be happy to switch (even though I have working code AFAICT).

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#55 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 08:44 PM

If we can come up with a standard that is better (either shorter, more extensible or more efficient) than that code, I'd be happy to switch (even though I have working code AFAICT).


Um. :(

Has mine been ruled out already?

Qwinn

#56 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 01 June 2009 - 09:07 PM

If we can come up with a standard that is better (either shorter, more extensible or more efficient) than that code, I'd be happy to switch (even though I have working code AFAICT).

Um. :(

Has mine been ruled out already?

Qwinn

I don't know, to be honest. I haven't used your macro but I assume it works since you use it in published mods, though the SHORT/LONG confusion definitely needed to be resolved - I assume you did that?

I filtered out comments and counted the actual lines of code in your macro, and at ~300 it is either not significantly more (if you count all code and the macro I used at ~210) or roughly 3 times larger if you count just the macro. So the question is: what code is necessary to do the same thing with your macro (i.e., add a new 6-vertex container to an area)? And the second question is: which is more efficient, which I cannot answer offhand because frankly, a lot of this discussion goes over my head (or I'm just too lazy to try to understand it and want other folks to do the work for me :P).

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#57 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 09:12 PM

I don't know, to be honest. I haven't used your macro but I assume it works since you use it in published mods, though the SHORT/LONG confusion definitely needed to be resolved - I assume you did that?


Yep, within a few hours of realizing it.

It actually didn't cause any problems with my mods... I think the way they are stored means that it was only a problem if an area had more than 0xFFFF, or 65,536, of a given type of record (like, "actors", or "doors"). Heh. So, unlikely to really cause any issues. Or, at least, the simple fact that you've got an area with over 65,000 actors is likely to present much bigger challenges. But still, it is fixed.

Qwinn

Edited by Qwinn, 01 June 2009 - 09:28 PM.


#58 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 09:22 PM

Miloch:

The vast bulk of what you see up there is just initializing variables. The macro that does all the non-vertex work is 43 lines long. The one that deals with vertexes is 86 lines long.

But there's a big difference. Your macro can add one container with vertexes and some items, but that's all. My macro is designed to allow you to add any type of section an area can handle, meaning, it can adjust all the offsets, counts, indexes and inserts for adding actors, entrances, doors, containers, items, vertexes, triggers, ambient sounds, animations, map notes, etc. etc. etc. etc. Not only that, but you can have it handle all those offsets, counts, indexes, etc. for -any number- of any of those types of sections, all with one call to the macro. I don't need to call it once for each actor, and against for a second actor, and then again for a door. I can set variables that say "Add 2 doors, 4 actors, 6 triggers, and 20 vertexes", run the macro once, and all the needed space is inserted and all the offsets and indexes updated. All that remains is to do your writes, with the offsets you need to write them to provided for you in variables reserved for that purpose.

I don't think a direct comparison of lines of code is therefore really fitting.

Qwinn

#59 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 01 June 2009 - 10:13 PM

My macro is designed to allow you to add any type of section an area can handle

I suspected that, therefore,

So the question is: what code is necessary to do the same thing with your macro (i.e., add a new 6-vertex container to an area)?

And I suspect that's fairly easy, and similar to the code you have above to change existing vertices, and I could probably figure it out by RTFM, but... I have existing code that works. Unlike some folks though, I'm not religious about optimising existing code, so I'll give your macro a try if I can don't have to comb through it all it figure out the parameters to pass to it (I'm only a half-orc, remember). Ultimately, we want to incorporate this (or whatever standard we decide on) into WeiDU so it's dead easy for others to do, like with the existing macros (such as ADD_CRE_EFFECT etc.).

Also, if it is as plainab/Sasha says and your macros cannot delete stuff from areas, but only create or change, then that is something we'll need to remedy. But as 'most everyone knows, it's far easier to destroy than create...

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#60 Qwinn

Qwinn
  • Modder
  • 3092 posts

Posted 01 June 2009 - 10:27 PM

It can easily do deletes. You just have to do the DELETE_BYTES yourself, set the variable "Q_ManualInsert" to 1 so that it skips doing the INSERT_BYTES, and then set the variable that normally tells the macro how many of that type of record you want to create to a negative number. The macro then goes through and updates all the offsets for you.

If you want the simple explanation of how to use my macros, including the list of variables that need to be set to make it work, see post #29.

Qwinn

Edited by Qwinn, 01 June 2009 - 10:29 PM.