#!/usr/bin/perl

use strict;

# Usage: combineMods era mod1.dm mod2.dm ... modN.dm newModName
# e.g. combineMods 2 TombKings.dm vaetti.dm MagicMod
# This would combine the two mods and make them both middle era (era 2).

# So far as I know, this script can handle anything that a set of mods can throw at it.

# All the variables that you might want to change as patches for Dom3 come out are here at the top.

# It's important that maxVanillaNationNumber is set sensibly.
# Basically, any nations of this number or lower are assumed to be vanilla nations, and won't
# be touched. This is good, because it allows mods which make changes to vanilla nation (e.g.
# CBM) to be combined with mod nations. However, you have to be careful of nations like
# Teutanion which have nation numbers which overlap with the numbers of the vanilla nations.
# Just fix them before using them with this script.
my $maxVanillaNationNumber = 71;

# These counters should all be set to the maximum available value for the respective item type.
# Ingeniously, weapons, units etc are assigned numbers starting from the maximum and working down,
# so as to minimise the chances of a clash with future vanilla content.
my $weaponCounter = 999;
my $armorCounter = 349;
my $unitCounter = 2999;
my $siteCounter = 949;
my $nationCounter = 93;

# The name type counter is different, because it works through entries in the following array.
my $nametypeCounter = 0;
# This is my estimation of the order in which one might reasonably overwrite nametypes.
my @availableNameTypes = (127, 128, 150, 149, 148, 147, 146, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125);

my %weaponNumbers;
my %armorNumbers;
my %unitNumbers;
my %siteNumbers;
my %nationNumbers;
my %nametypeNumbers;

my %createdArmors;
my $currentlyDescribingArmor;

my %unknownNationNumberFillIns;
my %nametypeFillIns;
my %weaponFillIns;
my %unitFillIns;
my %spellFillIns;

my $fillInCounter = 1;
my $nametypeFillInCounter = 1;
my $weaponFillInCounter = 1;
my $unitFillInCounter = 1;
my $spellFillInCounter = 1;

my $spellCounter;
my $maxSpellCounter;
my %spellIsASummon;
my %spellDamage;

#---------------------------------------
# Start of program
#---------------------------------------


my $era = shift @ARGV;
my $modName = pop @ARGV;
my @mods = @ARGV;

unless (($era == 1) or ($era == 2) or ($era == 3)) {
    print "Invalid era: must be 1, 2 or 3.\n";
    print "Usage: combineMods era mod1.dm mod2.dm ... modN.dm newModName\n";
    print "e.g. combineMods 2 TombKings.dm vaetti.dm MagicMod\n";
    exit;
}

unless (@mods) {
    print "You need to list some mods to combine!\n";
    print "Usage: combineMods era mod1.dm mod2.dm ... modN.dm newModName\n";
    print "e.g. combineMods 2 TombKings.dm vaetti.dm MagicMod\n";
    exit;
}

# Get rid of any ".dm" on the mod name, because that would be a common mistake.
$modName =~ s/\.dm//;

my $eraName;
if ($era == 1) {
    $eraName = "early";
} elsif ($era == 2) {
    $eraName = "middle";
} elsif ($era == 3) {
    $eraName = "late";
}

# Read in all the mod files, and extract the version number of each mod. Also find out how many mod nations we're adding.
my $modCounter;
my @versions;
my $totalModNations;
for my $modFile (@mods) {
    $modCounter++;
    open MODFILE, "<$modFile" or die "Couldn't find file $modFile";
    for (<MODFILE>) {
	chomp;
	if (/^#version ([\d\.]+)/) {
	    $versions[$modCounter] = $1;
	}
	if (/^#selectnation (\d+)/) {
	    if ($1 > $maxVanillaNationNumber) {
		$totalModNations++;
	    }
	}
    }
    close MODFILE;
}

# Ingeniously shift the nation counter down as far as necessary, so it can count upwards.
my $maxNation = $nationCounter;
$nationCounter = $nationCounter - $totalModNations + 1;

print "Name of new mod: ${modName}.dm\n";

open OUTFILE, ">${modName}.dm";

