New Improved Megacliloc/Tooltip package

Post your Custom Scripts or Packages.

Moderator: POL Developer

Post Reply
Agata
Journeyman Poster
Posts: 63
Joined: Sun Oct 30, 2011 6:33 am

New Improved Megacliloc/Tooltip package

Post by Agata » Sun Jan 27, 2013 11:45 pm

I was concerned about the size of the packets sent by the Megacliloc package for tooltips, so I rewrote the thing to actually use CliLocs.

Here is the result:

toolTips.src

Code: Select all

/* $Id: toolTips.src 104 2006-05-25 22:14:15Z montuz $
 *	Description: AOS Tooltips. Starter script.
 *	This packet takes awhile to get used to.
 *	HEAVILY modified by Agata
 */

use uo;
use cfgfile;
use polsys;

include "include/skills";
include "include/math";
include "include/itemtypes";

const OFFSET_OBJECT_SERIAL   := 0x05;
const OFFSET_CLILOC_ID       := 0x0F;
const OFFSET_LENGTH_ID       := 0x13;
const OFFSET_UNICODE_TEXT    := 0x14;

program Install()

	 Print("INSTALLING: Outgoing Tooltip PH...");
	 return 1;

endprogram

exported function MegaCliloc( who, byref packet )
	if (who)
	endif

	var xObject := SystemFindObjectBySerial(packet.GetInt32(OFFSET_OBJECT_SERIAL));

	if ( xObject.IsA(POLCLASS_ITEM) )
		packet.SetSize(15);
		
		var Object_Name := xObject.desc;
		Object_Name := CAscZ(Object_Name);
		packet.SetInt32(OFFSET_CLILOC_ID, 1042971);
		packet.SetUnicodeString(OFFSET_UNICODE_TEXT, Object_Name, 1);
		// I've noticed that this packet is only sent if this value has changed
		// from the last time it was checked. And using html to change the size doesn't work
		// for some reason. Maybe a core/client issue?
		packet.SetInt16(OFFSET_LENGTH_ID, Object_Name.Size() * 2);
		
		var xDesc := run_script_to_completion ( ":megacliloc:itemdata", xObject);
		if ( xDesc.Size() > 0 )
			foreach prop in xDesc
				var str := "";
				if (prop.values.size() > 0)
					str := CStr(prop.values[1]);
					var i;
					for (i:=2; i<=prop.values.size(); i:=i+1)
						str += CChr(0x09) + CStr(prop.values[i]);
					endfor
				endif
				str := CAscZ (str);
				packet.SetInt32(packet.GetSize() - 1, prop.clilocid);
				var Length_ID := packet.GetSize();
				packet.SetUnicodeString(packet.GetSize() + 1, str, 1);
				// SetUnicodeString adds 00 BYTE[1] at the start of the Unicode offset, which messes with the length offset.
				// Setting the length of the unicode text below will fix that issue. Same deal as above.
				packet.SetInt16(Length_ID, str.Size() * 2);
			endforeach
		endif
		// End of loop.
		packet.SetInt32(packet.GetSize(), 0);
	elseif (xObject.IsA (POLCLASS_MOBILE))
		// to be added later
		//var xDesc := run_script_to_completion ( ":megacliloc:chardata", xObject);		
	endif
	return 0;
endfunction
Now this is an example itemdata script. I am sure it WON'T compile for you as it contains several shard specific functions you won't have, but serves as a good way to show you how this works.


itemdata.src

Code: Select all

// Item data generator for tooltip packet
//
// Created by Agata
// natalia_buenota@hotmail.com
// The World of Dreams
//

use uo;
use cfgfile;
use polsys;

include "include/skills";
include "include/math";
include "include/itemtypes";

// Charges: 1049116
program itemdata(xObject)
	// Start of Loop.
	
	var allprops := array;
	var prop := struct;
	prop.+ clilocid := 0;
	prop.+ values := array;
	
	var owner := GetObjProperty(xObject, "ownername");
	if (owner)
		prop.clilocid := 1072304;
		prop.values := array {owner};
		allprops.append(prop);
	endif
	owner := GetObjProperty(xObject, "craftername");
	if (owner)
		prop.clilocid := 1050043;
		prop.values := array {owner};
		allprops.append(prop);
	endif
	if ( xObject.newbie )
		prop.clilocid := 1038021;
		prop.values := array {};
		allprops.append (prop);
	endif
	if (xObject.isa(POLCLASS_CONTAINER) and !xObject.isa(POLCLASS_CORPSE) and !(GetObjProperty (xObject, "lockpicking") and xObject.locked))
		if (xObject.objtype == UOBJ_RUNEBOOK)
			// 1049116, 1061837, 1075217, 1076207,
			// 1112590, 
			var charges := GetObjProperty (xObject, "%Charges%");
			prop.clilocid := 1061837;
			prop.values := array {charges.charges, charges.max_charges};
			allprops.append (prop);
