Fraz

Member
Fraz submitted a new resource:

Fraz Teleport System 1.0 - Itemless teleport system for dungeons, caves ect..

-Fraz Teleport System- created by Geos Frazurbluu April 17th, 2015
Please email me any comments or bug issues you find at '[email protected]'


A quick guide how to use this system..


Look for the file in this folder 'teleporters.cfg' at this path, 'DATA/TELEPORTERS/teleporters.cfg'.


Open 'teleporters.cfg' with notepad (or similar program)..

Inside you will see a list of file path locations that is included in this release, these are standard UO map locations...

Read more about this resource...
 
One of the most useful Resources for custom maps released in a good while. Nicely done.

I'll be using this for sure.
 
It's on my list to see about integrating it into the main distro. We've been needing a configuration-based teleporter system for a long time now.
 
I love this.

I do have a question/concern/suggestion. I notice that to make this work, Mobile is changed so that every time someone moves, it checks every Teleport object in the world to see if the X,Y,Z coordinates match the player's new location. My guess is that this could cause significant lag once the number of Teleport objects and the number of players moving start to get large.

Here is the code causing my concern:

Code:
                            #region Fraz Teleport System
                            foreach (Teleport teleport in Teleporters.m_Teleporters)
                            {
                                if (((teleport.PointLoc.m_X == x) && (teleport.PointLoc.m_Y == y)) && ((teleport.PointLoc.m_Z == newZ) && !teleport.OnMoveOver(this)))
                                {
                                    return false;
                                }
                                if (((teleport.PointDest.m_X == x) && (teleport.PointDest.m_Y == y)) && ((teleport.PointDest.m_Z == newZ) && !teleport.OnMoveOverReturn(this)))
                                {
                                    return false;
                                }
                            }
                            #endregion

Some possible solutions:

1. If this is not as bad as I am thinking, perhaps at least exit the loop once the Teleport is found - no need to keep looping.

2. If it is a problem, would it be possible to have a static Dictionary stored in Teleport? The constructor for Teleport gets passed a Point3D object. Perhaps that Point3D object can be the Key for the Dictionary? If so, then all we would need in Mobile is one line:

Code:
 if (Teleport.LocationDictionary.ContainsKey(m.Location)) ... etc. etc. ...
 
This was a major concern for me as well. If we integrate this into the main distro we'd have to use a location hash. Don't get us wrong Fraz, we all really love the idea and the work. As a minimum viable product this is a slam-dunk! We're just providing some critical input for scaling.

Here's an old-school approach I've used when developing similar systems in C:
Code:
// The thing that holds the hash of teleport locations
Dictionary<UInt64, Teleport> m_Teleporters = new Dictionary<UInt64, Teleport>();

// While loading teleport definitions, build the hash
m_Teleporters.Add(t.X | t.Y >> 16 | t.Z >> 32 | t.Map >> 48, t);

// To check on mobile move
Teleport tel;
if(m_Teleporters.TryGetValue(m.X | m.Y >> 16 | m.Z >> 32 | m.Map.Id >> 48, ref tel)
{
  // Mobile has moved onto a teleporter
}

For this approach we use a packed 64-bit unsigned integer to create a unique hash of the location of each teleporter. We then use the dictionary to associate hash values to objects. I'm actually not sure how this compares performance-wise to using a Dictionary<Point3D, Teleporter>.
 
I agree on the improvements entirely!
I love Dictionary using a hash table approach, closer to how I envisioned the finished product for sure.

Breaking the loop is a great idea as well. I should have realized that one at least.. o_O
EDIT: Wait, it does return doesn't it? I'll have to look. Am I somehow missing something?

As far as the locations causing lag in that area though, I actually think it may be in better shape that the code stands now..,
immediately following my entry is the item loop, so for every teleporter added, there would be one less item looped (or make that 2) .. right?? (That should be an improvement on current system)

This was my first attempt at making code in C# verse C++, and I never received any input prior to this regarding it, oh and my first look at the RunUo/ServUO code family.

Also I felt a little rushed even to release this code, normally I probably would have redesigned much of it a few times at least before that.
I'm used to working in a closed atmosphere..

Well enough of my pitiful explanations..
Thanks for the input!
 
Last edited:
I'm not quite sure why this would be added to the Distro- unless it would be added to use true/false? I thought ServUO was being kept as OSI accurate , just my thought :)
 
All the current entries included with the Resource are OSI accurate dungeons, caves teleporters, ect..
With this system in place you can enter an empty world with your first admin and walk to any location teleport entry without adding any items to the world whatsoever.
I always find the less items in the world save file, especially early in a shards life is best case scenario.
Or I'm not sure I understood your concern. :confused: Hehe.

EDIT: Did I really just say 'OSI' lol..
EDIT2: Oh you did too.. its not just me! :D
 
Last edited:
I did find one bug not sure if it was the location i set up but go to britain sewers and teleport down and try to teleport back up. for some reason it does not read the height correctly.

plus you might have to adjust some of those locations. if same one i sent you fraz i know after more testing i found i overlapped some of them. i wish i did more testing but that is just some.

hope that helps you guys :)
 