print OUTFILE "#modname \"$modName\"\n";
print OUTFILE "#description \"This mod is an automagic combination mod, incorporating the following original mods:\n\n\n\n";
for (1..@mods) {
    print OUTFILE "$mods[$_-1] v$versions[$_]\n\n";
}
print OUTFILE "\n\nAll mod nations have been placed in the $eraName era.\"\n\n";
print OUTFILE "#version 1.00\n\n";

my $out;

$out =  "This combined mod makes use of the following ID numbers:\n\n";
# The "lowerlimit" strings will be replaced at the end, when we actually know what they are.
$out .= "Armor: armorlowerlimit-$armorCounter\n";
$out .= "Weapons: weaponlowerlimit-$weaponCounter\n";
$out .= "Monsters: unitlowerlimit-$unitCounter\n";
$out .= "Sites: sitelowerlimit-$siteCounter\n";
$out .= "Nations: $nationCounter-$maxNation\n";
$out .= "Nametypes: nametypelist\n\n";

$out .= "--- END OF COMBINED MOD HEADERS - ANY FOLLOWING COMMENTS ARE FROM SOURCE MODS AND MAY BE INCORRECT ---\n\n";

$modCounter = 0;
for my $modFile (@mods) {
    $modCounter++;

    $spellCounter = 0;

    open MODFILE, "<$modFile" or die "Couldn't find file $modFile";
    for (<MODFILE>) {
	chomp;
	my $line = $_;

        # Fix the eras.
        if (/^\#era/) {
            $line = "#era $era";
        }

	# Take out the header lines from each mod.
	if (/^\#modname/) {
	    $line = "";
	}
	if (/^\#description/) {
            $line = "";
	}
	if (/^\#icon/) {
            $line = "";
	}
	if (/^\#version/) {
            $line = "";
	}
	if (/^\#domversion/) {
            $line = "";
	}

	# Spells.
	if (/^\#newspell/ or /^\#selectspell/) {
	    $spellCounter++;
	    if ($spellCounter > $maxSpellCounter) {
		$maxSpellCounter = $spellCounter;
	    }
	} elsif (/^\#effect\s+((".*")|[\w\d]+)/) {
	    my $effect = $1;
	    if (($1 == 1) or ($1 == 10001) or ($1 == 10021)) {
		$spellIsASummon{$modCounter}{$spellCounter} = 1;
	    }
	} elsif (/^\#damage\s+((".*")|[\w\d]+)/) {
	    my $damage = $1;
	    $spellFillIns{$modCounter}{$spellCounter} = "llamaspell${spellFillInCounter}_";
	    $spellFillInCounter++;
	    $spellDamage{$modCounter}{$spellCounter} = $damage;
	    $line = "#damage $spellFillIns{$modCounter}{$spellCounter}";
	}

	# Weapons.
        if (/^\#newweapon\s+((".*")|[\w\d]+)/) {
            my $weapon = $1;
            unless ($weaponFillIns{$modCounter}{$weapon}) {
                $weaponFillIns{$modCounter}{$weapon} = "llamaweapons${weaponFillInCounter}_";
                $weaponFillInCounter++;
            }
            $weaponNumbers{$modCounter}{$weapon} = $weaponCounter;
            $weaponCounter--;
            $line = "#newweapon $weaponNumbers{$modCounter}{$weapon}";
        } elsif (/^\#secondaryeffect\s+((".*")|[\w\d]+)/) {
            my $weapon = $1;
            unless ($weaponFillIns{$modCounter}{$weapon}) {
                $weaponFillIns{$modCounter}{$weapon} = "llamaweapons${weaponFillInCounter}_";
                $weaponFillInCounter++;
                unless ($weaponNumbers{$modCounter}{$weapon}) {
                    $weaponNumbers{$modCounter}{$weapon} = $weapon;
                }
            }
            $line = "#secondaryeffect $weaponFillIns{$modCounter}{$weapon}";
        } elsif (/^\#secondaryeffectalways\s+((".*")|[\w\d]+)/) {
            my $weapon = $1;
            unless ($weaponFillIns{$modCounter}{$weapon}) {
                $weaponFillIns{$modCounter}{$weapon} = "llamaweapons${weaponFillInCounter}_";
                $weaponFillInCounter++;
                unless ($weaponNumbers{$modCounter}{$weapon}) {
                    $weaponNumbers{$modCounter}{$weapon} = $weapon;
                }
            }
            $line = "#secondaryeffectalways $weaponFillIns{$modCounter}{$weapon}";
        } elsif (/^\#weapon\s+((".*")|[\w\d]+)/) {
            my $weapon = $1;
            unless ($weaponFillIns{$modCounter}{$weapon}) {
                $weaponFillIns{$modCounter}{$weapon} = "llamaweapons${weaponFillInCounter}_";
                $weaponFillInCounter++;
                unless ($weaponNumbers{$modCounter}{$weapon}) {
                    $weaponNumbers{$modCounter}{$weapon} = $weapon;
                }
            }
            $line = "#weapon $weaponFillIns{$modCounter}{$weapon}";
	}

	# Armor.
	# Omitting armor references entirely, because armors can only be set by name. While this could lead to clashes,
	# we just have to hope that two mods don't create new armors of the same name.
	# In fact to check this, we will keep track of created armors.
	if (/^\#name\s+((".*")|[\w\d]+)/ and $currentlyDescribingArmor) {
	    my $armor = $1;
	    if ($createdArmors{$1}) {
		print "Duplicate armor definition: $armor\n";
		print "This will need to be fixed by hand.\n";
	    } else {
		$createdArmors{$1} = 1;
	    }
	}

	# We do still need to remove clashes when creating new armors though.
        if (/^\#newarmor\s+((".*")|[\w\d]+)/) {
	    $currentlyDescribingArmor = 1;
            my $armor = $1;
            unless ($armorNumbers{$modCounter}{$armor}) {
                $armorNumbers{$modCounter}{$armor} = $armorCounter;
                $armorCounter--;
            }
            $line = "#newarmor $armorNumbers{$modCounter}{$armor}";	
	}

        if (/^\#selectarmor\s+((".*")|[\w\d]+)/) {
            $currentlyDescribingArmor = 1;
	}

	if (/^\#end/) {
	    $currentlyDescribingArmor = 0;
	}

	# The following could be uncommented to make things more elegant if armors ever become settable by number.
#	} elsif (/^\#armor ((".*")|[\w\d]+)/) {
#            my $armor = $1;
#            if ($armorNumbers{$modCounter}{$armor}) {
#                $line = "#armor $armorNumbers{$modCounter}{$armor}";
#            }
#	}
	# Units.
	if (/^\#newmonster\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
	    }
#            unless ($unitNumbers{$modCounter}{$unit}) {
	    $unitNumbers{$modCounter}{$unit} = $unitCounter;
	    $unitCounter--;
#            }
            $line = "#newmonster $unitNumbers{$modCounter}{$unit}";
        } elsif (/^\#copystats\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#copystats $unitFillIns{$modCounter}{$unit}";
       } elsif (/^\#copyspr\s+((".*")|[\w\d]+)/) {
	   my $unit = $1;
	   unless ($unitFillIns{$modCounter}{$unit}) {
	       $unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
	       $unitFillInCounter++;
	       unless ($unitNumbers{$modCounter}{$unit}) {
		   $unitNumbers{$modCounter}{$unit} = $unit;
	       }
	   }
	   $line = "#copyspr $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#firstshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#firstshape $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#secondshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#secondshape $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#secondtmpshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#secondtmpshape $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#shapechange\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#shapechange $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#watershape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
	    }
	    $line = "#watershape $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#landshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
	    }
	    $line = "#landshape $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#forestshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
	    }
	    $line = "#forestshape $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#plainshape\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
	    }
	    $line = "#plainshape $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#domsummon\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#domsummon $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#domsummon2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#domsummon2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#domsummon20\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#domsummon20 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#makemonster1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#makemonster1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#makemonster2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#makemonster2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#makemonster3\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
                $unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
            }
            $line = "#makemonster3 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#makemonster4\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
                $unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
                $unitFillInCounter++;
                unless ($unitNumbers{$modCounter}{$unit}) {
                    $unitNumbers{$modCounter}{$unit} = $unit;
                }
            }
            $line = "#makemonster4 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#makemonster5\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#makemonster5 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#summon1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#summon1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#summon5\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#summon5 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#homemon\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#homemon $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#homecom\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#homecom $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startcom\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startcom $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startscout\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startscout $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startunittype1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startunittype1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startunitnbrs1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startunitnbrs1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startunittype2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startunittype2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#startunitnbrs2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#startunitnbrs2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#addrecunit\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#addrecunit $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#addreccom\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#addreccom $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero3\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero3 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero4\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero4 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero5\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero5 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#hero6\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#hero6 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#multihero1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#multihero1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#multihero2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#multihero2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#defcom1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
	    unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defcom1 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#defcom2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defcom2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#defunit1\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defunit1 $unitFillIns{$modCounter}{$unit}";
	} elsif (/^\#defunit2\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defunit2 $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#defunit1b\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defunit1b $unitFillIns{$modCounter}{$unit}";
        } elsif (/^\#defunit2b\s+((".*")|[\w\d]+)/) {
            my $unit = $1;
            unless ($unitFillIns{$modCounter}{$unit}) {
		$unitFillIns{$modCounter}{$unit} = "llamaunits${unitFillInCounter}_";
		$unitFillInCounter++;
		unless ($unitNumbers{$modCounter}{$unit}) {
		    $unitNumbers{$modCounter}{$unit} = $unit;
		}
	    }
	    $line = "#defunit2b $unitFillIns{$modCounter}{$unit}";
	}

        # Sites.
        if (/^\#newsite\s+((".*")|[\w\d]+)/) {
            my $site = $1;
            unless ($siteNumbers{$modCounter}{$site}) {
                $siteNumbers{$modCounter}{$site} = $siteCounter;
                $siteCounter--;
            }
            $line = "#newsite $siteNumbers{$modCounter}{$site}";
        } elsif (/^\#startsite\s+((".*")|[\w\d]+)/) {
            my $site = $1;
            if ($siteNumbers{$modCounter}{$site}) {
                $line = "#startsite $siteNumbers{$modCounter}{$site}";
            }
	}

	# Nations.
        if (/^\#selectnation\s+((".*")|[\w\d]+)/) {
            my $nation = $1;
	    if ($nation > $maxVanillaNationNumber) { # It's a mod nation rather than a vanilla nation.
		unless ($nationNumbers{$modCounter}{$nation}) {
		    $nationNumbers{$modCounter}{$nation} = $nationCounter;
		    $nationCounter++;
		}
		$line = "#selectnation $nationNumbers{$modCounter}{$nation}";
	    }
        }

	if (/^\#restrictedgod\s+((".*")|[\w\d]+)/) {
            my $nation = $1;
            if ($nation > $maxVanillaNationNumber) { # It's a mod nation rather than a vanilla nation.
		unless ($unknownNationNumberFillIns{$modCounter}{$nation}) {
		    $unknownNationNumberFillIns{$modCounter}{$nation} = "llama${fillInCounter}_";
		    $fillInCounter++;
		}
		$line = "#restrictedgod $unknownNationNumberFillIns{$modCounter}{$nation}";
	    }
	}

	if (/^\#restricted\s+((".*")|[\w\d]+)/) {
            my $nation = $1;
            if ($nation > $maxVanillaNationNumber) { # It's a mod nation rather than a vanilla nation.
		unless ($unknownNationNumberFillIns{$modCounter}{$nation}) {
		    $unknownNationNumberFillIns{$modCounter}{$nation} = "llama${fillInCounter}_";
		    $fillInCounter++;
		}
		$line = "#restricted $unknownNationNumberFillIns{$modCounter}{$nation}";
	    }
	}

	# Nametypes.
	if (/^\#selectnametype\s+((".*")|[\w\d]+)/) {
            my $nametype = $1;
	    $nametypeNumbers{$modCounter}{$nametype} = $availableNameTypes[$nametypeCounter];
	    $nametypeCounter++;
	    $line = "#selectnametype $nametypeNumbers{$modCounter}{$nametype}";
	}
	# Replace any nametype references with temporary placeholders which we'll fix in the next pass.
	if (/^\#nametype\s+((".*")|[\w\d]+)/) {
	    my $nametype = $1;
	    unless ($nametypeFillIns{$modCounter}{$nametype}) {
		$nametypeFillIns{$modCounter}{$nametype} = "llamanametype${nametypeFillInCounter}_";
		# If we haven't already encountered this name type as a modded one, assume it's a vanilla one and hence
		# we don't want to change its number. If we come across a #selectnametype entry referring this nametype
		# later, that overwrite this entry, which is what we want. Hmm, that was difficult to make clear!
		unless ($nametypeNumbers{$modCounter}{$nametype}) {
		    $nametypeNumbers{$modCounter}{$nametype} = $nametype;
		}
		$nametypeFillInCounter++;
	    }
	    $line = "#nametype $nametypeFillIns{$modCounter}{$nametype}";
	}

	$out .= "$line\n";
    }
}