//			xDesc := xDesc + Html + CINT ((GetObjProperty (xObject, "%RuneList%")).size()) + " runes<br>";
		else
			prop.clilocid := 1073839;
			prop.values := array {CINT(xObject.item_count-1), xObject.weight};
			allprops.append (prop);
		endif
	elseif (!xObject.isa(POLCLASS_CORPSE) and !IsSign(xObject))
		prop.clilocid := 1072225;
		prop.values := array {xObject.weight};
		allprops.append (prop);
	endif
	if (IsGargishItem (xObject))
		prop.clilocid := 1111709;
		prop.values := array {};
		allprops.append(prop);
	elseif (IsForAnyRace (xObject))
		prop.clilocid := 1070722;
		prop.values := array {"For Any Race"};
		allprops.append(prop);
	endif
	if (GetObjProperty(xObject, "unidentified"))
		prop.clilocid := 1038000;
		prop.values := array {};
		allprops.append(prop);
	else
		if (xObject.isa (POLCLASS_EQUIPMENT))
			if (xObject.isa(POLCLASS_ARMOR))
				var armordesc := GetItemDescriptor(xObject.objtype);
				if (xObject.ar_mod > 0)
					prop.clilocid := 1072382;
					prop.values := array {xObject.ar_mod};
					allprops.append (prop);
					prop.clilocid := 1080361;
					prop.values := array {xObject.ar};
					allprops.append (prop);
				else
					prop.clilocid := 1060448;
					prop.values := array {xObject.ar};
					allprops.append (prop);
				endif
				if (armordesc.strrequired)
					prop.clilocid := 1061170;
					prop.values := array {CINT(armordesc.strrequired/10)};
					allprops.append (prop);
				endif
				// Have to work on this yet...
