My Firefox doesn't seem to want to load the EoC zone tools so I decided to write one myself and share with anyone that wanted to use it.
Here is what a cloned zone would look like in George's NPC editor it adds the version to the "new" NPCS.
so any script you may use to open doors by DOORID in certain zones will work across all the versions!
Here is what that looks like...
The script allows you to choose CLONE NPCS OR DOORS... or BOTH!
Cloning NPCS also places them in newly cloned spawngroups and correct spawn2 locations as well.
Here is my VERSION 1 of Gukbottom.. you can see the level 74 Ghoul Executioner and that the doors are correctly in place!
1. Edit the database information inside the script
2. Edit the zone / version you want to copy from and what version to copy TO!
3. MIN NPC -- lowest ID it will copy from I have this at 1000 because I don't like it copying my "CUSTOM" npcs where their NPCID must remain low. Like my NPC that handles Weapon graphics.
4. COPYDOORS / COPYNPCS -- put both to 0 and script does nothing.. turn either to 1 and it copies JUST THAT!
example... Copydoors 1 and COPYNPCS 0 would only copy doors and ignore all NPC DATA. So you could copy a zones doors and just make your own custom NPCS for a new version!
I hope that is enough explanation, but if you have questions or concerns just PM me or reply here and I will help ya when I can
Open command prompt ... and change directory to where the file is located..
Code:
use Getopt::Std;
my $BACKUP = "BACKUP.txt"; #default
open(DUMB, ">>$BACKUP") or die "Unable to find backup file!: $BACKUP\n";
sub DBI_CONNECT {
use DBI;
$database = "peq_new";
$host = "localhost";
$username = "USER";
$password = "PASS";
$dbh = DBI->connect("DBI:mysql:database=$database;host=$host", "$username", "$password", {RaiseError => 1});
return $dbh;
}
#DEFINE
$zone = "gukbottom"; #Zone to copy from
$version = 0; #Version to copy from
$versionset = 2; #Version to copy to
$minNPC = 1000; #Min NPC ID to copy from zone
$COPYDOORS = 1; #Set to 1 to copy doors from the copy version
$COPYNPCS = 1; #COPY ZONE set to 1.. turn to 0 if you only want the doors!
#END DEFINE
$space = "_";
my $TIME = localtime;
my $line = "##ZONE = $zone - VERSION = $versionset -- $TIME \n";
print DUMB $line; #write to the file
$dbh = DBI_CONNECT();
if($COPYNPCS == 1)
{
$query = "SELECT distinct se.spawngroupID, se.npcID, se.chance FROM spawnentry se
INNER JOIN spawn2 s ON se.spawngroupID = s.spawngroupID
INNER JOIN npc_types n ON se.npcID = n.id
INNER JOIN spawngroup sg ON sg.id = se.spawngroupID
WHERE s.zone = '$zone' and s.version = $version and se.npcID >= $minNPC ORDER by se.spawngroupID ASC" ;
$sth = $dbh->prepare($query);
$sth->execute();
$n = 0;
while (@row = $sth->fetchrow_array())
{
$n++;
$SpawnEntries[$n] = [@row];
#print "@row \n";
#print "$n -- $SpawnEntries[$n][0] -- $SpawnEntries[$n][1] -- $SpawnEntries[$n][2] \n";
#$lastone = $row[0];
}
print "$n \n";
#return;
$query = "SELECT distinct n.id FROM spawnentry se
INNER JOIN spawn2 s ON se.spawngroupID = s.spawngroupID
INNER JOIN npc_types n ON se.npcID = n.id
INNER JOIN spawngroup sg ON sg.id = se.spawngroupID
WHERE s.zone = '$zone' and s.version = $version and n.id >= $minNPC ORDER by n.id ASC";
$sth = $dbh->prepare($query);
$sth->execute();
while ($id = $sth->fetchrow_array())
{
push(@oldnpcs, $id);
}
# print "\n $oldnpcs[5] \n";
foreach $old_npc (@oldnpcs)
{
$query = "SELECT max(id) FROM npc_types";
$sth = $dbh->prepare($query);
$sth->execute();
$maxid = $sth->fetchrow_array()+1;
push(@newnpcs, $maxid);
#INSERT NEW NPC
$dbh->do("INSERT INTO `npc_types`
(`id`,`name`,`lastname`,`level`,`race`,`class`,`bodytype`,`hp`,`mana`,`gender`,`texture`,`helmtexture`,`size`,`hp_regen_rate`,`mana_regen_rate`,`loottable_id`,`merchant_id`,`alt_currency_id`,
`npc_spells_id`,`npc_faction_id`,`adventure_template_id`,`trap_template`,`mindmg`,`maxdmg`,`attack_count`,`special_abilities`,`aggroradius`,`face`,`luclin_hairstyle`,`luclin_haircolor`,`luclin_eyecolor`,`luclin_eyecolor2`,
`luclin_beardcolor`,`luclin_beard`,`drakkin_heritage`,`drakkin_tattoo`,`drakkin_details`,`armortint_id`,`armortint_red`,`armortint_green`,`armortint_blue`,`d_meele_texture1`,`d_meele_texture2`,`prim_melee_type`,`sec_melee_type`,
`runspeed`,`MR`,`CR`,`DR`,`FR`,`PR`,`Corrup`,`see_invis`,`see_invis_undead`,`qglobal`,`AC`,`npc_aggro`,`spawn_limit`,`attack_speed`,`findable`,`STR`,`STA`,`DEX`,`AGI`,`_INT`,`WIS`,`CHA`,`see_hide`,`see_improved_hide`,
`trackable`,`isbot`,`exclude`,`ATK`,`Accuracy`,`slow_mitigation`,`version`,`maxlevel`,`scalerate`,`private_corpse`,`unique_spawn_by_name`,`underwater`,`isquest`,`emoteid`,`spellscale`,`healscale`)
SELECT distinct $maxid, n.`name`, n.`lastname`, n.`level`, n.`race`, n.`class`, n.`bodytype`, n.`hp`, n.`mana`, n.`gender`, n.`texture`, n.`helmtexture`, n.`size`, n.`hp_regen_rate`, n.`mana_regen_rate`,
n.`loottable_id`, n.`merchant_id`, n.`alt_currency_id`, n.`npc_spells_id`, n.`npc_faction_id`, n.`adventure_template_id`, n.`trap_template`, n.`mindmg`, n.`maxdmg`, n.`attack_count`, n.`special_abilities`, n.`aggroradius`, n.`face`,
n.`luclin_hairstyle`, n.`luclin_haircolor`, n.`luclin_eyecolor`, n.`luclin_eyecolor2`, n.`luclin_beardcolor`, n.`luclin_beard`, n.`drakkin_heritage`, n.`drakkin_tattoo`, n.`drakkin_details`, n.`armortint_id`, n.`armortint_red`, n.`armortint_green`,
n.`armortint_blue`, n.`d_meele_texture1`, n.`d_meele_texture2`, n.`prim_melee_type`, n.`sec_melee_type`, n.`runspeed`, n.`MR`, n.`CR`, n.`DR`, n.`FR`, n.`PR`, n.`Corrup`, n.`see_invis`, n.`see_invis_undead`, n.`qglobal`, n.`AC`,
n.`npc_aggro`, n.`spawn_limit`, n.`attack_speed`, n.`findable`, n.`STR`, n.`STA`, n.`DEX`, n.`AGI`, n.`_INT`, n.`WIS`, n.`CHA`, n.`see_hide`, n.`see_improved_hide`, n.`trackable`, n.`isbot`, n.`exclude`, n.`ATK`, n.`Accuracy`,
n.`slow_mitigation`, $versionset, n.`maxlevel`, n.`scalerate`, n.`private_corpse`, n.`unique_spawn_by_name`, n.`underwater`, n.`isquest`, n.`emoteid`, n.`spellscale`, n.`healscale`
FROM npc_types n WHERE n.id = $old_npc");
my $line = "DELETE FROM `npc_types` WHERE `id` = $maxid;\n";
print DUMB $line; #write to the file
}
$sth = $dbh->prepare("SELECT count(distinct s.spawngroupid) from spawn2 s
INNER JOIN spawnentry se ON se.spawngroupID = s.spawngroupID
WHERE s.version = $version and s.zone = '$zone' and se.npcID >= $minNPC");
$sth->execute();
$spawncount = $sth->fetchrow_array();
#print "$spawncount \n";
$sth = $dbh->prepare("SELECT distinct sg.* FROM spawnentry se
INNER JOIN spawn2 s ON se.spawngroupID = s.spawngroupID
INNER JOIN npc_types n ON se.npcID = n.id
INNER JOIN spawngroup sg ON sg.id = se.spawngroupID
WHERE s.zone = '$zone' and s.version = $version and se.npcID >= $minNPC ORDER by sg.ID ASC
");
$sth->execute();
$B = 0;
while (@SG = $sth->fetchrow_array())
{
$B++;
$SpawnGroups[$B] = [@SG];
#print "@SG \n";
}
for $M (1 .. $spawncount)
{
$sth = $dbh->prepare("SELECT MAX(id) FROM spawngroup");
$sth->execute();
$SGID = $sth->fetchrow_array() + 1;
$dbh->do("INSERT INTO `spawngroup`
(`id`, `name`, `spawn_limit`, `dist`, `max_x`, `min_x`, `max_y`, `min_y`, `delay`, `despawn`, `despawn_timer`)
VALUES ($SGID, '$zone$space$SGID', $SpawnGroups[$M][2], $SpawnGroups[$M][3], $SpawnGroups[$M][4], $SpawnGroups[$M][5], $SpawnGroups[$M][6], $SpawnGroups[$M][7], $SpawnGroups[$M][8], $SpawnGroups[$M][9], $SpawnGroups[$M][10])");
my $line = "DELETE FROM `spawngroup` WHERE `id` = $SGID;\n";
print DUMB $line; #write to the file
push(@SPAWNGROUPS, $SGID);
#print "$M";
}
$F = 0;
for $SE (1 .. $n)
{
if($LastSpawnG == $SpawnEntries[$SE][0])
{
$F--;
}
$SG = $SPAWNGROUPS[$F];
$SPOTS = FINDSPOT($SpawnEntries[$SE][1]);
$npcID = $newnpcs[$SPOTS];
$chance = $SpawnEntries[$SE][2];
#print "$SE -- $SG ... $npcID ... $chance \n";
$dbh->do("INSERT INTO `spawnentry`
(`spawngroupID`, `npcID`, `chance`)
VALUES ($SG, $npcID, $chance)");
my $line = "DELETE FROM `spawnentry` WHERE `spawngroupID` = $SG and `npcID` = $npcID;\n";
print DUMB $line; #write to the file
$LastSpawnG = $SpawnEntries[$SE][0];
$F++;
#print "$SG $npcID $chance \n";
}
$sth = $dbh->prepare("SELECT distinct s.spawngroupid, s.x, s.y, s.z, s.heading, s.respawntime, s.variance, s.pathgrid, s._condition, s.cond_value, s.enabled, s.animation FROM spawn2 s
INNER JOIN spawnentry se ON se.spawngroupID = s.spawngroupID
WHERE zone = '$zone' AND version = $version and se.npcID >= $minNPC ORDER by s.spawngroupid ASC");
$sth->execute();
$g = 0;
while ( ($spawnGID, $x, $y, $z, $heading, $respawntime, $variance, $pathgrid, $condition, $convalue, $enabled, $animation) = $sth->fetchrow_array())
{
if($spawnGID eq $spawnlast)
{
$g--;
}
#print "$g -- $SPAWNGROUPS[$g] -- $x, $y, $z \n";
$dbh->do("INSERT INTO `spawn2`
(`id`, `spawngroupID`, `zone`, `version`, `x`, `y`, `z`, `heading`, `respawntime`, `variance`, `pathgrid`, `_condition`, `cond_value`, `enabled`, `animation`)
VALUES ('', $SPAWNGROUPS[$g], '$zone', $versionset, $x, $y, $z, $heading, $respawntime, $variance, $pathgrid, $condition, $convalue, $enabled, $animation)");
$spawnlast = $spawnGID;
$g++;
$sth
}
my $line = "DELETE FROM `spawn2` WHERE `version` = $versionset and `zone` = '$zone';\n";
print DUMB $line; #write to the file
$sth->finish;
}
if($COPYDOORS == 1)
{
$dbh->do("INSERT INTO `doors`
(`id`, `doorid`, `zone`, `version`, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`)
SELECT '', `doorid`, `zone`, $versionset, `name`, `pos_y`, `pos_x`, `pos_z`, `heading`, `opentype`, `guild`, `lockpick`, `keyitem`, `nokeyring`, `triggerdoor`, `triggertype`, `doorisopen`, `door_param`, `dest_zone`, `dest_instance`, `dest_x`, `dest_y`, `dest_z`, `dest_heading`, `invert_state`, `incline`, `size`, `buffer`, `client_version_mask`, `is_ldon_door`
FROM `doors` WHERE zone = '$zone' and version = $version");
my $line = "\n ### ADDED DOORS !! \n\n";
print DUMB $line; #write to the file
my $line = "DELETE FROM doors WHERE zone = '$zone' and version = $versionset;\n\n";
print DUMB $line; #write to the file
}
my $line = "\n ### END OF -- ZONE = $zone - VERSION = $versionset -- $TIME\n\n";
print DUMB $line; #write to the file
print "FINISHED! Copying $zone to Version $versionset!";
close (DUMB); #since we're done with it...
sub FINDSPOT
{
for $i (0 .. $#oldnpcs)
{
#print "$oldnpcs[$i] \n";
if($oldnpcs[$i] == $_[0])
{
return $i;
}
}
}
$dbh->disconnect;