Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: HoMM 3 Complete & HotA Modding Guide
Thread: HoMM 3 Complete & HotA Modding Guide This thread is 2 pages long: 1 2 · «PREV
Juas
Juas


Hired Hero
posted January 17, 2024 11:56 PM
Edited by Juas at 00:03, 18 Jan 2024.

Hello, Kabanos.
If you mean the starting Spells and Secondary Skills of Heroes, I don't know how to do that yet.

I know Karyoplasma is creating a program called "Hero Editor" that let's you "edit hero secondaries, specialties and starting army.".
He posted a link to it on page 107 of "How to edit HotA?" thread (I think it is on beta state, and only works for 1.7 for the moment).

I'm glad you liked the tutorial

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 05:59 PM

phoenix4ever said:

HotA creatures are actually quite easy to edit.
They are all in the beginning of HotA.dat, you can even see the text description on the right (at least in Hex Editor Neo) which creature it relates to.
It should be fairly easy to figure out what the numbers around these addresses stand for or I can maybe help, if you tell my exactly what you want?


Is hex editing the only way to edit their names and basic stats like number and whatnot? I was looking with MMArchive but could only find the original creatures in CRTRAITS
____________
What are Homm Songs based on?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
phoenix4ever
phoenix4ever


Legendary Hero
Heroes is love, Heroes is life
posted January 22, 2024 06:04 PM
Edited by phoenix4ever at 18:05, 22 Jan 2024.

Cove and Factory creatures + Fangarms, Satyrs, Leprechauns and Steel Golems must be edited in HotA.dat, they can't be edited through crtraits or other txt files.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 06:11 PM
Edited by LordCameron at 18:21, 22 Jan 2024.

So I edited a name and now it is crashing when I try to load it. Is there some sort of anti-cheat you have to avoid tripping?

Edit: or do the names need to be the exact same length? I just noticed I accidentally deleted an 06 value at the end of the name, so I'm guess that was at least partially the culprit.
Going to do a bit more fiddling

Edit Edit: I can easily change the name to an equal length name, but when I try to change the length of the name the game no longer loads. I'm only overwriting 00 s so not sure what I need to change to make that work
____________
What are Homm Songs based on?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
FirePaladin
FirePaladin


Legendary Hero
DoR Modder
posted January 22, 2024 06:25 PM

I might be wrong, but you need to change the length of the string.
____________
Enshackling time itself, heralds of the Ancients among their heat-depleted land.... Who could they be, who could rally the beings of the East and the North and control the mortals' fate?

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted January 22, 2024 06:28 PM
Edited by AlexSpl at 18:29, 22 Jan 2024.

There are two main types of strings in this game. With preceeding length (pascal-style) and null-terminated (c-style), so depends which one you are trying to change. Also notice that you cannot wipe any characters following a string.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 06:49 PM

Okay so I have this: 06 00 00 00 53 65 61 6D 61 6E 06 00 00 00 53 65 61 6D 65 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Which is "Seaman" and "Seamen"

and I changed it to this

06 00 00 00 53 61 69 6C 6F 72 07 00 00 00 53 61 69 6C 6F 72 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

"Sailor" "Sailors"

Note I changed what I assume denotes the length of the string in bold.

All I can figure is the sixteen 00 s after the names are important, but I'm not sure what to do about that.

____________
What are Homm Songs based on?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted January 22, 2024 06:56 PM

Quote:
06 00 00 00 53 65 61 6D 61 6E

