Jump to content

Add a new door to the area (with tiles!)


Recommended Posts

I have updated the library with a new function, ps_tileset_replace_palette_entry, that replaces palette entries with a new color. So say there was a tileset with a tile that contained a pure green pixel, which would look odd. You can use this function to replace every pure green pixel with some other color. I feel like there was a fixpack somewhere that did something like this. A problem arises if you need to replace the color of a single pixel without entirely removing that color from the tile (like if that bad green pixel was in a door or water overlay tile that intentionally uses green for the transparent sections). To replace the color of this pixel, you would first look to see if the color you want to replace it with was already in the palette. If it is, great you're done. If it isn't, you would next have to look for an unused palette entry. If every palette entry is used, you would look for duplicate palette entries, combine them, and then use the free entry. If there are no duplicates, you're left with calculating the nearest-neighbor color within the existing color pool. I have basically already done this for BAMs in a different language (AHK) so I know how to do this, but rewriting it in WeiDU would constitute significant time and effort. While this last function would complete my initial vision for this tileset function library, I'm a bit hesitant to put forth the effort if there is no need for it. Other than this, my library (along with Tile2EE) includes the capability to do anything with a tileset I could envision anyone wanting to do that couldn't be done better with just a well placed WRITE_BYTE.

 

Thoughts? Anyone know which fixpack I vaguely remember or how it went about replacing green pixels?

Link to comment

 

I broke down and wrote it anyway, which concludes my initial vision for the project. The first beta release containing the full feature set can be found on GitHub.

Wow thanks! Could you write a tutorial on how to use your tool?

 

Setup-PS_Tileset.tp2 is a working example that displays almost all of the functionality offered by the tool, plus it intentionally uses some bad inputs (where noted in the comments) to show that it handles them properly. That main TP2 file has inline comments explaining what each call to the function library is doing, plus I tried to make sure the library itself (ps_tileset_lib.tpa) was well commented. If you have specific questions, I'd be happy to answer them the best I can.

Link to comment

I don't see anyone questioning how to go from A to Z on this, so I must be missing a vital piece of the pie.

I'm attempting to add a door to a house in the SoD version of the exterior ducal palace area.  This journey will encompass more than a few tasks, but the first that I'm attempting is taking tiles from one TIS (BG0200.TIS) and replace tiles in another (BD0010.TIS) with those from the first area.  Right now, I'd just like to see the open door graphic when I look at the BG0010.TIS.  I'll worry about the closed door graphic, WED changes, ARE changes later.

Attempts I've made so far:

  1. Export top two tiles of the open BG0200 door to BMP using DLTCEP: Result of ps_tileset_add_tiles = H0OPNTOP.BMP is not an uncompressed 8-bit bitmap - check the file.
  2. Export top two tiles of the open BG0200 door to TIS using DLTCEP: Result of ps_tileset_add_tiles = Dimensions of H0OPNTOP.TIS are incorrect for this tileset.  The tile should be 12 bytes but is 5120 bytes.
  3. tile2ee -f 2 -o processed h0opntop.tis: Result of ps_tileset_add_tiles = a change to BD0010.TIS that looks NOTHING like tiles in BG0200.TIS
  4. Attempt to export the tiles from BG0200 with ps_tileset_export_tiles: Results in a RAW file (even though I specified BMP) that I can't seem to do anything with

Am I supposed to take that raw file, convert it to a string, and write that to BG0010.TIS?

Edited by Lauriel
Link to comment
10 hours ago, Lauriel said:

I don't see anyone questioning how to go from A to Z on this, so I must be missing a vital piece of the pie.

I'm attempting to add a door to a house in the SoD version of the exterior ducal palace area.  This journey will encompass more than a few tasks, but the first that I'm attempting is taking tiles from one TIS (BG0200.TIS) and replace tiles in another (BD0010.TIS) with those from the first area.  Right now, I'd just like to see the open door graphic when I look at the BG0010.TIS.  I'll worry about the closed door graphic, WED changes, ARE changes later.