//				if (armordesc.DexPenalty)
//					xDesc := xDesc + Html + "-" + CINT(armordesc.DexPenalty/10) + " Dexterity" + "<br>";
//				endif
				if (IsMedableArmor (xObject))
					prop.clilocid := 1060437;
					prop.values := array {};
					allprops.append (prop);
				endif
			elseif (xObject.isa (POLCLASS_WEAPON))
				if (GetObjProperty(xObject, "silver"))
					prop.clilocid := 1060479;
					prop.values := array {};
					allprops.append (prop);
				endif
				var weapondesc := GetItemDescriptor(xObject.objtype);
				//Damage
				var damagefactor := (xObject.hp * xObject.quality)/xObject.maxhp;
				if (xObject.dmg_mod > 0)
					prop.clilocid := 1074762;
					prop.values := array {xObject.dmg_mod};
					allprops.append (prop);
				endif
				prop.clilocid := 1061168;
				prop.values := array {CINT((weapondesc.MinDamage + xObject.dmg_mod)*damagefactor), CINT((weapondesc.MaxDamage + xObject.dmg_mod)*damagefactor)};
				allprops.append (prop);
				//Speed
				prop.clilocid := 1061167;
				prop.values := array {weapondesc.Speed};
				allprops.append (prop);
				//Handedness
				if (weapondesc.TwoHanded)
					prop.clilocid := 1061171;
				else
					prop.clilocid := 1061824;
				endif
				prop.values := array {};
				allprops.append (prop);	
				//Mage weapon
				if (weapondesc.BlocksCastingIfInHand == 0)
					prop.clilocid := 1062755;
					prop.values := array {};
					allprops.append (prop);
				endif
				//Skill
				case (lower(xObject.attribute))
					"swordsmanship": prop.clilocid := 1061172;
					"macefighting": prop.clilocid := 1061173;
					"fencing": prop.clilocid := 1061174;
					"archery": prop.clilocid := 1061175;
					"throwing": prop.clilocid := 1112075;
					default: prop.clilocid := 1060400;
				endcase
				prop.values := array {};
				allprops.append(prop);
			
			endif
			var skillid := GetObjProperty(xObject, "skilladv");
			if (GetObjProperty (xObject, "skill"+skillid))
				var skillname := GetSkillName(skillid);
				prop.clilocid := 1060451;
				prop.values := array {skillname, GetObjProperty (xObject, "skill"+skillid)};
				allprops.append (prop);
			endif
			if (xobject.resist_poison)
				prop.clilocid := 1072385;
				prop.values := array {xObject.resist_poison};
				allprops.append (prop);
			endif
			var charges := GetObjProperty(xObject, "charges");
			if (charges)
				var spell := "";
				if (xobject.resist_fire)
					prop.clilocid := 1072383;
					prop.values := array {xObject.resist_fire};
					allprops.append (prop);
					spell := "f";
				endif
				if (xobject.resist_cold)
					prop.clilocid := 1072384;
					prop.values := array {xObject.resist_cold};
					allprops.append (prop);
					spell := "c";
				endif
				if (xobject.resist_energy)
					prop.clilocid := 1072386;
					prop.values := array {xObject.resist_energy};
					allprops.append (prop);
					spell := "e";
				endif
				if (spell == "")
					// 1017324-1017371, 1049116, 1060487-1060492, 1061837,
					// 1062412-1062416, 1072852-1072853, 1075217, 1076207,
					// 1112590, 
					spell := GetObjProperty(xObject, "itemspellname");
					if (!spell)
						prop.clilocid := 1075217;
						prop.values := array {charges + " Spell"};
						allprops.append (prop);
					else
						case (lower (spell))
							"clumsiness":
								prop.clilocid := 1017326;
							"feeblemindedness":
								prop.clilocid := 1017327;
							"weakness":
								prop.clilocid := 1017328;
							"harming":
								prop.clilocid := 1017334;
							"cursing":
								prop.clilocid := 1017335;
							"draining":
								prop.clilocid := 1017339;
							"paralyzation":
								prop.clilocid := 1017340;
							"dispelling":
								prop.clilocid := 1060417;
							"flametongue":
								prop.clilocid := 1060487;
							"lightning":
								prop.clilocid := 1060491;
							default:
								prop.clilocid := 1075217;
						endcase
						if (prop.clilocid == 1075217)
							prop.values := array {charges + " " + spell};
						else
							prop.values := array {charges};
						endif
						allprops.append (prop);
					endif
				endif
			endif
			//Durability
			prop.clilocid := 1060639;
			prop.values := array {xObject.hp, xObject.maxhp};
			allprops.append (prop);
		elseif (IsMusicalInstrument(xObject))
			var skillbonus := GetObjProperty(xObject, "skillbonus");
			if (skillbonus)
				prop.clilocid := 1060451;
				prop.values := array {"Barding Skills", skillbonus};
				allprops.append (prop);
			endif
		elseif (IsJewelry(xObject))
		//1060485, 1060409, 1060432, 1075846, 1075842, 1075844
			var stat_bonus := GetObjProperty (xObject, "str");
			if (stat_bonus)
				prop.clilocid := 1060485;
				prop.values := array {stat_bonus};
				allprops.append (prop);
			endif
			stat_bonus := GetObjProperty (xObject, "dex");
			if (stat_bonus)
				prop.clilocid := 1060409;
				prop.values := array {stat_bonus};
				allprops.append (prop);
			endif
			stat_bonus := GetObjProperty (xObject, "int");
			if (stat_bonus)
				prop.clilocid := 1060432;
				prop.values := array {stat_bonus};
				allprops.append (prop);
			endif
		elseif (xObject.isa(POLCLASS_SPELLBOOK))
			prop.clilocid := 1042886;
			prop.values := array {xObject.spells().size()};
			allprops.append (prop);
		elseif (xObject.objtype == 0xA100)
			prop.clilocid := 1042886;
			prop.values := array {NecroSpellCount(xObject)};
			allprops.append (prop);
		elseif (xObject.objtype == 0x1706b)
			prop.clilocid := 1042886;
			prop.values := array {DruidSpellCount(xObject)};
			allprops.append (prop);
		elseif (IsSign(xObject))
			owner := GetObjProperty (xObject, "lastownername");
			if (owner)
				prop.clilocid := 1041602;
				prop.values := array {owner};
				allprops.append (prop);
			endif
		endif
	endif
	return allprops;