No , none of this was sent to me by you.EDIT: (Sorry, Directly I mean!) I compiled it from work that was submitted to the project, alot of it made by you, but not as the script releases you made.
Also just checked Sewer and was able to go both directions.. albeit the second ladder..
Quite possible there could be missing and erroneous locations as I haven't personally checked every file and entry that was contributed to the project. Thanks for reminding me of that as well, as I should have made mention of it in the notes.

If anyone has an exact location fix please do post it here, to be included in future versions.

You may want to update or check against these entries for fixes you may not have.
You may also wish to check the mobiles.cs in the download here verse the one you made from Shard Engine, as the original code looks different than the patch you made in GOW.
 
Last edited:
The primary reason I would like to integrate this into the distro would be to move to a configuration based teleport system. Right now they are hard coded. This makes modification more difficult and maintenance of custom content a nightmare.
 
I did do some experimenting with the suggestions..
I don't think using Point3D is a viable alternative as a key due to overlapping x,y,z on different maps.
So I went with the other suggestion.. opened up a can of worms there, I'll do some more testing and give a progress report.
I don't wish to give up on the idea, but.. I suspect that all the data locations may require being redone with this method, unless some fancy coding can solve some of the issues I'm running into with this..

It's only a few lines of code to add, so I won't bother posting the new code yet..
Has anyone else attempted to update this with the suggestions and had problems?
 
I did do some experimenting with the suggestions..
I don't think using Point3D is a viable alternative as a key due to overlapping x,y,z on different maps.
So I went with the other suggestion.. opened up a can of worms there, I'll do some more testing and give a progress report.
I don't wish to give up on the idea, but.. I suspect that all the data locations may require being redone with this method, unless some fancy coding can solve some of the issues I'm running into with this..

It's only a few lines of code to add, so I won't bother posting the new code yet..
Has anyone else attempted to update this with the suggestions and had problems?

You don't have to use Point3D as a key, since you can also search for Values in the same way. You just need to store the values so that it knows if one exists at that location or not. Once you have decided that one does in fact exist, then you can loop through until it finds the exact one.
 
I'm not sure why I didn't mention this before, but you also don't need a core mod to do this. You can hook EventSink.Movement . This is how we implement the overweight system so it's already proven to be scaleable. Also if you are needing data for the teleporters, look at adding a line to the GenTeleporters command to write out it's data when ran. You could execute this on a local copy to extract the data.

I wish you luck with this. We have a fairly immediate need for a new teleport system. It would be great if we could adopt this one without having to re-implement it.
 
In the testing I did I basically coded it as suggested.. here's how it came out..

I added to the class..
Code:
public static Dictionary<Int64, Teleport> m_TeleportersD = new Dictionary<Int64, Teleport>();

I added to the load method..
Code:
m_TeleportersD.Add(x | y >> 16 | z >>32  | mapLoc.MapID >> 48, teleport);

I made two attempts at movement key location..

Code:
  Teleport tel;
  if (Teleporters.m_TeleportersD.TryGetValue(Location.X | Location.Y >> 16 | Location.Z >> 32 | Map.MapID >> 48, out tel))
  {
  if (!tel.OnMoveOver(this))
  return false;
  }

and..

Code:
  if (Teleporters.m_TeleportersD.ContainsKey(Location.X | Location.Y >> 16 | Location.Z >> 32 | Map.MapID >> 48))
  {
  Teleport TeleSpot = Teleporters.m_TeleportersD[Location.X | Location.Y >> 16 | Location.Z >> 32 | Map.MapID >> 48];
  if (!TeleSpot.OnMoveOver(this))
  return false;
  }

I even went so far as to make a new testing location, broke up the entries so it can read each location and have that location as a key..(as the data is entered now, it wouldn't work correctly even if you added another m_TeleportersD.Add in the load method, it would be confused where to 'send' on that key done that way.)

With both methods I am being teleported at locations that I have double checked and there is no entry with that key..

When arriving at a correct key location..
Testing revealed that the 'send' locations would need an offset from it's send location and arrival point,or the check would have to be done in a different location (I hadn't got that far on that yet) as you arrive in an endless loop of being teleported every time you attempt to move after using one.

As for now, as a 'custom' feature, I think I've arrived at the point it's sufficient 'as is'.. :eek:

I am very interest at looking at it from your new comment Norman, 'EventSink.Movement'.
My curiosity will I'm sure get the better of me and I'll start experimenting with it.
Thanks as well for the suggestion with the GenTeleports command I'll look at that as well.
 