# Now we need to go through the almost-ready output and fix the nation number fill-ins.
for my $modCounter (keys %unknownNationNumberFillIns) {
    for my $nation (keys %{$unknownNationNumberFillIns{$modCounter}}) {
	my $toReplace = $unknownNationNumberFillIns{$modCounter}{$nation};
	my $replaceWith = $nationNumbers{$modCounter}{$nation};
	$out =~ s/$toReplace/$replaceWith/g;
    }
}
# And now the nametype fill-ins.
for my $modCounter (keys %nametypeFillIns) {
    for my $nametype (keys %{$nametypeFillIns{$modCounter}}) {
        my $toReplace = $nametypeFillIns{$modCounter}{$nametype};
        my $replaceWith = $nametypeNumbers{$modCounter}{$nametype};
        $out =~ s/$toReplace/$replaceWith/g;
    }
}
# And now the unit fill-ins.
for my $modCounter (keys %unitFillIns) {
    for my $unit (keys %{$unitFillIns{$modCounter}}) {
        my $toReplace = $unitFillIns{$modCounter}{$unit};
        my $replaceWith = $unitNumbers{$modCounter}{$unit};
#	print "to, from: $toReplace, $replaceWith\n";
        $out =~ s/$toReplace/$replaceWith/g;
    }
}
# Weapon fill-ins.
for my $modCounter (keys %weaponFillIns) {
    for my $weapon (keys %{$weaponFillIns{$modCounter}}) {
        my $toReplace = $weaponFillIns{$modCounter}{$weapon};
        my $replaceWith = $weaponNumbers{$modCounter}{$weapon};
        $out =~ s/$toReplace/$replaceWith/g;
    }
}

