AAAARGH! Particle, it's right there! In your screenshot, no less!
Let's take a look at how this works:
for(%i = 1; %i <= $numZones; %i++)
{
%type = $Zone::Type[%i];
if(%type == "PROTECTED" && String::ICompare(%zonetype, "town") == 0 || %type == "DUNGEON" && String::ICompare(%zonetype, "dungeon") == 0 || %type == "FREEFORALL" && String::ICompare(%zonetype, "freeforall") == 0 || %zonetype == -1)
{
%finalpos = $Zone::Marker[%i];
%dist = Vector::getDistance(%finalpos, %clpos);
if(%dist < %closestDist)
{
%closestDist = %dist;
%closestZoneDesc = $Zone::Desc[%i];
%closestZone = $Zone::FolderID[%i];
%mpos = %finalpos;
}
}
}
if(%mpos == "") //no zones were found (this means there are NO zones in the map...)
return False;
If the %mpos variable is EMPTY, the function returns False, and the teleport failed. Right? Right.
Let's take a look at what conditions have to be satisfied in order for %mpos to not be False.
for(%i = 1; %i <= $numZones; %i++) = This line starts a for() loop which goes through every zone in the server.... then, "for" each zone, the following is done:
%type = $Zone::Type[%i]; We get the zone type (can be DUNGEON, PROTECTED, or FREEFORALL.
if(%type == "PROTECTED" && String::ICompare(%zonetype, "town") == 0 || %type == "DUNGEON" && String::ICompare(%zonetype, "dungeon") == 0 || %type == "FREEFORALL" && String::ICompare(%zonetype, "freeforall") == 0 || %zonetype == -1) Here's the crucial part. The whole idea of this function is to go through every zone, and figure out which one is closest to the player, right? Well, before a zone is added to the list-of-zones-that-are-able-to-be-teleported-to, it has to go through the above 'if' check. If you were to translate the above into readable English, it would be: "IF the type of this zone is 'PROTECTED' AND the zonetype variable is 'town'..... OR IF the type of this zone is 'DUNGEON' AND the zonetype variable is 'dungeon'.... OR IF the type of this zone is 'FREEFORALL' AND the zonetype variable is 'freeforall'... OR if the user didn't specify a zonetype because zonetype is false, THEN...."
Thus, in order to be considered as a zone to teleport to, the zone must first pass the above check. If, for example, the user specified zonetype "dungeon", it would FAIL the part of the check that says "IF the type of this zone is 'PROTECTED' AND the zonetype variable is 'town'...", and thus, the zone would not get considered, and as a result, the teleport spell would not teleport you there.
I'm not an experienced programmer, but I understand basic if-else if-else checks.
And besides, you're completely ignoring the fact that the spell actually works this way in Base TRPG. It's not theory. It's not an abstract concept. It's not conjecture, or hypothesis. It's fact: If you type "#cast teleport town" in keldrin town, you will go to keldrin town, EVERY TIME. If you type "#cast teleport dungeon" in keldrin town, you will go to stronghold yolanda, EVERY TIME. If any active PCRPG player disagrees with this statement, please say so.
*EDIT*
Based on this research, I believe I can even guess what the problem is! Your teleport spell is not properly carrying over the %zonetype that the player provides. The default behavior when the player DOES NOT specify a zone type is to teleport to the nearest zone regardless of its type, which is what seems to be happening. And we've had problems with variables not getting passed before on PCRPG. So.... there you go.