I would do this:

Add this to Teleporters:

public static Dictionary<Int, Point3D> m_TeleportersD = new Dictionary<Int, Point3D>();

Then, in the Teleport constructor add these:

teleportID = Teleporters.m_TeleportersD.Length;
Teleporters.m_TeleportersD.Add(teleportID, pointLoc);

Then when you move, check like this:

if (Teleporters.m_TeleportersD.TryGetValue(Location))

Then if that results TRUE, go ahead and loop through the Teleports like you did before, breaking out of the loop when you find the right one.

Oh, and setting up an EventSink for this should be very easy.
 
That is an excellent suggestion! You mentioned it earlier, but I read it without grasping what you were saying.
I will make the adjustments now and report back soon. :)
 
I would have to switch that around for the Point3D to be the location key correct?
public static Dictionary<Point3D, Int> m_TeleportersD = new Dictionary<Point3D, Int>();

To maintain the current data file the send location is contained all in the same data line,
So I would assume for the send back location a Point3D location would be needed as well for the condition to ever be true...

so I added,

teleportID = Teleporters.m_TeleportersD.Count;
Teleporters.m_TeleportersD.Add(pointLoc, teleportID);
teleportID = Teleporters.m_TeleportersD.Count;
Teleporters.m_TeleportersD.Add(pointDest, teleportID);

Shouldn't the Count be taken care of internally, after an Add is done? It doesn't seem to be working.
 
Update.., it depends where I am at if it is working back and forth and it is very stubborn and takes much effort and moving around to teleport..

I'm not just quite giving up yet.. but this is being fairly stubborn.. lol

The result is quite puzzling.., I wouldn't suspect it.

Note: The original system is smooth as imaginable, you don't even miss a step..
 
Last edited:
That is awesome I'm glad to see it improve over other system. nice job fraz just a idea or something

is there any way you can tie in the quest system where has to check a quest item or maybe the quest you are on. I know that is asking for a lot but figure I ask.
 
Oh no.. its just falling through 90% of the time with this system..
Everything should be in place but the key check here..

if (Teleporters.m_TeleportersD1.TryGetValue(Location.X | Location.Y >> 16 | Location.Z >> 32 | Map.MapID >> 48, out tel))

just falls through like a Definition is almost every step on the map.. (which is really worse than before)

Ya that could be done for quests.

I'm going to have to give up on this upgrade idea.. unless someone comes up with a solution.
I've tried all the suggestions every way to Sunday.. no luck.
 
Thanks Norman, I'll try that now.., sounds reasonable as to why it would just fall through..
I'll report back my findings.
 
Have you noticed that you're only doing this check within the bit of code that handles transition between sectors? Try moving the whole system out of the core and into a stand-alone script that hooks EvenSink.Movement . The event system is there to help moders respond to events without having to dig into the guts of a complex system.
 
The check is being done in the mobile CheckMovement, its actually the part of code that handles no transition of a sector, the code above it accomplishes the differences for sector transitions. I actually now think there was a check in that section as well, I don't remember if I removed it.., or forgot to add it when putting it into ServUO. Hmm something I will look into for sure.

It is also where any item that causes a teleport is checked on movement as well.. it doesn't seem to complicated.

Personally, on one side I feel the code is sufficient 'as is', there would be a slight decrease in item loops to offset the location loops, which I think I'd find acceptable if running it on my shard.

On the other end is my obsession with performance and wanting it to be as efficient as possible.

At this time, I'm not sure how moving it would fix the fall through that I am receiving in the last test.
Which had also caused random teleporting at rare times when added without the coded system I already made.
I understand the logic of what we are attempting to do, however cannot explain the result.. (without devoting a lot more brain resources to the task)
I've supplied all the testing code I used per all the suggestions made..
Perhaps you can explain it? (EDIT: No need added Point4D)
I've already devoted a substantial amount of time with no results, and I'm also not sure if moving it will improve it in any way as well.
 
Last edited:
OK.. to clinch it for me, I went and made Point4D, so it could include the map in the dictionary easily
There are a few outcomes..

Using Normans suggestion
Result: Fall through and when used, endless teleport loop.

Using Lokai's second suggestion, Point3D and my Teleport List check
Result: Sticky teleport spots that barely work.

Point4D without my Teleport List Check
Result: No fall through, endless teleport loop

Point4D with my Teleport List Check
Result: Sticky teleport spots that barely work.