# And finally spells.
#for my $key1 (keys %spellFillIns) {
#    for my $key2 (keys %{$spellFillIns{$key1}}) {
#	print "$key1 $key2 $spellFillIns{$key1}{$key2}\n";
#    }
#}

for my $modCounter (keys %unknownNationNumberFillIns) {
    for my $spellNo (1..$maxSpellCounter) {
	my $toReplace = $spellFillIns{$modCounter}{$spellNo};
	if ($toReplace) {
	    my $replaceWith;
	    if ($spellIsASummon{$modCounter}{$spellNo}) {
		if ($unitNumbers{$modCounter}{($spellDamage{$modCounter}{$spellNo})}) {
		    $replaceWith = $unitNumbers{$modCounter}{($spellDamage{$modCounter}{$spellNo})};
		} else {
		$replaceWith = $spellDamage{$modCounter}{$spellNo};
		}
	    } else {
		$replaceWith = $spellDamage{$modCounter}{$spellNo};
	    }
#	    print "to, from: $toReplace, $replaceWith\n";
	    $out =~ s/$toReplace/$replaceWith/g;
	}
    }
}

# Also fix the bit at the top of the mod which lists which ID numbers are used, know that we actually know which ones we used.
# The counters are currently off by one (the lowest entry never having been used), so fix that.
$armorCounter++;
$weaponCounter++;
$unitCounter++;
$siteCounter++;
$out =~ s/armorlowerlimit/$armorCounter/;
$out =~ s/weaponlowerlimit/$weaponCounter/;
$out =~ s/unitlowerlimit/$unitCounter/;
$out =~ s/sitelowerlimit/$siteCounter/;
$out =~ s/nationlowerlimit/$nationCounter/;
my $nametypesString;
if ($nametypeCounter > 0) {
    for (0..$nametypeCounter-2) {
	$nametypesString .= $availableNameTypes[$_] . ", ";
    }
    $nametypesString .= $availableNameTypes[$nametypeCounter-1];
} else {
    $nametypesString = "None";
}
$out =~ s/nametypelist/$nametypesString/;

print OUTFILE $out;
close OUTFILE;

print "All done!\n";