Attempts I've made so far:

  1. Export top two tiles of the open BG0200 door to BMP using DLTCEP: Result of ps_tileset_add_tiles = H0OPNTOP.BMP is not an uncompressed 8-bit bitmap - check the file.
  2. Export top two tiles of the open BG0200 door to TIS using DLTCEP: Result of ps_tileset_add_tiles = Dimensions of H0OPNTOP.TIS are incorrect for this tileset.  The tile should be 12 bytes but is 5120 bytes.
  3. tile2ee -f 2 -o processed h0opntop.tis: Result of ps_tileset_add_tiles = a change to BD0010.TIS that looks NOTHING like tiles in BG0200.TIS
  4. Attempt to export the tiles from BG0200 with ps_tileset_export_tiles: Results in a RAW file (even though I specified BMP) that I can't seem to do anything with

Am I supposed to take that raw file, convert it to a string, and write that to BG0010.TIS?

There are two primary types of tilesets:  Palette-based tilesets and PVRz-based tilesets.  A tile from a Palette-based tilesets contains a palette of 256 colors and a block of pixel data pointing into the palette.  A tile from a PVRz-based tileset is just a pointer into a PVRz file, which is a Zlib-compressed PowerVR texture using one of several compression algorithms.  There is no mechanic in WeiDU to access the contents of a PVRz file, largely due to the filesize limitations of WeiDU, but even if that were not a factor, the complexity of the task would be a huge barrier.

Because of this, PS_Tileset CANNOT mix tiles between palette-based and PVRz-based tilesets.  That's why approach #1 wouldn't work even if the BMP was the correct format; approach #2 doesn't work, not sure where you were going with #3, but if you were converting it to Palette-based tileset that won't work; why #4 gave you a RAW file instead of a BMP, but with this one you're on the right track.  IF AND ONLY IF both BG0200.TIS and BD0010.TIS are both PVRz-based tilesets AND both are already in the same game (along with their associated PVRz files), then you should be able to export the tiles from BG0200 (ps_tileset_export_tiles) and use them to overwrite tiles in BD0010 using ps_tileset_add_tile with STR_VAR Method = "Replace".  Again, these "tiles" are just pointers into a PVRz file.  If both tilesets (and their PVRz files) aren't already in the same game, things are a bit trickier.

Link to comment
7 hours ago, Sam. said:

IF AND ONLY IF both BG0200.TIS and BD0010.TIS are both PVRz-based tilesets AND both are already in the same game (along with their associated PVRz files)

Well, that means this would only work for EET and not for separate BG1/SoD games.  At least I know what I'm attempting isn't possible and that I should try another method.  Thank you. And thank you for explaining the different file types.  I knew they were different but not how they were different.

Much appreciated. :)

Link to comment
1 hour ago, Lauriel said:

Well, that means this would only work for EET and not for separate BG1/SoD games.  At least I know what I'm attempting isn't possible and that I should try another method.  Thank you. And thank you for explaining the different file types.  I knew they were different but not how they were different.

Much appreciated. :)

I said that it would be a bit trickier, not that it wouldn't be possible.  The first thing you'll need to do is figure out which PVRz file(s) the tiles you are interested in are pointing to.  You should be able to use the ps_tileset_info function to look it up.  You should then fall into 1 of 2 categories:

1. The PVRz file names referenced do NOT already exist in the game you want to add them to.  If this is the case, just dump the PVRz files into the override folder and proceed as I previously suggested.

2.  The PVRz file names referenced DO already exist in the game.  In this case, you'll need to remap them.  Export the desired tiles with the ps_tileset_export_tiles function, but specify "tis" as the OutType.  You'll also need to extract the referenced PVRz files from the game, using NearInfinity or WeiDU.  Rename your new mini-tileset to any valid name not already in the target game, preferably with your modder prefix if you have one.  Next, use this method to install the tileset into the target game and update the PVRz references.  Now proceed as I previously suggested, but using this newly updated tileset.  Afterward you can delete the TIS file, but make sure to leave the PVRz files in the game.

Link to comment
6 hours ago, Sam. said:

If this is the case, just dump the PVRz files into the override folder

You're dealing with a rank amateur.  I don't even know how to find those files.  They are invisible to me when I use NI and DLTCEP - at least I've not ever found them.  I'll dig in your tool to see if I can get a clue where they reside.  I've never looked inside a BIF file.  I imagine they're there somewhere.

 

6 hours ago, Sam. said:

You'll also need to extract the referenced PVRz files from the game, using NearInfinity

I guess NI has hidden talents.  How would I do this?

