RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Skill Ball - Final

Kamron

Knight
Skill Ball - Final

Summary:
This skill ball has absolutely no bugs or exploits and is based off of the original Wulf C. Krueger skillball.

Description:
This skill ball takes into account the skillcap of the individual player.
It allows them to first use up all available skill points in their pool, and furthermore utilize all skills facing down in order to get the desired amount of skills gained
The skillball will not allow anyone to raise a skill past that particular's skills cap by simply not displaying the skill in the gump. (if a better approach to this can be thought up, please do tell).

This skillball was tested for all possible exploits.

Installation:
Drop anywhere in your scripts folder, or replace the already existing skillball script with this one.
 

Attachments

  • skillball.cs
    6.3 KB · Views: 2,155

Igon

Wanderer
How about showing all skills that aren't maxed out, and subtract the difference from the skill ball, thus maxing out one skill and having the remainder of the points left to use on another skill?

Just a thought.
 

Kamron

Knight
Problem is that for most shards the point of a skillball is to raise 1 skill. This would be shard dependant, and I guess I could add a boolean. I had this idea before, but for Defiance (what this was altered to work on), that was not the desired functionality. It's no problem, I can add it.
 
W

Whitefyr

Guest
That would be incredible. I would greatly appreciat that.
 

NoIdeaNoClue

Wanderer
Is there a way to determine if a player has used a PS in a particular skill and then allowing them to actually use the bonus for that skill over 100? Somehow delete the ball even if they didn't use all of the bonus. If a player has 98.0 and the cap for that skill is 100.0 and they use a skillball for +10, they would only get to that skill's cap (100.0) no matter what with the extra points just being lost.

I changed it to show skills that the bonus plus the skill would be less than or equal to 120 but no matter if they have used a powerscroll or not, the skillball will take them over that skill's cap. (example: Players swordmanship cap is 100.0, they have 96.0, when they use the skillball (at +10) they have 106.0.) Somehow a check needs to be made for that particular skill to see what the cap is at, but I have no idea (hence my handle) how to do that.

Don't know if anything I just said made sense. If not, just ignore me. lol
 

NoIdeaNoClue

Wanderer
Well, what do you know...I actually figured some of it out. I have edited and added some things to this skillball so that it takes the player's cap of a certain skill in consideration. However, all leftover points will be lost (only goes to the player's cap). The scripting might be a bit sloppy but it works for my shard. If you have any problems with this, let me know and I'll try to help with what I can.
Code:
//	RunUO script: Skill Ball
//	Copyright (c) 2003 by Wulf C. Krueger <[email protected]>
//
//	This script is free software; you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation; version 2 of the License applies.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	Please do NOT remove or change this header.

//	Official Defiance(c) skillball - by [Dev]Kamron aka XxSP1DERxX - [email][email protected][/email]

//	"Shr"edited by NoIdeaNoClue to fully take advantage of the powerscroll/cap system. Renamed to
//	SkillBall10 for the +10 bonus (edit the bonus to whatever you like). All leftover skill points
//	from this ball, will be gone (only goes to the players cap).

using System;
using Server.Network;
using Server.Items;
using Server.Gumps;
using System.Collections;

namespace Server.Items
{
	public class SkillBall10 : Item
	{
		private int m_SkillBonus = 10;
		private string m_BaseName = "a skill ball +";
		public bool GumpOpen = false;

		[CommandProperty( AccessLevel.GameMaster )] 
		public int SkillBonus
		{
			get { return m_SkillBonus; }
			set 
			{ 
				m_SkillBonus = value;
				this.Name = m_BaseName + Convert.ToString(m_SkillBonus); 
			}
		}

		[Constructable]
		public SkillBall10( int SkillBonus ) : base( 6249 )
		{
			m_SkillBonus = SkillBonus;
			Name = m_BaseName + Convert.ToString(SkillBonus); 
		}

