In this thread I will talk about a few things that may be helpful to new users of POL and eScript. They may also benefit long time users as well if you have never read the documentation for POL's built-in modules. It's easy to fall into the trap of assuming a function does only what you think it does because of its name.
Specifically in this first post I will address the uo.em function TargetCoordinates(). When you look at the name you can infer, correctly I might add, that it returns the coordinates that the user targetted. Since TargetCoordinates() contains the word "Coordinates" you can infer this from the more frequently used function Target() which returns the object reference to the object targetted.
But first I need to define some terms:
Items - These are anything that appears in the game world that is not a NPC, player character (PC), a Multi, or a terrain tile.
Static, Static items, and Statically placed items - These are any item that has an ObjType number in the art tile range that comes preset in the map prior to decorating by a staff member. They cannot be moved or destroyed in-game.
Dynamic, Dynamic items, and Dynamically placed items - These are any items placed in the game world by scripts, staff members using in-game commands or by players using crafting skills or some other scripted means of creating items.
In this post by "in the game world" I mean in the readily visible game either on the ground, in a house or in a shoppe. Anything inside a storage container is a dynamic item but for the purpose of this post is not relevant.
Some time ago, Mon Jun 26, 2006 to be exact, OldnGrey asked to have the realm member added to the returned struct when calling the function TargetCoordinates().
You can read the thread if you want to. I bring-up this old topic to make a point, judging a function by only its name can limit what you can do. If you took TargetCoordinates() at face value you might, being new to POL, assume it just returns the x, y, and z coordinates of the player. However it returns a lot of useful informatation, other than just x, y, z, and, (now) realm.
From core-changes.txt:
Code: Select all
06-27-06 MuadDib
Added : Realm property to return struct of TargetCoordinates() function. This
is based off the targeter's realm. Never trust information returned
by the client for stuff like this.
You will note the feature was added the day after the request was made. Those were the days of fairly rapid POL development. Would that was still the case...
In fact place := TargetCoordinates(player) returns the following information in a struct, or "structured data type":
place.x - The x coordinate.
place.y - The y coordinate.
place.z - The z coordinate.
place.realm - The realm player was in when she single-clicked after receiving the target.
place.objtype - The ObjType of the static object, if present, at the location which player targetted.
place.item - An item reference to the dynamic, or placed item, if present, at the location targetted.
place.mobile - A character reference to a mobile, if present, at the targetted location.
place.multi - A Multi reference if the coordinates are inside of a multi.
That is a wealth of useful information. Some of which I will use to show you a neat trick you can do in scripts.
I do not know when the objtype member, item reference, or mobile reference were added but from core-changes we can see when Turley added the multi reference:
Code: Select all
05-02-2009 Turley:
Added: new TargetCoordinates return member "multi" with multiref if coords are inside a multi
I ask you this: Have you ever wanted to make a static item "usable"?
Well, with TargetCoordinates() you can, in a round-about way.
In the current Distro mining package you smelt ore by double-clicking, or "using", it and targetting a forge. It uses the Target() function in the smelting script. So you must have a dynamic or "placed" forge to target but what if you wanted to make it possible for players to be able to use a dynamically placed forge or to take advantage of statically placed forges that are already in the world? if you use TargetCoordinates() you can! This also can reduce decoration time for a shard. If there are static forges already present then that means less forges to be placed. Plus if you are concerned about the item count that's another thing, less forge items in your items.txt file.
This is how I implemented this in the upcoming "new Distro":
Code: Select all
...
var forge := TargetCoordinates(who);
var dist := CoordinateDistance(who.x, who.y, forge.x, forge.y);
// If there is a dynamic item at the location TargetCoordinates() returns the item reference
// and we make the variable "forge" equal to that.
// I have to admit eScript's weak variable typing simplifies this and I took advantage of this :P
if(forge.item)
forge := forge.item;
endif
// If there was no item reference then we are still OK because if there was a static item at the location
// TargetCoordinates() gives the ObjType number of that static item.
// So we check to see if the ObjType of either the dynamic item or static item matches the ObjTypes of known forges.
if((forge.objtype == 0xfb1) || forge.objtype := 0x2DD8|| ((forge.objtype >= CInt(0x197a)) && (forge.objtype <= CInt(0x19a9))))
// We have to check Line Of Sight (LOS) to the targetted location because TargetCoordinates() has no
// flags for LOS check as does Target().
if(!CheckLosBetween( who.x, who.y, who.z, forge.x, forge.y, forge.z, who.realm ))
SendSysMessageCL(who,500876, {}, 3, 33); // You can't see that.
return;
endif
// If the distance between the player and the forge is greater than 2 squares
// send the cliloc message "That is too far away." in font 3 colour red.
// The empty array in SendSysMessageCL is necessary because some cliloc
// messages can have text inserted in them. See the cliloc.em documentation
// for more information.
if(dist > 2)
SendSysMessageCL(who, 501975, {}, 3, 33); // That is too far away.
return;
endif
...
I hope this is helpful to you in programming in eScript. To be honest I was not aware of all of the info returned by TargetCoordinates() until I looked at the docs about a year ago to see if it had LOS check flags. It was then that I discovered just how useful it was and this is just a small example of its usefulness. It pays to read the Documentation.
On a side note about the POL Docs: When I started down the POL road in 2002 we only had a few text documents and the *.em files for documentation and even then no one told me that the *.em files were simple text files I could view for more information. We had the Distro with its eScript programs to learn from but that along with the few text files was it. Around about the time POL 095 was released Racalac showed me a beta version of his POL Documentation page and honestly it brought tears to my eyes. It was beautiful! Of course you all see it all the time if you go to the POL Documentation page. But imagine if all you had were just 3 or 4 text files explaining only a few of the built-in functions and then you were shown the Docs page. Since then Racalac has moved on and is no longer developing for POL but as new functions and features are added to POL the current, and hopefully future, developers expand the Docs to include these new features. If you ask just about any developer, engineer or designer they will tell you documentation is a PAIN. So once again I want to first thank Racalac for creating the first documentation page and just as important I want to offer my continued thanks to the developers for maintaining it and updating it with new information.
Hopefully I will have some more useful tips to add to this thread soon.