endprogram

function NecroSpellCount(book)
	var GreaterFlag := CINT (GetObjProperty (book, "Greater"));
	var LesserFlag := CINT (GetObjProperty (book, "Lesser"));
	var spellcount := 0;
	for i := 1 to 8
		if (FlagCheck (LesserFlag, i))
			spellcount := spellcount + 1;
		endif
		if (FlagCheck (GreaterFlag, i))
			spellcount := spellcount + 1;
		endif
	endfor
	return spellcount;
endfunction

function DruidSpellCount(bag)
	var runes := GetObjProperty (bag, "runes");
	if (runes)
		return runes.size();
	endif
	return 0;
endfunction

function IsSign (item)
	case (item.objtype)
		0xb95:
		0xb96:
		0xbd0:
		0xbd2:
		0xc43:
		0xc44:
		0x1f28:
		0x1f29:
		0x17060:
		0x1708a:
			return 1;
	endcase
	if (item.objtype >= 0xba3 and item.objtype <= 0xc0e)
		return 1;
	elseif (item.objtype >= 0x1297 and item.objtype <= 0x129e)
		return 1;
	endif
	return 0;
endfunction

Attachments
megacliloc.zip
(4.09 KiB) Downloaded 194 times

Yukiko
Distro Developer
Posts: 2735
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

Re: New Improved Megacliloc/Tooltip package

Post by Yukiko » Mon Jan 28, 2013 5:07 am

Agata,
How does one use the itemdata script? In other words, how do I attach it to a specific item so that it is called for that item and what player action causes it to be called?

Thanks in advance for the info.

Agata
Journeyman Poster
Posts: 63
Joined: Sun Oct 30, 2011 6:33 am

Re: New Improved Megacliloc/Tooltip package

Post by Agata » Mon Jan 28, 2013 8:04 am

You don't need to attach it to anything, the itemdata script is called by the toolTips script, which is a PacketHook SendFunction for packet 0xD6. Download the attached Zip files and look at the uopacket.cfg file.

If you look at toolTips.src file on line 45 you will see the following:
var xDesc := run_script_to_completion ( ":megacliloc:itemdata", xObject);

And the next lines are the ones that put the data into the packet.

As for what action triggers this whole thing, hover the mouse pointer over the item.

Yukiko
Distro Developer
Posts: 2735
Joined: Thu Feb 02, 2006 1:41 pm
Location: San Antonio, Texas
Contact:

Re: New Improved Megacliloc/Tooltip package

Post by Yukiko » Tue Jan 29, 2013 5:50 am

Ah. Thanks.

Guess I was being lazy. I should have read itemdata.src. Very nice!

Thanks again.

Agata
Journeyman Poster
Posts: 63
Joined: Sun Oct 30, 2011 6:33 am

Re: New Improved Megacliloc/Tooltip package

Post by Agata » Tue Jan 29, 2013 10:43 pm

Maybe I should have mentioned that I broke it into two scripts, the toolTips.src and itemdata.src so the second can be recompiled and unloaded quickly and safely for live testing.

Harley
Forum Regular
Posts: 359
Joined: Sat Mar 18, 2006 1:41 am
Location: Germany

Re: New Improved Megacliloc/Tooltip package

Post by Harley » Wed Oct 30, 2013 11:47 am

Agata wrote:Maybe I should have mentioned that I broke it into two scripts, the toolTips.src and itemdata.src so the second can be recompiled and unloaded quickly and safely for live testing.
Agata, can u upload your cliloc.enu file? With best regards.

Harley
Forum Regular
Posts: 359
Joined: Sat Mar 18, 2006 1:41 am
Location: Germany

Re: New Improved Megacliloc/Tooltip package

Post by Harley » Wed Apr 02, 2014 10:25 am

Agata, thanks for your megacliloc! It's great!
Tell me please, did you finish a chardata or you didn't do this?

Agata
Journeyman Poster
Posts: 63
Joined: Sun Oct 30, 2011 6:33 am

Re: New Improved Megacliloc/Tooltip package

Post by Agata » Tue Nov 25, 2014 7:11 am

I started work on a "chardata" script, and since I wanted to implement custom selectable titles, title styles and other things, I stopped working on it until I finish designing the Titles System

Post Reply