		[Constructable]
		public SkillBall10() : base( 6249 )
		{
			Name = m_BaseName + Convert.ToString(SkillBonus); 
		}

		public SkillBall10( Serial serial ) : base( serial )
		{
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( (this.SkillBonus == 0) && (from.AccessLevel < AccessLevel.GameMaster) ) 
			{
				from.SendMessage("This skill ball isn't charged. Please page for a GM.");
				return;
			}
			else if ( (from.AccessLevel >= AccessLevel.GameMaster) && (this.SkillBonus == 0) ) 
			{
				from.SendGump( new PropertiesGump( from, this ) );
				return;
			}

			if ( !IsChildOf( from.Backpack ) ) 
				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
			else if (!GumpOpen) 
			{
				GumpOpen = true;
				from.SendGump( new SkillBallGump10( from, this ) );
			}
			else if (GumpOpen)
				from.SendMessage("You're already using the ball.");
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
			writer.Write( m_SkillBonus );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			switch (version) 
			{
				case 0 : 
				{
					m_SkillBonus = reader.ReadInt();
					break;
				}
			}
		}
	}
}

namespace Server.Gumps
{
	public class SkillBallGump10 : Gump
	{
		private const int FieldsPerPage = 14;

		private Skill m_Skill;
		private SkillBall10 m_skb;

		public SkillBallGump10 ( Mobile from, SkillBall10 skb ) : base ( 20, 30 )
		{
			m_skb = skb;
			
			AddPage ( 0 );
			AddBackground( 0, 0, 260, 351, 5054 );
			
			AddImageTiled( 10, 10, 240, 23, 0x52 );
			AddImageTiled( 11, 11, 238, 21, 0xBBC );
			
			AddLabel( 65, 11, 0, "Skills you can raise" );
			
			AddPage( 1 );
			
			int page = 1;
			int index = 0;
			
			Skills skills = from.Skills;
			
			int number;
			if ( Core.AOS )
				number = 0;
			else
				number = 3;
			
			for ( int i = 0; i < ( skills.Length - number ); ++i ) 
			{
				if ( index >= FieldsPerPage ) 
				{
					AddButton( 231, 13, 0x15E1, 0x15E5, 0, GumpButtonType.Page, page + 1 );
					 
					++page;
					index = 0;
					 
					AddPage( page );
					 
					AddButton( 213, 13, 0x15E3, 0x15E7, 0, GumpButtonType.Page, page - 1 );
				}
			  
				Skill skill = skills[i];
			  
				if ( skill.Base < skill.Cap )				
				{	 
					AddImageTiled( 10, 32 + (index * 22), 240, 23, 0x52 );
					AddImageTiled( 11, 33 + (index * 22), 238, 21, 0xBBC );
					 
					AddLabelCropped( 13, 33 + (index * 22), 150, 21, 0, skill.Name );
					AddImageTiled( 180, 34 + (index * 22), 50, 19, 0x52 );
					AddImageTiled( 181, 35 + (index * 22), 48, 17, 0xBBC );
					AddLabelCropped( 182, 35 + (index * 22), 234, 21, 0, skill.Base.ToString( "F1" ) );
					 
					if ( from.AccessLevel >= AccessLevel.Player )
						AddButton( 231, 35 + (index * 22), 0x15E1, 0x15E5, i + 1, GumpButtonType.Reply, 0 );
					else
						AddImage( 231, 35 + (index * 22), 0x2622 );
					 
					++index;
				}
			}
		}
	  