Nevermind, I'm blind as a bat.  I see the entire section called PVRZ now that I actually am awake.

Edited by Lauriel
Link to comment

I've made a small tileset using DLTCEP of just the open door in question from BG0200 and exported as a TIS.  I then used tile2ee to make separate TIS and PVRz files from it.  Now, the export/import using your tool will be from a PVRZ that is not in the game, correct?

10 hours ago, Sam. said:

1. The PVRz file names referenced do NOT already exist in the game you want to add them to.  If this is the case, just dump the PVRz files into the override folder and proceed as I previously suggested.

So I should be able to simply copy the new PVRz file to override and the modified TIF should show up correctly, right?

Then I'm not understanding something because the result was a modified BG0010.TIF that has different tiles where they should be different, just not the correct ones.

Exact steps I've taken:

Spoiler
  • Started DLCT Editor Pro v7.7
  • Selected Edit->Area (ARE,WED)
  • Hit the "Load External Area" button
  • Selected BG0200.ARE
  • Hit "Edit wed" button
  • With overlay 1 of 5 selected, hit the 'Extract' button
  • Hit the 'Preview selection' Button
  • Checked the 'Show grid' box
  • Scrolled to the door I want to export and left clicked on the tile of it's upper left corner
  • Hit the 'Select top left' button
  • Back in the grid, left clicked on the tile of the door's lower right corner
  • Hit the 'Select bottom right' button (this left me with 4 tiles just of the open door)
  • Hit the 'Save as TIS' button and saved it off into a work folder I call 'Ignore' so it won't get uploaded to GitHub
  • Closed DLCTEP
  • Copied the exported TIS to a working folder and renamed it to #LLH0Open.tis (so the resulting PVRz would still have my prefix)
  • Copied tile2ee.exe into my working folder
  • Ran 'tile2ee -f 2 -o processed #LLH0Open.tis' which resulted in a new #LLH0Open.tis (in the processed folder) and #LH0Open00.pvrz
  • Ran the following code in WeiDU:
    COPY ~%mod_root%/objects/processed/#LH0Open00.pvrz~ ~override~
    
    		// Snag open door tiles from BG1 area
    		COPY_EXISTING ~%mod_root%/objects/processed/#LLH0Open.tis~ ~override~
    			LPF ps_tileset_export_tiles
    				INT_VAR
    					Pos = 0 
    					Count = 2
    				STR_VAR
    					OutTileDir = EVAL ~%mod_root%/objects/processed~
    					OutType = "tis"
    			END
    		
    			LPF ps_tileset_export_tiles
    				INT_VAR
    					Pos = 2 
    					Count = 2
    				STR_VAR
    					OutTileDir = EVAL ~%mod_root%/objects/processed~
    					OutType = "tis"
    			END
    		BUT_ONLY_IF_IT_CHANGES
    
    		COPY_EXISTING ~BD0010.TIS~ ~override~
    			// Add the door graphic to the area tile set
    			LPF ps_tileset_add_tiles
    				INT_VAR 
    					Pos = 140
    					MaxCount = 2
    				STR_VAR 
    					TileDir = EVAL "%mod_root%/objects/processed" 
    					TileRegExp = "#LLH0Open_0000-0002.tis"
    					Method = "Replace" 
    				RET Count
    			END
    			
    			LPF ps_tileset_add_tiles
    				INT_VAR 
    					Pos = 160
    					MaxCount = 2
    				STR_VAR 
    					TileDir = EVAL "%mod_root%/objects/processed" 
    					TileRegExp = "#LLH0Open_0002-0004.tis"
    					Method = "Replace" 
    				RET Count
    			END
    		BUT_ONLY_IF_IT_CHANGES	

     

 

EDIT: Follow-up - I did an NI 'Find References' in TIS files on the new pvrz file, it found none.  So, I guess, the imported tiles have no idea that they're supposed to look in that file for directions.

EDIT: Another follow-up - I ran ps_tileset_info against the new TIS file and it said it "is a PVRz-based tileset referencing #LH0Open**.pvrz files.", so it should qualify as a new pvrz file not in the game.  Is the name causing issues because it's longer than expected?  I'll try to shorten it... Tried that - made no difference.

