Tracking Rewrite from Scratch

Post your Custom Scripts or Packages.

Moderator: POL Developer

Post Reply
User avatar
Damien White
Journeyman Poster
Posts: 68
Joined: Tue Aug 18, 2009 6:34 pm
Location: Canada

Tracking Rewrite from Scratch

Post by Damien White »

Here is a different way to take a look at the tracking skill. This is my 1st code attempt. So please be patient if you can write it more efficiently. However, I sure would like to hear about it. Please leave feedback.

Let's start with a few images for visual reference:

[img=http://img4.imageshack.us/img4/5453/uo0002bn.th.jpg]
[img=http://img7.imageshack.us/img7/9370/uo0003o.th.jpg]
[img=http://img4.imageshack.us/img4/7133/uo0001t.th.jpg]

Features:
- Visual gump display
- Gump is transeparent and movable so player can view behind
- Tracked mobiles listed on a radar type display in a button format
- Radar buttons are interactive, and change colour based on successfuly obtained info
- On successful skill check mobile details will be displayed

Todo:
- The gump displays an icon for mobiles tracked, the function that calls the appropriate images is not complete

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Package: Tacking
// Scripts: Tacking
// Version: 3.21
//
// Design Date: Sept 01 2009
//
// Designed by Damien White
// Designed for The Shores of Babylon
////////////////////////////////////////////////////////////////////////////////
// Info:
//   MobileInfo[0]  = Unused
//   MobileInfo[1]  = Tracked Mobile Ref
//   MobileInfo[2]  = Name - Skill Check Success or Fail [1/0]
//   MobileInfo[3]  = Speed - Skill Check Success or Fail [1/0]
//   MobileInfo[4]  = Hidden - Skill Check Success or Fail [1/0]
//   MobileInfo[5]  = Image - Shown if name is known
//   
//   TotalInfo = [2] + [3] + [4] -> Tracks # of peices of info success for button colour
//
//   Picture = function tileimage(tile)
//
//   Colours -> Red = 37    Blue = 98    Green = 371
////////////////////////////////////////////////////////////////////////////////
// Details:
// - Skill check vs Dexterity done for each trackable added to Visual Array (MobileInfo)
//     - Skill check vs Dexterity for each peice of info (Name, Speed, Hidden)
//     - Picture is given if name is successful
// - Skill Checks are made against the tracked mobiles Dexterity
// - Skill gain is based on difficulty, which is based on mobiles dexterity
// - range = (skill% / 2) + 5 (Max range = 55 paces)
// - mobiles removed from radar when out of range
//
////////////////////////////////////////////////////////////////////////////////
// Things to do:
// - add sfx check for all races
//
////////////////////////////////////////////////////////////////////////////////

// Modules
use uo;
use os;
use polsys;
use attributes;

// Includes
include ":attributes:advanceCheck";

// Program Body
program tracking(who)

  // How far is tracking range? (Skill / 2 = # of paces) + 5
  var TrackingRange := (GetAttributeBaseValue( who, "Tracking" ) / 20)+5;
  
  // List of Mobiles in that range (Including tracker)
  var Trackables := ListMobilesNearLocation( who.x, who.y, who.z, TrackingRange, realm := _DEFAULT_REALM );
  
  // Set up variables used
  var HowSuccessful; // Used in skill check
  var MobileInfo := array; // Array of information on each mobile (See top)
  var SingleMobileInfo := {0,0,0,0,0,0}; // Temp array used for setting MobileInfo
  
  var NumberOfTrackables := 0; // Used to count Mobiles in area
  
  var TrackDifficulty; //Difficulty Level (Check against itself)
  var award_diff;
  // Add all trackables, except tracker to array, and data
  for a := 1 to len(Trackables)
    
    TrackDifficulty := GetAttribute( Trackables[a], "Dexterity" );
		award_diff := TrackDifficulty;

    // General skill check to find mobile
  	HowSuccessful := SkillCheck(who, "Tracking", TrackDifficulty, award_diff, advance_flags:=ADV_ALL);

    // Fill Mobile Info array for each trackable on successful skill check
	  If ( HowSuccessful > 0) // Skill Check here if the mobile button should be added
  
      if ((Trackables[a].serial != who.serial) || (GetCmdLevelNumber(Trackables[a]) > 1) || (Trackables[a].connected != 1)) // Only add tracked mobiles not tracker or admin team
        
        // Action and sound effect -> Hands on hips -> "Ahha!"
        // Check human female and male
        // **** Add check for all races
        PerformAction(who,6);
        if (who.graphic == 0x190)
        	PlaySoundEffect (who, 0x41b);
        elseif (who.graphic == 0x191)
        	PlaySoundEffect (who, 0x30c);
        endif
        sleepms(1200);
        
        // Add Mobile Ref to Mobile Info
        SingleMobileInfo[1] := Trackables[a];
        
        // Skill Check for name
        HowSuccessful := SkillCheck(who, "Tracking", TrackDifficulty, award_diff, advance_flags:=ADV_ALL);

        // Fill Mobile Info with -> Name data
	      If ( HowSuccessful > 0)
	        SingleMobileInfo[2] := 1;
	      endif
	      
	      // Fill Mobile Info with -> Speed data
		    HowSuccessful := SkillCheck(who, "Tracking", TrackDifficulty, award_diff, advance_flags:=ADV_ALL);

		    If ( HowSuccessful > 0)
		  	  SingleMobileInfo[3] := 1;
	  	  endif
	  	  
	  	  // Fill Mobile Info with -> hidden data
	  	  HowSuccessful := SkillCheck(who, "Tracking", TrackDifficulty, award_diff, advance_flags:=ADV_ALL);

	 	    If ( HowSuccessful > 0)
	 	    	SingleMobileInfo[4] := 1;
	  	  endif
	  	  
	  	  // Add Single Mobile Info to Mobile Info Array
	  	  MobileInfo.append(SingleMobileInfo);
	  	  // Set Single Mobile Info to default
	  	  SingleMobileInfo := {0,0,0,0,0,0};
	  	  // Track number of mobile currently refferenced
	  	  NumberOfTrackables := NumberOfTrackables + 1;
	  	  
	  	  endif
		  
		endif
    
 	endfor
 	
 	// Preset variables used to track mobile clicked in gump
 	var ButtonReturned := 1;
  var ButtonSelected := 0;
  
  // Gump Display Loop -> Only exit if quit button is pressed
  while(ButtonReturned != 0)
    ButtonReturned := CInt(DisplayGump(who, MobileInfo, NumberOfTrackables, ButtonSelected, TrackingRange));
    ButtonSelected := ButtonReturned;
  endwhile

endprogram

// Making it a function makes it easier to loop
function DisplayGump(who, MobileInfo, NumberOfTrackables, ButtonSelected, TrackingRange)

  var gump := array {
		"page 0",
		"noclose",
		"resizepic 8 27 2620 265 449",
		"checkertrans 13 32 255 439",
		"text 93 31 147 0",
		"gumppic 0 32 9006",
		"resizepic 158 327 2620 91 94",
		"tilepic 168 339 8459",
		"text 22 448 996 1",
		"text 32 296 147 2",
		"gumppic 88 296 2440",
		"gumppic 135 159 1210",
		"text 96 296 37 3",
		"text 32 328 147 4",
		"gumppic 88 328 2444",
		"text 96 328 37 5",
		"text 32 360 147 6",
		"gumppic 88 360 2444",
		"text 96 360 37 7",
		"gumppic 17 427 2360",
		"text 32 424 37 8",
		"gumppic 94 427 2362",
		"text 112 424 98 9",
		"gumppic 177 428 2361",
		"text 192 424 371 10",
		"button 57 392 1027 1027 1 0 0"
	};
	
	// Define Button Image for each mobile and add to gump DisplayGump
	var MobileDistanceX;
	var MobileDistanceY;
	var ButtonImage;
	
	var TotalInfo;
	
	var DistanceToMobile;
	
	//Add buttons to gump
	for a := 1 to NumberOfTrackables

	  MobileDistanceX := ((MobileInfo[a,1].x - who.x) + 135);
	  MobileDistanceY := ((MobileInfo[a,1].y - who.y) + 159);

		TotalInfo := cint(MobileInfo[a,2]) + cint(MobileInfo[a,3]) + cint(MobileInfo[a,4]);

	  Case(TotalInfo)
			1: // Red
		   ButtonImage := 2360;
			2: // Blue
			  ButtonImage := 2362;
			3: // Green
		   ButtonImage := 2361;
			Default: // Red
		   ButtonImage := 2360;
    endcase
    
    DistanceToMobile := Distance( MobileInfo[a,1], who );
    
    If (DistanceToMobile <= TrackingRange) // Continue to list mobile if still within range
    	gump[Len(gump) + a] := "button " + MobileDistanceX + " " + MobileDistanceY + " " + ButtonImage + " " + ButtonImage + " 1 0 " + cstr(a);
    endif
    
  endfor
  
  // Add Mobile Info to gump
  var Species;
  var SpeciesColour;
	var Speed;
	var SpeedColour;
	var Hidden;
	var HiddenColour;
	
	// On 1st load of gump, no button is pressed, so set defaults
	if (ButtonSelected == 0)
		Species := "unknown";
		SpeciesColour := 37;
		Speed := "unknown";
		SpeedColour := 37;
		Hidden := "unknown";
		HiddenColour := 37;
		gump[8] := "tilepic 168 339 " + tileimage(0);
	else
	
	  // Species
	  if(MobileInfo[ButtonSelected,2] == 1)
		  Species := MobileInfo[ButtonSelected,1].name;
		  SpeciesColour := 371;
		  gump[8] := "tilepic 168 339 " + tileimage(MobileInfo[ButtonSelected,1].graphic);
		else
		  Species := "unknown";
		  SpeciesColour := 37;
		  gump[8] := "tilepic 168 339 " + tileimage(0);
		endif
		
		// Speed
		if(MobileInfo[ButtonSelected,3] == 1)
			//Text Info
		  If (MobileInfo[ButtonSelected,1].run_speed == 0)
		    Speed := "no move";
		  elseif (MobileInfo[ButtonSelected,1].run_speed > 30)
		    Speed := "fast";
		  elseif (MobileInfo[ButtonSelected,1].run_speed > 20)
		    Speed := "medium";
		  elseif (MobileInfo[ButtonSelected,1].run_speed > 10)
		    Speed := "slow";
		  endif
		  SpeedColour := 371;
		else
		  Speed := "unknown";
		  SpeedColour := 37;
		endif
		
		// Hidden
		if(MobileInfo[ButtonSelected,4] == 1)
			if(MobileInfo[ButtonSelected,1].hidden == 1)
		    Hidden := "yes";
		    HiddenColour := 371;
		  else
			  Hidden := "no";
			  HiddenColour := 371;
			endif
		else
			Hidden := "unknown";
			HiddenColour := 37;
		endif
	endif
	
	// Adjust colour of text for Species, Speed and HiddenColour
	gump[13] := "text 96 296 " + SpeciesColour + " 3";
	gump[16] := "text 96 328 " + SpeedColour + " 5";
	gump[19] := "text 96 360 " + HiddenColour + " 7";
	
	var data := array {
		"- - Tracking - -",
		"The Shores of Babylon © 2009 - 2010",
		"Species:",
		Species,
		"Speed:",
		Speed,
		"Hidden:",
		Hidden,
		"Unknown",
		"Not Sure",
		"Successful"
	};
	
	var trapcancelbutton := 0;
	
	var SelectedMobile := SendDialogGump(who, gump, data);
	
	foreach key in ( SelectedMobile.keys )
	  ButtonSelected := key;
	  trapcancelbutton := 1;
  endforeach
  
  if (trapcancelbutton == 0)
  	ButtonSelected := 0;
  endif
	
	return ButtonSelected;

endfunction

// I could not find an easy way to do this
function tileimage(tile)
	
	case(tile)
		0x1: // Ogre
			return 0x20df;
		0x2: // Ettin
			return 0x20de;
		0x3: // Zombie
			return 0x20ec;
		0x4: // Gargoyle
			return 0x20d9;
		0x5: // Bird - Eagle
			return 0x20f2;
		0x6: // Bird - Generic
			return 0x20ee;
		0x7: // Orc - Captain
			return 0x25af;
		0x8: // Corpser
			return 0x20d2;
		0x9: // Daemon
			return 0x20d3;
		0xa: // Daemon 2
			return 0x20d3;
		0xb: // Spider - Dread
			return 0x25c4;
		0xc: // Dragon
			return 0x20d6;
		0xd: // Elemental - Air
			return 0x20ed;
		0xe: // Elemental - Earth
			return 0x20d7;
		0xf: // Elemental - Water
			return 0x20f3;
		0x10: // Elemental - Water
			return 0x210b;
		0x11: // Orc
			return 0x20e0;
		0x12: // Ettin 2
			return 0x20de;
		0x13: // Spider - Dread 2
			return 0x25c4;
		0x14: // Spider - Frost
			return 0x25c5;
		0x15: // Snake - Giant
			return 0x25bf;
		0x16: // Gazer
			return 0x20f4;
		0x17: // Wolf - Dire
			return 0x25d0;
		0x18: // Liche - Retro
			return 0x25a4;
		0x19: // Wolf - Grey
			return 0x25d1;
		0x1a: // Ghost
			return 0x25c7;
		0x1b: // Wolf - Grey 2
			return 0x25d1;
		0x1c: // Spider - Giant
			return 0x25c6;
		
			
		0xcf: // Sheep
			return 0x20eb;
			
		0xd8: // Cow Spotted (Brown?)
			return 0x2103;
			
		0xe7: // Cow Brown (Spotted?)
			return 0x2103;
			
		0xea: // Deer - Stag
			return 0x20d4;
		0xed: // Deer - Doe
			return 0x20d4;
			
		0x190: // Human Male
			return 0x20cd;
		0x191: // Human Female
			return 0x20ce;
			
		default: // No Draw
			return 0x1;
			
	endcase
	
endfunction
*** PLEASE READ WHOLE THREAD FOR ALL FEATURES ****
Last edited by Damien White on Tue Sep 29, 2009 3:11 pm, edited 2 times in total.
MuadDib
Former Developer
Posts: 1091
Joined: Sun Feb 12, 2006 9:50 pm
Location: Cross Lanes, WV

Re: Tracking Rewrite from Scratch

Post by MuadDib »

Nice work, I think someone who works on distro patches should work on adding this method to distro.

One question, does the gump dynamically update based on mobs moving, that it finds? Could be done, if it doesn't
User avatar
Damien White
Journeyman Poster
Posts: 68
Joined: Tue Aug 18, 2009 6:34 pm
Location: Canada

Re: Tracking Rewrite from Scratch

Post by Damien White »

Thanks for the input MaudDip!

Fact is, when the gump is first loaded, a default set of data is added.
"Unknown"
"Unknown"
"Unknown"
At this time, it is assumed none of the tracked mobile buttons have been pressed.

When a button is pressed, not only is the info updated in the text fields, but the location of the mobiles are updated in the map. This is to give the effect of constant tracking. So to keep following the where abouts of a mobile just keep pressing the button.

However, did you say that mobiles (buttons) could be tracked and location updated on the radar live? If that is possible, please do tell.

Let me take this oppertunity to list a few other features:
- tracking range = (Skill% / 2) + 5, so 0% tracking is 5 paces, but 100% tracking is 55 paces. It is easy enough to change this as documented in the script.
- Difficulty is based on the Dexterity of the mobile being tracked. The more agile a creature is, the harder it is to track.
- Info text also changes colour to better indicate if you have succeeded the skill check needed to obtain that info.

If a tracker wants to get more info, if some info checks failed, or a mobile is not listed. All he has to do is, close the gump and try again.

Again, thanks for the feedback, please keep it coming.
User avatar
Damien White
Journeyman Poster
Posts: 68
Joined: Tue Aug 18, 2009 6:34 pm
Location: Canada

Re: Tracking Rewrite from Scratch

Post by Damien White »

Updated the original code with the following features:
- Mobile removed from radar when outside of tracking range
- Mobiles with cmdlevel > 1 no longer trackable
- Mobiles/players logged off will be removed from radar
- added a few more icons ( I guess I will add these slowly and post them with updates if noone else offers)
MuadDib
Former Developer
Posts: 1091
Joined: Sun Feb 12, 2006 9:50 pm
Location: Cross Lanes, WV

Re: Tracking Rewrite from Scratch

Post by MuadDib »

This is all just personal preference, but,. to me makes sense. Your call though :)

1. Instead of Quit, use the nice OK button
2. Default info should be just empty instead of unknown, looks a bit cleaner that way.
3. Instead of the green button, using a Map Pin icon for mobiles. Can't remember if hueing for gumps works, but could hue it if does. If not, then at that point the "Not Sure" would be hit or miss for them and they wouldn't just simply ignore them which might be a better idea anyway.
4. Unknown ones, shouldn't be listed at all. Keep those hidden from the player so they can't track unknown mobs and find stuff they should not be able to.
5. The tilepic could be loaded from a config file. Much cleaner code that way, and easier to add new creatures to the tracking list.
User avatar
Damien White
Journeyman Poster
Posts: 68
Joined: Tue Aug 18, 2009 6:34 pm
Location: Canada

Re: Tracking Rewrite from Scratch

Post by Damien White »

Those are some interesting thoughts...

1. The okay button would be rather misleading. As you are not really agreeing to anything. But rather you are quitting your attempt to track. At least that was my line of thinking.

2. So you suggest just "" for default info. Can do. I guess that would be cleaner.

3. It's not hueable, I went through ever picture, and the one used seem to be the best for the task.

4. As for showing unknown one. They are not listed. All mobiles in the area are skill check listed. On success they get listed. The colour of the button reflects the amount of info (name, speed and hidden) known. Not if a mobiles tracks are known.

5. I suppose this could be converted to a CFG file, they way it is written on my end, is this is in an include file accessed by other scripts. But if it were being looked at to add to the distro package, I certainly would not mind the work.

Thanks again for all the feedback. I am curious if anyone is actualy using the script on their shard. Please let me know if you are... ;)
Havoc
Neophyte Poster
Posts: 34
Joined: Mon Feb 13, 2006 1:35 pm

Re: Tracking Rewrite from Scratch

Post by Havoc »

I have not yet implemented this, but this looks very promising!
User avatar
Damien White
Journeyman Poster
Posts: 68
Joined: Tue Aug 18, 2009 6:34 pm
Location: Canada

Re: Tracking Rewrite from Scratch

Post by Damien White »

Thanks for the input!
Post Reply