--------------------------------------------------------------------------------

ServUO - [http://www.servuo.com] Version 0.5, Build 6217.15950
Publish 54
Core: Optimizing for 4 64-bit processors
RandomImpl: CSPRandom (Software)
Core: Loading config...
Scripts: Compiling C# scripts...Failed with: 1 errors, 0 warnings
Errors:
+ Mobiles/PlayerMobile.cs:
CS0266: Line 88: Cannot implicitly convert type 'uint' to 'int'. An explicit
conversion exists (are you missing a cast?)
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.
I did have to change the number to 0x80000000 instead of 0x40000000
But that is it, the other part for refuse trade is properly merged in, so any ideas>?????
Code:
  #region Enums
   [Flags]
   public enum PlayerFlag // First 16 bits are reserved for default-distro use, start custom flags at 0x00010000
   {
     None = 0x00000000,
     Glassblowing = 0x00000001,
     Masonry = 0x00000002,
     SandMining = 0x00000004,
     StoneMining = 0x00000008,
     ToggleMiningStone = 0x00000010,
     KarmaLocked = 0x00000020,
     AutoRenewInsurance = 0x00000040,
     UseOwnFilter = 0x00000080,
     PublicMyRunUO = 0x00000100,
     PagingSquelched = 0x00000200,
     Young = 0x00000400,
     AcceptGuildInvites = 0x00000800,
     DisplayChampionTitle = 0x00001000,
     HasStatReward = 0x00002000,
     Bedlam = 0x00010000,
     LibraryFriend = 0x00020000,
     Spellweaving = 0x00040000,
     GemMining = 0x00080000,
     ToggleMiningGem = 0x00100000,
     BasketWeaving = 0x00200000,
     AbyssEntry = 0x00400000,
     ToggleClippings = 0x00800000,
     ToggleCutClippings = 0x01000000,
     ToggleCutReeds = 0x02000000,
     MechanicalLife = 0x04000000,
  HumilityHunt = 0x08000000,
  ToggleCutTopiaries = 0x10000000,
  HasValiantStatReward = 0x20000000,
  FireRockMining  = 0x40000000,
     RefuseTrades = 0x80000000,
   }
All help is appreciated, I would really like to get this update in today :(

Shazzy
 
Changing the underlying type of the enum can and will cause serialization issues without taking the proper precautions.

It is recommended that ulong be used instead of uint, because it can provide the most possible combinations of options.
 
An int is what we call a primitive type. All primitive types use the same amount of memory when created, this cannot be increased or lowered which means there is a floor and a ceiling on the amount of data that can be stored in the type.

in c# on windows an int has a size of 32 bits. This is equivalent to 0xFFFFFFFF or 4,294,967,295. Now you might be saying, wait a second. 0x80000000 is a smaller number than 0xFFFFFFFF and you would be right! But, to accommodate numbers in the negative range we have to use one of the bits available in order to know if a number is negative or positive. This leaves us with 31 bits or 0x7FFFFFFF or 2147483647 in both the positive and negative range. This is called a signed integer.

Your flag above is overflowing the maximum amount of a signed integer by a single decimal. In order to get around this you need to tell the computer that your integer will never be negative thus allowing you to use all 32 bits essentially doubling the range you can use so long as the number is always positive. This is called an unsigned int or a uint.

You can also use a long instead of an integer to get 64 bits of data which is an immense number. 0 to 18446744073709551615.

Or you can use the decimal type which is the biggest primitive available to us, which is a 128 bit number. However, decimal is a very slow data type since our CPU's are only 64 bit. Every time you use a decimal your computer has to do a lot more math in order to figure out the result of an operation since we do not have handy instruction sets available to us in the hardware like we do 32 bit and 64 bit numbers.
 
Last edited:
A decimal number in .NET is represented by 128 bits, but only 96 bits are actually used.
A decimal consists of 3 integral sections of 4 bytes, the high, medium, and low, and a fourth section of 4 bytes for flags.
The 32 bits that are reserved for state information (flags), includes a flag for signing the interpreted value of the high, medium, and low bytes.
IIRC, depending on the amount of precision required, either the low and medium bytes, or the medium and high bytes, can be interpreted as 64-bit numbers, while the remaining bytes are interpreted as 32-bit numbers, meaning the left-side of the decimal place can be 32 or 64 bit and the right-side will be the remainder. (This would make sense as to why it can not be directly cast to other native data types)

Storing and interpreting primitive data types in memory should not be confused with floating-point CPU instructions.
Most -if not all- modern CPU's have a cache dedicated to processing floating point operations and that is where the bottle-neck is in this case.

Updating an enum from its default (Int32) to UInt32, can still be written and read as an Int32 - if the enum has a [Flags] attribute, the value will not be interpreted as signed.
When you update from Int32 to Int64, you need to store 4 more bytes of data, so you need to modify your Serialize/Deserialize methods to compensate, as they will be reading/writing Int32 values for the enum.
If you don't compensate, you will end up writing and reading inconsistent enum values.
It is recommended to update Serialization even if you're doing Int32 -> UInt32.
 
A decimal number in .NET is represented by 128 bits, but only 96 bits are actually used.
A decimal consists of 3 integral sections of 4 bytes, the high, medium, and low, and a fourth section of 4 bytes for flags.
The 32 bits that are reserved for state information (flags), includes a flag for signing the interpreted value of the high, medium, and low bytes.
IIRC, depending on the amount of precision required, either the low and medium bytes, or the medium and high bytes, can be interpreted as 64-bit numbers, while the remaining bytes are interpreted as 32-bit numbers, meaning the left-side of the decimal place can be 32 or 64 bit and the right-side will be the remainder. (This would make sense as to why it can not be directly cast to other native data types)

Storing and interpreting primitive data types in memory should not be confused with floating-point CPU instructions.
Most -if not all- modern CPU's have a cache dedicated to processing floating point operations and that is where the bottle-neck is in this case.

Updating an enum from its default (Int32) to UInt32, can still be written and read as an Int32 - if the enum has a [Flags] attribute, the value will not be interpreted as signed.
When you update from Int32 to Int64, you need to store 4 more bytes of data, so you need to modify your Serialize/Deserialize methods to compensate, as they will be reading/writing Int32 values for the enum.
If you don't compensate, you will end up writing and reading inconsistent enum values.
It is recommended to update Serialization even if you're doing Int32 -> UInt32.

Yeah I didn't really want to get into decimals and it's intricacies too much since it is really only needed in programs written for financial institutions as it offers the best accuracy when rounding. I just mentioned it since we were talking about the different sizes of numbers we have available to us. For our needs it would be not be recommended as we do not need numbers so large and would also slow down the method which incorporates it.
 
So if another is going to be added down the line, or for people like me with a custom script added to that list, how do we make 0x80000000 usable as well as those that come after?
I am sure the distro will encounter this sooner than later?
 
So if another is going to be added down the line, or for people like me with a custom script added to that list, how do we make 0x80000000 usable as well as those that come after?
I am sure the distro will encounter this sooner than later?

Like has been mentioned already, you either need to declare the enum as an unsigned integer or change it's datatype to a long.

Code:
publicenum PlayerFlag : uint
or
Code:
publicenum PlayerFlag : long

You will need to update existing mobiles in deserialisation too.
 
Like has been mentioned already, you either need to declare the enum as an unsigned integer or change it's datatype to a long.

Code:
publicenum PlayerFlag : uint
or
Code:
publicenum PlayerFlag : long

You will need to update existing mobiles in deserialisation too.
Before I say OH HOLY &*%^, do you mean on each one at the serialize/deserialize changing the int to uint:
Code:
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);

writer.Write((uint)0);
}

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

  uint version = reader.ReadUInt();

}
:eek:
 
Back