		public override void OnResponse( NetState state, RelayInfo info )
		{
			Mobile from = state.Mobile;
			
			if ( (from == null) || (m_skb.Deleted) )
				return;

			m_skb.GumpOpen = false;

			if ( info.ButtonID > 0 ) 
			{
				m_Skill = from.Skills[(info.ButtonID-1)];
			  
				if ( m_Skill == null )
					return;
			
				double count = from.Skills.Total / 10;
				double cap = from.SkillsCap / 10;
				ArrayList decreased = new ArrayList();
				double decreaseamount = 0.0;
				double bonuscopy = m_skb.SkillBonus;
				if ( (count + bonuscopy) > cap ) 
				{
					for (int i = 0;i < from.Skills.Length;i++ )
					{
						if (from.Skills[i].Lock == SkillLock.Down)
						{
							decreased.Add(from.Skills[i]);
							decreaseamount += from.Skills[i].Base;
							break;
						}
					}
					if (decreased.Count == 0)
					{
						from.SendMessage("You have exceeded the skill cap and do not have any skills set to be decreased.");
						return;
					}
				}
				if (m_Skill.Base + bonuscopy > m_Skill.Cap) 
				{
					if ((cap - count) + decreaseamount >= bonuscopy)
					{
						if (cap - count >= bonuscopy)
						{
							m_Skill.Base = m_Skill.Cap;
							bonuscopy = 0;	
						}
						else
						{
							m_Skill.Base = m_Skill.Cap;
							bonuscopy -= cap - count;

							foreach( Skill s in decreased)
							{
								if (s.Base >= bonuscopy)
								{
									s.Base -= bonuscopy;
									bonuscopy = 0;
								}
								else
								{
									bonuscopy -= s.Base;
									s.Base = 0;
								}
							
								if (bonuscopy == 0)
									break;
							}
						}
						m_skb.Delete();
					}
					else
						from.SendMessage("You must have enough skills set down to compensate for the skill gain.");
				}
				

				else if (m_Skill.Base + bonuscopy <= m_Skill.Cap) 
				{
					if ((cap - count) + decreaseamount >= bonuscopy)
					{
						if (cap - count >= bonuscopy)
						{
							m_Skill.Base += bonuscopy;
							bonuscopy = 0;	
						}
						else
						{
							m_Skill.Base += bonuscopy;
							bonuscopy -= cap - count;

							foreach( Skill s in decreased)
							{
								if (s.Base >= bonuscopy)
								{
									s.Base -= bonuscopy;
									bonuscopy = 0;
								}
								else
								{
									bonuscopy -= s.Base;
									s.Base = 0;
								}
							
								if (bonuscopy == 0)
									break;
							}
						}
						m_skb.Delete();
					}
					else
						from.SendMessage("You must have enough skills set down to compensate for the skill gain.");

				}
				else 
					from.SendMessage("You have to choose another skill.");
			}
		}
	}
}
Hope this helps anyone that needs it. :)

Yay!! Nite Nite Time!!
 

Kamron

Knight
Yeah, see I can do all of that, but everyone has a different opinion on how it should work. I am uncertain which to choose. And I would hate to code this with ten different modifiers to make it bulky and discouraging to use.
 

Kamron

Knight
Give me a little bit of time, and I will make this bulky version with all of the stuff you guys make (as well as keep the original final skillball).
 

septor

Sorceror
Why not make 2 versions, one that added all points to one skill, and any left over points would be lost. And then make one that, when a skill is maxed out, all remaining points can then go into another skill, and so on until the points on the skillball are gone. This way, players can't persay pick how many points go into what skills it more or less adds any points needed to max a skill out. To clearify this:

A player gets a +100 skill ball, woot!

Their skills as of now are:

65 Magery
75 EvalInt
45 Resist
26 Med
16 Wrestling

They click the skillball, they have 100 points, they decided to max out EvalInt, this takes the skill ball down to 75. They now decided they'd like to put only 20 points in Magery, but they soon find out that, because the skillball only maxes out skills, magery is upped to 100, and the skill ball points now dropped to 40. With only 40 points left, they realize that the skill ball adds points to a skill as far as it can go, so they decided to put the remaining points into Resist, thus making it 85, and leaving the skillball empty.

Basically, the skill ball keeps maxing out skills until it's empty, not allowing for picking and choosing how many points go to which skills, and also eliminating wasted skill points.
 

NoIdeaNoClue