I guess 06 00 00 00 is the length of 53 65 61 6D 61 6E (probably "Seaman", can't convert on the fly). Then the next string follows. So, you have to change the length (06 00 00 00) and the actual string. To make strings longer you will need a pointer to them.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 07:07 PM
Edited by LordCameron at 19:08, 22 Jan 2024.

Okay I did it! All I had to do was add an extra 00 after I overwrote the one with my 73.

I didn't actually know you could add (make the file larger without breaking everything) instead of overwrite, but ctrl-c ctrl-v seems to have done the trick
____________
What are Homm Songs based on?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted January 22, 2024 07:09 PM

Yeah, congratulations Was writing a reply In general it depends on how this array of strings is parsed.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 07:15 PM

Thanks Feeling pretty proud for figuring it out even if it is really basic haha. Most hex editing I've done before is just switching the victory condition in Civ V save files.
____________
What are Homm Songs based on?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted January 22, 2024 07:15 PM
Edited by AlexSpl at 19:18, 22 Jan 2024.

Warning Never do such a thing with an executable or dll. HotA.dat has a custom format, so it allows you to change its length, I suppose.

Or... you've just overwritten something else. You never know

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
LordCameron
LordCameron


Known Hero
Veteran of the Succession Wars
posted January 22, 2024 07:18 PM
Edited by LordCameron at 19:19, 22 Jan 2024.

Good to know. I did think it was strange that it worked because I could have sworn I'd read somewhere not to do that. Like you said, just this file I guess. If my game explodes somewhere down the line I'll update my post

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted January 22, 2024 07:56 PM

It shouldn't. If the parser reads a block of strings it should consider its length, so the next block may be read just after the block of strings. So called consequential reading. In a nutshell, if the whole HotA.dat is loaded into the memory at once, it's OK to make it bigger. And I think it's the case.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Nikulani
Nikulani

Tavern Dweller
posted January 25, 2024 12:27 AM

homm3 creature modding

Hi Juas and everybody, I am new to this whole modding business. Maybe therefore I cant see the point in modifying hero skills and stuff because this is something even the map editior allows you to do. What I am looking for is a post which transparently shows step by step how to open the lod files to then substitute bmps from one creature of a faction against my own bmps. So that finally my 6 year old son sees himself on the battlefield instead of lets say magies. That cant be too complicated. I did not try any implementation right now but saw in your thread, Juas, that things are more hidden then one might expect them to be. At least I already found the mmarchive, lod tool and much more. But some of the guys producing cove and factory or other mods must be able to showcase how their business works simply in a 5min youtube video for a single detail to be modified, right? Does anybody of you know of such a kind of tutorial? Far off, but closest to this I found the following from one of the vcmi-dudes:

https://forum.vcmi.eu/t/how-to-open-def-sprites/6174/7

Any ideas? Thx a lot in advance!
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Phoenix4ever
Phoenix4ever


Legendary Hero
Heroes is love, Heroes is life
posted January 25, 2024 08:00 AM

Don't expect any help from the official HotA Crew, they are the last ones to help you mod HotA sadly.
I can't help you with the thing you are asking either, but hopefully someone else can...

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
FirePaladin
FirePaladin


Legendary Hero
DoR Modder
posted January 25, 2024 03:14 PM

@Nikulani

I'll be a bit brief, but feel free to ask for details.

I assume you can use MMArchive to open .lod files found in the /Data folder of H3, and can preview .def files inside them (such as those of combat creatures: they start with C; adv map ones start with AVW).

Get Defr Preview and Def Tool from here: https://grayface.github.io/wog/

Extract the .def you want to edit or replace, such as Magi. Open it with Def Preview. There should be a panel at the top. Press the 5th button "Extract All for DefTool". Then, open the newly generated .hdl file using Def Tool.

For editing the frames, open them in Adobe Photoshop or Gimp and edit each one of them manually (remember to respect the #00ffff color pixels, which are replaced with transparency in-game). You will also have to add their final, edited outline to the shadow frames, found in a subfolder with a self-explanatory name. Once you're done with all that, open DefTool, press on the big square button with a wrench on the right, and you got your new Def file. You can check it out with Def preview, and if it looks well, replace the original with it in .lod (but you can make a plugin that does not alter the game files, if using H3 Complete/SoD with HD+ mod).

Hope this helps and will make your son happy!
____________
Enshackling time itself, heralds of the Ancients among their heat-depleted land.... Who could they be, who could rally the beings of the East and the North and control the mortals' fate?

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
Juas
Juas


Hired Hero
posted February 15, 2024 01:03 PM

Nikulani said:
Hi Juas and everybody


Hi Nikulani!

Good thing that FirePaladin responded you, because I don't know anything about modding graphics. Hope that works for you and your son becomes a new fan of the game

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Parmenides
Parmenides

Tavern Dweller
posted March 31, 2024 09:20 PM

What would be the most straightforward method to edit the sound effects of the dwellings on the adventure map? In particular, I want to change each of the "neutral" dwellings that have the same "sword" sound effect and match them with something more appropriate (e.g. change the Crystal Dragon dwelling to either the Cyclops Cave effect or perhaps the Crystal Cavern). I'm using Homm3 Complete SoD version, not HotA.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted March 31, 2024 10:52 PM

See the following function @ 4AB100h:

void __thiscall advManager::EventSound(advManager *this, int eventID, int extraInfo)
{
   unsigned int v3; // kr28_4
   unsigned int v4; // ebx
   char *v5; // edi
   char *v6; // edi
   const char *v7; // esi
   char v8; // cl
   unsigned int v9; // kr2C_4
   unsigned int v10; // ecx
   const char *v11; // esi
   unsigned int v12; // kr30_4
   char *v13; // edi
   unsigned int v14; // kr34_4
   unsigned int v15; // kr38_4
   char *v16; // edi
   unsigned int v17; // kr3C_4
   unsigned int v18; // kr40_4
   char *v19; // edi
   unsigned int v20; // kr44_4
   unsigned int v21; // kr48_4
   char *v22; // edi
   unsigned int v23; // kr4C_4
   unsigned int v24; // kr50_4
   char *v25; // edi
   unsigned int v26; // kr54_4
   unsigned int v27; // kr58_4
   char *v28; // edi
   unsigned int v29; // kr5C_4
   char *v30; // edi
   char v31; // al
   unsigned int v32; // ecx
   const char *v33; // ecx
   char v34; // al
   int v35; // [esp+Ch] [ebp-1Ch] BYREF
   char *v36; // [esp+10h] [ebp-18h]
   int v37; // [esp+14h] [ebp-14h]
   int v38; // [esp+24h] [ebp-4h]

   LOBYTE(v35) = HIBYTE(eventID);
   std::string::string(&v35, 0);
   v38 = 0;
   switch ( eventID )
   {
       case OBJECT_ALTAR_OF_SACRIFICE:
       case OBJECT_PANDORAS_BOX:
       case OBJECT_BLACK_MARKET:
       case OBJECT_CORPSE:
       case OBJECT_OBELISK:
       case OBJECT_PYRAMID:
       case OBJECT_DEN_OF_THIEVES:
           string_memcpy(&v35, "Mystery.wav", strlen("Mystery.wav"));
           break;
       case OBJECT_ARENA:
       case OBJECT_MARLETTO_TOWER:
       case OBJECT_MERCENARY_CAMP:
           v12 = strlen("Nomad.wav") + 1;
           v4 = v12 - 1;
           if ( string_allocate_memory(&v35, v12 - 1, 1) )
           {
               v13 = v36;
               qmemcpy(v36, "Nomad.wav", 4 * (v4 >> 2));
               v7 = &aNomad_wav[4 * (v4 >> 2)];
               v6 = &v13[4 * (v4 >> 2)];
               v8 = v12 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_ARTIFACT:
       case OBJECT_SHIPWRECK_SURVIVOR:
           v14 = strlen("Treasure.wav") + 1;
           v4 = v14 - 1;
           if ( string_allocate_memory(&v35, v14 - 1, 1) )
           {
               v10 = v14 - 1;
               v11 = "Treasure.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_BORDERGUARD:
       case OBJECT_KEYMASTER:
       case OBJECT_SUBTERRANEAN_GATE:
       case OBJECT_BORDER_GATE:
       case OBJECT_QUEST_GUARD:
           string_memcpy(&v35, "Cavehead.wav", strlen("Cavehead.wav"));
           break;
       case OBJECT_BUOY:
       case OBJECT_FOUNTAIN_OF_YOUTH:
       case OBJECT_OASIS:
       case OBJECT_RALLY_FLAG:
       case OBJECT_WATERING_HOLE:
           v18 = strlen("Morale.wav") + 1;
           v4 = v18 - 1;
           if ( string_allocate_memory(&v35, v18 - 1, 1) )
           {
               v19 = v36;
               qmemcpy(v36, "Morale.wav", 4 * (v4 >> 2));
               v7 = &aMorale_wav[4 * (v4 >> 2)];
               v6 = &v19[4 * (v4 >> 2)];
               v8 = v18 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_CAMPFIRE:
       case OBJECT_IDOL_OF_FORTUNE:
       case OBJECT_MYSTICAL_GARDEN:
           v3 = strlen("Expernce.wav") + 1;
           v4 = v3 - 1;
           if ( string_allocate_memory(&v35, v3 - 1, 1) )
           {
               v5 = v36;
               qmemcpy(v36, "Expernce.wav", 4 * (v4 >> 2));
               v7 = &aExpernce_wav[4 * (v4 >> 2)];
               v6 = &v5[4 * (v4 >> 2)];
               v8 = v3 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_CARTOGRAPHER:
       case OBJECT_COVER_OF_DARKNESS:
       case OBJECT_EYE_OF_MAGI:
       case OBJECT_HUT_OF_MAGI:
       case OBJECT_LIGHTHOUSE:
       case OBJECT_REDWOOD_OBSERVATORY:
       case OBJECT_PILLAR_OF_FIRE:
           string_memcpy(&v35, "Lighthouse.wav", strlen("Lighthouse.wav"));
           break;
       case OBJECT_SWAN_POND:
       case OBJECT_FAERIE_RING:
       case OBJECT_FOUNTAIN_O_FORTUNE:
       case OBJECT_MERMAID:
           v20 = strlen("Luck.wav") + 1;
           v4 = v20 - 1;
           if ( string_allocate_memory(&v35, v20 - 1, 1) )
           {
               v10 = v20 - 1;
               v11 = "Luck.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_CREATURE_BANK:
       case OBJECT_DERELICT_SHIP:
       case OBJECT_PRISON:
       case OBJECT_SHIPWRECK:
           string_memcpy(&v35, "Rogue.wav", strlen("Rogue.wav"));
           break;
       case OBJECT_CREATURE_GENERATOR1:
       case OBJECT_CREATURE_GENERATOR4:
       case OBJECT_GARRISON:
       case OBJECT_HILL_FORT:
       case OBJECT_REFUGEE_CAMP:
       case OBJECT_SCHOOL_OF_WAR:
           v9 = strlen("Military.wav") + 1;
           v4 = v9 - 1;
           if ( string_allocate_memory(&v35, v9 - 1, 1) )
           {
               v10 = v9 - 1;
               v11 = "Military.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_DRAGON_UTOPIA:
           v26 = strlen("Dragon.wav") + 1;
           v4 = v26 - 1;
           if ( string_allocate_memory(&v35, v26 - 1, 1) )
           {
               v10 = v26 - 1;
               v11 = "Dragon.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_FLOTSAM:
       case OBJECT_LEAN_TO:
       case OBJECT_WAGON:
       case OBJECT_WATER_WHEEL:
       case OBJECT_WINDMILL:
           string_memcpy(&v35, "Genie.wav", strlen("Genie.wav"));
           break;
       case OBJECT_GARDEN_OF_REVELATION:
       case OBJECT_SANCTUARY:
           v21 = strlen("GetProtection.wav") + 1;
           v4 = v21 - 1;
           if ( string_allocate_memory(&v35, v21 - 1, 1) )
           {
               v22 = v36;
               qmemcpy(v36, "GetProtection.wav", 4 * (v4 >> 2));
               v7 = &aGetprotection_[4 * (v4 >> 2)];
               v6 = &v22[4 * (v4 >> 2)];
               v8 = v21 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_LIBRARY_OF_ENLIGHTENMENT:
       case OBJECT_STAR_AXIS:
       case OBJECT_SCHOLAR:
       case OBJECT_LEARNING_STONE:
       case OBJECT_TREE_OF_KNOWLEDGE:
       case OBJECT_UNIVERSITY:
       case OBJECT_WITCH_HUT:
           v17 = strlen("Gazebo.wav") + 1;
           v4 = v17 - 1;
           if ( string_allocate_memory(&v35, v17 - 1, 1) )
           {
               v10 = v17 - 1;
               v11 = "Gazebo.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_SCHOOL_OF_MAGIC:
       case OBJECT_MAGIC_SPRING:
       case OBJECT_MAGIC_WELL:
           v15 = strlen("Faerie.wav") + 1;
           v4 = v15 - 1;
           if ( string_allocate_memory(&v35, v15 - 1, 1) )
           {
               v16 = v36;
               qmemcpy(v36, "Faerie.wav", 4 * (v4 >> 2));
               v7 = &aFaerie_wav[4 * (v4 >> 2)];
               v6 = &v16[4 * (v4 >> 2)];
               v8 = v15 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_MINE:
           if ( armyGroup::HasCreatures(&gpGame->minePool.first[extraInfo].guards) )
               string_memcpy(&v35, "mystery.wav", strlen("mystery.wav"));
           else
               string_memcpy(&v35, "flagmine.wav", strlen("flagmine.wav"));
           break;
       case OBJECT_OCEAN_BOTTLE:
       case OBJECT_SHIPYARD:
       case OBJECT_SIGN:
       case OBJECT_STABLES:
       case OBJECT_TAVERN:
       case OBJECT_TRADING_POST:
       case OBJECT_WAR_MACHINE_FACTORY:
           v24 = strlen("Store.wav") + 1;
           v4 = v24 - 1;
           if ( string_allocate_memory(&v35, v24 - 1, 1) )
           {
               v25 = v36;
               qmemcpy(v36, "Store.wav", 4 * (v4 >> 2));
               v7 = &aStore_wav[4 * (v4 >> 2)];
               v6 = &v25[4 * (v4 >> 2)];
               v8 = v24 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_SEA_CHEST:
       case OBJECT_TREASURE_CHEST:
           string_memcpy(&v35, "Chest.wav", strlen("Chest.wav"));
           break;
       case OBJECT_SEER_HUT:
           v27 = strlen("Quest.wav") + 1;
           v4 = v27 - 1;
           if ( string_allocate_memory(&v35, v27 - 1, 1) )
           {
               v28 = v36;
               qmemcpy(v36, "Quest.wav", 4 * (v4 >> 2));
               v7 = &aQuest_wav[4 * (v4 >> 2)];
               v6 = &v28[4 * (v4 >> 2)];
               v8 = v27 - 1;
               goto LABEL_41;
           }
           break;
       case OBJECT_CRYPT:
       case OBJECT_WARRIORS_TOMB:
           string_memcpy(&v35, "Graveyard.wav", strlen("Graveyard.wav"));
           break;
       case OBJECT_SHRINE_OF_MAGIC_INCANTATION:
       case OBJECT_SHRINE_OF_MAGIC_GESTURE:
       case OBJECT_SHRINE_OF_MAGIC_THOUGHT:
       case OBJECT_TEMPLE:
           v23 = strlen("Temple.wav") + 1;
           v4 = v23 - 1;
           if ( string_allocate_memory(&v35, v23 - 1, 1) )
           {
               v10 = v23 - 1;
               v11 = "Temple.wav";
               goto LABEL_40;
           }
           break;
       case OBJECT_SIRENS:
       case OBJECT_WHIRLPOOL:
           v29 = strlen("Danger.wav") + 1;
           v4 = v29 - 1;
           if ( string_allocate_memory(&v35, v29 - 1, 1) )
           {
               v10 = v29 - 1;
               v11 = "Danger.wav";
LABEL_40:
               v30 = v36;
               v31 = v10;
               v32 = v10 >> 2;
               qmemcpy(v36, v11, 4 * v32);
               v7 = &v11[4 * v32];
               v6 = &v30[4 * v32];
               v8 = v31;
LABEL_41:
               qmemcpy(v6, v7, v8 & 3);
               std::string:perator+=(&v35, v4);
           }
           break;
       default:
           break;
   }
   if ( v37 )
   {
       v33 = v36;
       if ( !v36 )
           v33 = kEmptyString;
       launch_sample(v33, -1, 3);
   }
   if ( v36 )
   {
       v34 = *(v36 - 1);
       if ( !v34 || v34 == -1 )
           operator delete(v36 - 1);
       else
           *(v36 - 1) = v34 - 1;
   }
}

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 2 pages long: 1 2 · «PREV
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.1105 seconds