You can actually remove objects from zones if they are ones you spawned dynamically at least. I have done basically the same thing you are wanting to do and it isn't too hard at all thanks to the object code added by Secrets (I think) last year. Here is an example default.pl I use in a zone I was working on for a bit. It does a few extra things in the script that you probably don't need, but the basic idea is there for you to play with:
Note that this is for the revamped version of Steamfont Mountains, so the objects used in this list most likely won't work for any other zone you try it in. You can just replace the list with objects available in the zone you are working on using the global model viewer tool.
Code:
sub EVENT_SPAWN {
# Prevent pets or charmed NPCs from loading the default.pl
if (!$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner())
{
return;
}
my $NPCRace = $npc->GetRace();
# Races of the zone
$InvisibleRace = 127;
$TeleporterRace = 240;
if ($NPCRace == $InvisibleRace || $NPCRace == $TeleporterRace)
{
quest::settimer("SpawnObject", 35);
}
}
sub EVENT_TIMER {
# Prevent pets or charmed NPCs from loading the default.pl
if (!$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner())
{
return;
}
my $NPCName = $npc->GetCleanName();
my $NPCID = $npc->GetID();
if ($timer eq "SpawnObject")
{
quest::stoptimer("SpawnObject");
$npc->SetEntityVariable(1, $NPCID);
# OBJ_AKHUTA_EXT_ACTORDEF
# OBJ_AKHUTA_INT_ACTORDEF
# OBJ_AKHUTB_EXT_ACTORDEF
# OBJ_AKHUTB_INT_ACTORDEF
# OBJ_TENT_KOBOLDA_ACTORDEF
# OBJ_TENT_KOBOLDB_ACTORDEF
# OBJ_FUEL_ORB_WPIPES_ACTORDEF
# OBJ_ROOF_METAL_ACTORDEF
# OBJ_DRAGONBONES_ACTORDEF
my $ObjectID = 0;
my $ObjectID2 = 0;
my $RandomNum = plugin::RandomRange(0, 1);
my $Degrees = plugin::ConvertHeadingToDegrees($h);
if ($NPCName =~ /Gnome House/i)
{
if ($RandomNum)
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_AKHUTA_EXT_ACTORDEF", $x, $y, $z, $Degrees);
$ObjectID2 = quest::creategroundobjectfrommodel("OBJ_AKHUTA_INT_ACTORDEF", $x, $y, $z, $Degrees);
}
else
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_AKHUTB_EXT_ACTORDEF", $x, $y, $z, $Degrees);
$ObjectID2 = quest::creategroundobjectfrommodel("OBJ_AKHUTB_INT_ACTORDEF", $x, $y, $z, $Degrees);
}
}
if ($NPCName =~ /Peasant Tent/i)
{
if ($RandomNum)
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_TENT_KOBOLDA_ACTORDEF", $x, $y, $z, $Degrees);
}
else
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_TENT_KOBOLDB_ACTORDEF", $x, $y, $z, $Degrees);
}
# Spawn a peasant to random roam outside near the tent
#quest::spawn2(42100003, 0, 0, $x, $y, $z, $h);
}
if ($NPCName =~ /Fuel Tank/i)
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_FUEL_ORB_WPIPES_ACTORDEF", $x, $y, $z, $Degrees);
}
if ($NPCName =~ /Dragon Bones/i)
{
$ObjectID = quest::creategroundobjectfrommodel("OBJ_DRAGONBONES_ACTORDEF", $x, $y, $z, $Degrees);
}
if ($ObjectID)
{
my $obj = $entity_list->GetObjectByID($ObjectID);
if ($obj)
{
$obj->SetEntityVariable(1, $NPCID);
}
}
if ($ObjectID2)
{
my $obj = $entity_list->GetObjectByID($ObjectID2);
if ($obj)
{
$obj->SetEntityVariable(1, $NPCID);
}
}
}
}
sub EVENT_DEATH {
# Prevent pets or charmed NPCs from loading the default.pl
if (!$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner())
{
return;
}
my $NPCRace = $npc->GetRace();
my $NPCName = $npc->GetCleanName();
if ($NPCRace == $InvisibleRace || $NPCRace == $TeleporterRace)
{
my $NPCID = 0;
if ($npc->EntityVariableExists(1))
{
$NPCID = $npc->GetEntityVariable(1);
}
my @ObjList = $entity_list->GetObjectList();
foreach $ent (@ObjList)
{
if ($ent->EntityVariableExists(1) && $ent->GetEntityVariable(1) == $NPCID)
{
$ent->Depop();
#plugin::Debug("Object Depopped");
}
}
}
}
The above script should work, but I am not 100% sure if I ever submitted my ConvertHeadingToDegrees plugin, so you may need to add this to one of your plugin files if you don't have it already:
Code:
#Usage: my $Degrees = plugin::ConvertHeadingToDegrees(Heading);
# Converts 0-256 headings into 0 to 360 degrees
sub ConvertHeadingToDegrees {
my $Heading = $_[0];
my $ReverseHeading = 256 - $Heading;
my $ConvertAngle = $ReverseHeading * 1.40625;
if ($ConvertAngle <= 270)
{
$ConvertAngle = $ConvertAngle + 90;
}
else
{
$ConvertAngle = $ConvertAngle - 270;
}
return $ConvertAngle;
}