EDIT: Follow-up #3 - I ran ps_tileset_info against the results of the latest exports (exported from #LLOpn instead of #LLH0Open) :transitions/objects/processed/#LLOpn_0000-0002.tis" is a PVRz-based tileset referencing #LOpn_0000-0002**.pvrz files.  It doesn't use the 'mother' pvrz file.  It uses it's own and I don't know how to get a handle on that one.

EDIT: Follow-up #4 - When I open #LLOpn_0000-0002.tis and #LLOpn_0002-0004.tis with NI - they show up as gray squares.  When I open #LLOpn.tis with NI, I see the tiles for the open door as expected.

EDIT: Follow-up #5 - I exported 2 small tilesets using DLCTEP so I could skip the ps_tileset_export_tiles part and copied their pvrz files into override since I had them now.  The results were the same.  The tiles in BD0010.TIS are changed but to the wrong tiles.

EDIT: Follow-up #6 - sick of me yet? LOL When I open DB0010.TIS in NI, the tiles that have been replaced are gray. They contain no image. I'm going to try option #2 (use this method to install the tileset into the target game and update the PVRz references). Tomorrow...it's getting late.  But I'll post another update.  Won't y'all be thrilled. 🙃

EDIT: Follow-up #7 - ok, I lied.  I couldn't walk away without trying something.  I can 'one more thing' myself until dawn sometimes. I tried exporting the tiles directly from the BG1 TIS (in this case BG0200.tis) into two small tilesets, one containing the top two tiles, the other one containing the bottom two.  I was about to run Argent77s functions on them when I noticed..I can't.  Here's his example:

Spoiler

  

Quote
// Installing all TIS files from the specified folder
ACTION_BASH_FOR ~%MOD_FOLDER%/tis~ ~^.+\.tis$~ BEGIN
  COPY ~%BASH_FOR_FILESPEC%~ ~override~
    LPF UPDATE_PVRZ_INDICES RET original_base_index new_base_index END

  // Installing associated PVRZ files for each tileset individually
  ACTION_IF (new_base_index >= 0) BEGIN
    LAF TIS_RES_TO_PVRZ STR_VAR tis_res = EVAL ~%BASH_FOR_FILESPEC%~ RET prefix END

    ACTION_BASH_FOR ~%MOD_FOLDER%/tis~ ~^%prefix%.+\.pvrz$~ BEGIN
      LAF INSTALL_PVRZ
        INT_VAR original_base_index new_base_index
        STR_VAR source_file = EVAL ~%BASH_FOR_FILESPEC%~
        RET success DEST_FILESPEC
      END

      ACTION_IF (NOT success) BEGIN
        FAIL ~Could not install "%BASH_FOR_FILESPEC%"!~
      END
    END
  END ELSE BEGIN
    FAIL ~Could not install "%BASH_FOR_FILESPEC%"!~
  END
END

 

 

The problem is, he expects the pvrz files associated with the tis files to exist.  They don't.  There are no pvrz files produced when tiles are exported using ps_tileset_export_tiles.

EDIT: Follow-up #8 - my last on this subject unless new information comes to light.  I attempted to run Argent77's pvrz install functions against the files produced by exporting tilesets from DLCTEP and modifying them with tile2ee to product separate TIS and PVRZ files, but the function produced the error "Invalid or corrupted BAM V2 or MOS V2 resource found. No changes have been made."  I've run out of ideas and things to try.

Edited by Lauriel
Link to comment

I have realized I had forgotten about a vitally important fact which led me to give you bad information which in turn has likely caused you no small amount of frustration and wasted time.  I sincerely apologize.

On 8/25/2021 at 7:48 AM, Sam. said:

IF AND ONLY IF both BG0200.TIS and BD0010.TIS are both PVRz-based tilesets AND both are already in the same game (along with their associated PVRz files), then you should be able to export the tiles from BG0200 (ps_tileset_export_tiles) and use them to overwrite tiles in BD0010 using ps_tileset_add_tile with STR_VAR Method = "Replace".

This is untrue.

19 hours ago, Sam. said:

Rename your new mini-tileset to any valid name not already in the target game, preferably with your modder prefix if you have one.

This was terrible advice.

 

Here's why:  from the IESDP:

Quote

Filenames of referenced PVRZ resources are made up from the first character of the TIS filename, the four digits of the area code, the optional 'N' from night tilesets and this page value as a zero-padded two digits number. Example: AR2600N.TIS would refer to A2600Nxx.PVRZ where xx indicates the PVRZ page.