Seeing no reason to really move it from my end..
not wanting to redo the data with offsets (which isn't good anyways)
and the test results...

This Resource will stand 'as is'.
Result: Works perfectly.

Of course anyone else is always free to try and improve upon it.
I tried.

P.S.
I will be making future updates with any fixes, location data corrections, quest features, and a possible menu driven edit feature.
 
Last edited:
I took the liberty of modifying the code to show you what I was trying to say. Pardon if this does not compile or work, it was done without the benefit of the rest of the Server code. You will see my 5 small code changes with comments. The 5th is just for testing, as commented. If you can, try this out and see if it works like I expect it will.
 

Attachments

  • Teleporters.cs
    19.1 KB · Views: 3
Yes, that method wasn't in the move, but was tested.
I will try this just to be certain, but am quite certain of the result. (Sticky teleports that barely work.)

I will try again though in case there is something I missed and post the result.

Side Note: The data cannot be parsed correctly in this example. Will need modified slightly.
m_Locations.Add(pointLoc); // LOKAI MOD #3
m_Locations.Add(pointDest);// This too
 
Last edited:
Confused.....

All I did was add another check. I did not subtract anything. If anything, my code would make it MORE restrictive, not LESS. Is the code you posted above the "working" code? Because basically my code was the same as the code you pasted in Post #33, but with a check first to see if the player's location was in the static List<>.
 
No!, the code above was the example of me saying this will not work moved out of the core.. even if you only use my original working method!

Your example put into the working code gives sticky tele's as I am calling them, works too well..
Your example in this code results in teleport loop.

Even only using my original code and moving it to its own script section (using EventSink) as per suggested breaks it!

Let me explain.. since you have no way of seeing this in effect for yourself.
If you use EventSink.Movement, there is no method I am aware of to pause it (per mobile), so to speak...
I can think of a lot of ways to achieve this, but hardly worth investigating.. (to me!! maybe not someone else)

When you step onto a tele location, you are whisked away to the destination..
The destination coords then get passed to the EventSink, and you are whisked back to the original spot..
Where of course you arrive at a location again that has a teleport spot.. ect.. (teleport loop)
This is the same result as just putting teleport points as keys in the core method..

This is what I spoke of earlier as needing offsets.. (which again I feel is a bad solution)

I hope that helps.

EDIT:
In your suggestion while in core..
As of now I am at a loss to explain why a conditional passed as true, doesn't continue to execute my code below it consistently.. you need to run back and forth over the spot hoping to teleport.. (where is Spock when you need him, because that almost defies logic..) (although I'm sure theres a good explanation)
 
Last edited:
Also, was happy to discuss, create and test all the code that was suggested.
I put a lot of time and effort to do this.

I've been certain, since way back, it doesn't work.., at least without a certain amount of tweaking that isn't top on my priority list right now.

What I was suggesting recently was that if someone likes the idea but is adamant that it needs to be out of the core to be included in ServUO, to have at it.. whether it makes it to the repo or not isn't my concern.
I've reached my end of chasing hunches with this for now, just to convince everyone the suggestions don't work. :D

The original code reached my expectation and needs since I first posted it.
However, I love the thought behind the suggestions!
There's been a lot of those, and no one seems to care enough to even check the work I did, just add more speculation..
I am fully aware that is beyond your personal ability at the moment to check..so no worries!

With the results posted now, hopefully to your full understanding, perhaps you may solve the main issues.
For your future approach, it will have to be either with the core version, or the script EventSink version,
as either will produce their own issues, not related to the other.

I will gladly continue with new suggestions that address the real issues with what was suggested.
 
Last edited:
Hi Norman, someone told me you added data teleports..
Would have been nice if you had ever replied to my posts here when asked..
So I'm guessing you used EventSink?
How bout since I went through all that trouble for your suggestions, you have the simple decency to let us know what you did to solve the issue I informed you about when I tried 'your' suggestion, exactly as you suggested it. Since.., I gather you resolved it.

I suppose I could grab the code and look.. but that takes a bit of effort and time.. a lot easier if you just tell us.
 
Hi Norman, someone told me you added data teleports..
Would have been nice if you had ever replied to my posts here when asked..
So I'm guessing you used EventSink?
How bout since I went through all that trouble for your suggestions, you have the simple decency to let us know what you did to solve the issue I informed you about when I tried 'your' suggestion, exactly as you suggested it. Since.., I gather you resolved it.

I suppose I could grab the code and look.. but that takes a bit of effort and time.. a lot easier if you just tell us.

I am not aware of a Data Teleport system from Norman. Are you sure about your "someone" that told you?

*EDIT*

There is a data-driven system for generating the teleporters, but they are still the same old teleporter items that are getting created, not imaginary objects that get triggered by a movement hook.
 
Last edited:
Thank you Lokai.. go figure... my bad.. my apologies to Norman as well.

I should have looked before inserting foot in mouth.. but since they're buds I took the message as probable fact.
 
The decision to go with a data-driven teleporter generation system was to help ease the development of several teleporter-related defects and enhancements. An item-less teleportation system is not off the table, it was simply not required to achieve the goal.
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back