Wanderer
septor said:
Why not make 2 versions, one that added all points to one skill, and any left over points would be lost. And then make one that, when a skill is maxed out, all remaining points can then go into another skill, and so on until the points on the skillball are gone. This way, players can't persay pick how many points go into what skills it more or less adds any points needed to max a skill out. To clearify this:

A player gets a +100 skill ball, woot!

Their skills as of now are:

65 Magery
75 EvalInt
45 Resist
26 Med
16 Wrestling

They click the skillball, they have 100 points, they decided to max out EvalInt, this takes the skill ball down to 75. They now decided they'd like to put only 20 points in Magery, but they soon find out that, because the skillball only maxes out skills, magery is upped to 100, and the skill ball points now dropped to 40. With only 40 points left, they realize that the skill ball adds points to a skill as far as it can go, so they decided to put the remaining points into Resist, thus making it 85, and leaving the skillball empty.

Basically, the skill ball keeps maxing out skills until it's empty, not allowing for picking and choosing how many points go to which skills, and also eliminating wasted skill points.
I agree with septor. Two versions would make it perfect. That way both can be offered as rewards (with the one that can be used on multiple skills being a higher reward of course) or Admins can choose which version to offer.

XxSP1DERxX said:
Yeah, see I can do all of that, but everyone has a different opinion on how it should work.
I have no doubt you could...I did it. lol Two seperate skillballs would definately put an end to everyone's problem (well, almost everyone as you can't please them all). :)
 

Kamron

Knight
Well what I would do personally is make two versions yes (which isn't that difficult..)
and the second one, would just subtract however many points were used from the current skillball, and just not delete that ball. Then they can use the ball again if they want on another skill. Or they can sell the ball, or give it to another player (depending on how your shard is run, and how good you are at spotting exploits). Or if they can't do that.. auction it (if you have a shitty auction system with no exploit checks).

See.. there are factors that play into the restriction. But I will make one that works like that.
 

septor

Sorceror
Is it possible to make it work for only the person it's given to? Kind of like a new player ticket.

edit

Or even better, make it nonmovable, making it even less exploitable.
 

Kamron

Knight
Of course, I can load it with shitloads of security. Again all of these are shard based. Some shard would want it to be a NoDrop, No Trade item. Others don't care. Others only want it to work for 1 skill, and THATS IT. Other believe that the full amount of points being used is important, and are willing to allow players to use it on multiple skills.


Basically, stop asking for features which are shard specific, because then we will have alot of versions going :\ Again, or I can make it bulky.
 

septor

Sorceror
So do you want suggestions or not? I was under the imression we were giving you suggestions and then you were going from there. Shard specific or not, they're ideas, either use them or don't, it's really simple.
 

NoIdeaNoClue

Wanderer
To make it non-movable just set it from:
Code:
                           [Constructable]
		public SkillBall10( int SkillBonus ) : base( 6249 )
		{
			m_SkillBonus = SkillBonus;
			Name = m_BaseName + Convert.ToString(SkillBonus); 
		}

                           [Constructable]
		public SkillBall10() : base( 6249 )
		{
			Name = m_BaseName + Convert.ToString(SkillBonus); 
		}
To:
Code:
                                [Constructable]
		public SkillBall10( int SkillBonus ) : base( 6249 )
		{
			m_SkillBonus = SkillBonus;
                         Movable = false;
			Name = m_BaseName + Convert.ToString(SkillBonus); 
		}

		[Constructable]
		public SkillBall10() : base( 6249 )
		{
			Name = m_BaseName + Convert.ToString(SkillBonus); 
                         Movable = false;
		}
Then you can give them to players at character creation and they can't transfer them to other players or between characters. :)
 

Kamron

Knight
You don't want to give players non-movable items... it causes problems.

Another method which I used on another shard, was to put them into player banks unmovable and make them usable only from thier bank. But again, all up to the shard admin. You DO NOT want to put unmovable items into a player's backpack, period.
 
Top