If you're wanting to replace tiles in BD0010.TIS, then your exported tiles should be BL0010.TIS and the PVRz file it references should be B0010xx.PVRZ.  Here, L is part of your modder prefix and xx is the original index of the PVRz.  You should then be able to install the files with Argent77's function and then replace the tiles with PS_Tileset.  However, I'm thinking this whole process of exporting tiles is entirely unnecessary.  I'll try to come up with a working example of how I'd do it.

 

Link to comment
1 hour ago, Sam. said:

I'll try to come up with a working example of how I'd do it.

Oh you're awesome!  Thank you.

I was unable to sleep last night having this on my mind, thinking there had to be an easier way.  My thinking, before finally dozing off, was to convert both BG0200.TIS and BD0010.TIS to palette, swap tiles, then reconvert them both back to PVRz.  I don't even know this is possible but it was what I was going to try this morning.

Link to comment
32 minutes ago, Lauriel said:
1 hour ago, Sam. said:

I'll try to come up with a working example of how I'd do it.

Oh you're awesome!  Thank you.

Let's start off simple, and then we can add layers of automation/safety as we get more comfortable with the process.

For a test, I decided to move a door from AR0200 to BD0010 in BGEE w/ SoD.  The first step was to use NI's Area Viewer to figure out which tiles I wanted to move.  I determined I wanted to move tiles 2985, 2986, 3054, and 3055 from AR0200.tis to tiles 140, 141, 160, and 161 in BD0010.tis.  To double check my maths, I used this to blank out those tiles to make sure I got the right ones:

// Test that we've picked the correct tiles by blanking them out and then check with NI's area viewer or in game
COPY_EXISTING ~AR0200.tis~ ~override~
  LPF ps_tileset_add_tiles INT_VAR Pos = 2985 MaxCount = 2 PVRz_Page = "-1" PVRz_X = 0 PVRz_Y = 0 STR_VAR Method = "Replace" RET Count END // Blank out a tile in a PVRz-based tileset using a manually specified tile
  LPF ps_tileset_add_tiles INT_VAR Pos = 3054 MaxCount = 2 PVRz_Page = "-1" PVRz_X = 0 PVRz_Y = 0 STR_VAR Method = "Replace" RET Count END // Blank out a tile in a PVRz-based tileset using a manually specified tile
BUT_ONLY

COPY_EXISTING ~BD0010.tis~ ~override~
  LPF ps_tileset_add_tiles INT_VAR Pos = 140 MaxCount = 2 PVRz_Page = "-1" PVRz_X = 0 PVRz_Y = 0 STR_VAR Method = "Replace" RET Count END // Blank out a tile in a PVRz-based tileset using a manually specified tile
  LPF ps_tileset_add_tiles INT_VAR Pos = 160 MaxCount = 2 PVRz_Page = "-1" PVRz_X = 0 PVRz_Y = 0 STR_VAR Method = "Replace" RET Count END // Blank out a tile in a PVRz-based tileset using a manually specified tile
BUT_ONLY

Looked at them in NI's are viewer, and they were the right ones so I uninstalled this code to reset them.  The next step was to determine which PVRz file the 4 tiles from AR0200.tis were using, and what the X and Y offsets were.

COPY_EXISTING ~AR0200.tis~ ~override~
  LPF ps_tileset_info INT_VAR Verbose = 2 Log = 1 END // Log verbose output of PVRz-based tileset to file
BUT_ONLY

Looked at the log and extracted:

Quote

Tile 2985:
  PVRz_Page = 8 (A020008.pvrz)
  PVRz_X = 128
  PVRz_Y = 704

Tile 2986:
  PVRz_Page = 8 (A020008.pvrz)
  PVRz_X = 192
  PVRz_Y = 704

Tile 3054:
  PVRz_Page = 8 (A020008.pvrz)
  PVRz_X = 128
  PVRz_Y = 768

Tile 3055:
  PVRz_Page = 8 (A020008.pvrz)
  PVRz_X = 192
  PVRz_Y = 768

Last bit of info we need is an unused PVRz index for BD0010.tis.  Looking for B0010**.pvrz files in NI, we see that 00-02 are used, so 03 is free.  Now let's install the new door:

COPY_EXISTING ~A020008.pvrz~ ~override\B001003.pvrz~
COPY_EXISTING ~BD0010.tis~ ~override~
  LPF ps_tileset_add_tiles INT_VAR Pos = 140 MaxCount = 1 PVRz_Page = 3 PVRz_X = 128 PVRz_Y = 704 STR_VAR Method = "Replace" RET Count END // Overwrite tile
  LPF ps_tileset_add_tiles INT_VAR Pos = 141 MaxCount = 1 PVRz_Page = 3 PVRz_X = 192 PVRz_Y = 704 STR_VAR Method = "Replace" RET Count END // Overwrite tile
  LPF ps_tileset_add_tiles INT_VAR Pos = 160 MaxCount = 1 PVRz_Page = 3 PVRz_X = 128 PVRz_Y = 768 STR_VAR Method = "Replace" RET Count END // Overwrite tile
  LPF ps_tileset_add_tiles INT_VAR Pos = 161 MaxCount = 1 PVRz_Page = 3 PVRz_X = 192 PVRz_Y = 768 STR_VAR Method = "Replace" RET Count END // Overwrite tile
BUT_ONLY

And it works.image.png.57e435ba862c5acf1f9787f6e4b17f2e.png

Again, much of this could/should be automated further, but now we have an outline of what to do.

Link to comment
53 minutes ago, Sam. said:

Let's start off simple

It works!  And so so simple.  I had to make a few adjustments for EET, but nothing terrible.  Thank you so much.  I've learned a lot doing this process.

53 minutes ago, Sam. said:

Again, much of this could/should be automated further, but now we have an outline of what to do.

Yeah, this is pretty much a hard-coded way of doing it.  It's progress, though, and it makes me very happy! Thank you :)

The only thing you didn't explain was how you came up with the following:

PVRz_X = 128 PVRz_Y = 704

Never mind - I see it's in the log

Edited by Lauriel
Link to comment

I've automated those parts that can be automated.  We still need to do our research on the where to snag the tiles and where to put them, but this little bit helps with the naming of the PVRz...

Spoiler
		OUTER_SPRINT source_pvrz "A020008"
		OUTER_SPRINT page ~-1~
		OUTER_SET strt_idx = 0
		OUTER_SET ok_to_proceed = 0
		ACTION_IF GAME_IS ~eet~ THEN BEGIN
			OUTER_SPRINT source_pvrz "B020008"
			OUTER_SET strt_idx = 50
		END
		OUTER_FOR (idx = strt_idx; idx < 99 && ok_to_proceed = 0; idx = idx + 1) BEGIN
			ACTION_IF idx < 10 THEN BEGIN
				OUTER_SPRINT page ~0%idx%~
			END ELSE BEGIN
				OUTER_SPRINT page ~%idx%~
			END
			ACTION_IF NOT FILE_EXISTS_IN_GAME ~B0010%page%.pvrz~ THEN BEGIN
				OUTER_SET ok_to_proceed = 1
			END
		END
		
		ACTION_IF ok_to_proceed = 1 THEN BEGIN	// This is sort of overkill... but ya never know
			COPY_EXISTING ~%source_pvrz%.PVRZ~ ~override\B0010%page%.pvrz~
			COPY_EXISTING ~BD0010.tis~ ~override~
				LPF ps_tileset_add_tiles INT_VAR Pos = 140 MaxCount = 1 PVRz_Page = %page% PVRz_X = 128 PVRz_Y = 704 STR_VAR Method = "Replace" RET Count END
				LPF ps_tileset_add_tiles INT_VAR Pos = 141 MaxCount = 1 PVRz_Page = %page% PVRz_X = 192 PVRz_Y = 704 STR_VAR Method = "Replace" RET Count END
				LPF ps_tileset_add_tiles INT_VAR Pos = 160 MaxCount = 1 PVRz_Page = %page% PVRz_X = 128 PVRz_Y = 768 STR_VAR Method = "Replace" RET Count END
				LPF ps_tileset_add_tiles INT_VAR Pos = 161 MaxCount = 1 PVRz_Page = %page% PVRz_X = 192 PVRz_Y = 768 STR_VAR Method = "Replace" RET Count END
			BUT_ONLY_IF_IT_CHANGES
		END

 

What would really be nice here is being able to determine if the source file is equivalent to one of the target pages already installed.

Edited by Lauriel
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...