09-12-2003
- Added TAGs to CHARDEF/ITEMDEF sections. If a TAG does exists at an instance it overrides
  the def value.

10-12-2003, Kell
- Added OptionFlags to sphere.ini, to set multiple options. These will be named OF_
- Added OF_Magic_IgnoreAR = 0001, so that AR doesn't count to stop damage spells.
- Added ACTDIFF to characters to obtain the current action difficulty.
  Suggestion: One can use ACTDIFF to modify difficulty within skill Start triggers.
- Added a 6th parameter to the EFFECT command, the hue for the effect.
- Added @Effect trigger to spells, triggered after @SpellEffect
-  can now be used to assume "0" as the default value for a tag.
- TAG0.xxx = yyy can now be used, if yyy is 0, then no tag will be recorded (same as setting
  to a zero length string)
  Using TAG0, you can thus have tags that are only recorded if they are not 0. This is great
  for tags that are usually 0 and are often used (e.g. tags that must exist on all characters).
- Added VAR0 (same functionality as TAG0, but for VAR).

11-12-2003, Kell
- Added OF_Magic_CanHarmSelf = 0002, so that spells with SPELLFLAG_HARM will still affect the
  caster (useful for SPELLEFFECT in scripts)
- Changed rand(x) to allow a 2nd parameter rand(x,y) and return a random number between x and y,
  if y is present.

12-12-2003, Kell
- You can now use @color,font in SYSMESSAGE and MESSAGE. font ranges from 0 to 9, and I quote:
      FONT_BOLD,	// 0 - Bold Text = Large plain filled block letters.
      FONT_SHAD,	// 1 - Text with shadow = small gray
      FONT_BOLD_SHAD,	// 2 - Bold+Shadow = Large Gray block letters.
      FONT_NORMAL,	// 3 - Normal (default) = Filled block letters.
      FONT_GOTH,	// 4 - Gothic = Very large blue letters.
      FONT_ITAL,	// 5 - Italic Script
      FONT_SM_DARK,	// 6 - Small Dark Letters = small Blue
      FONT_COLOR,	// 7 - Colorful Font (Buggy?) = small Gray (hazy)
      FONT_RUNE,	// 8 - Rune font (Only use capital letters with this!)
      FONT_SM_LITE,	// 9 - Small Light Letters = small roman gray font.
- Changed SKILLMAKE to allow getting an individual resource in the list. SKILLMAKE.1 gets the first,
  SKILLMAKE.1.VAL gets the value and SKILLMAKE.1.KEY gets the associated resource key.

13-12-2003, Kell
- Added "RELEASE" to character verbs, does the same as "release" when spoke to a pet.
- Added @NPCFollow trigger, called when an NPC is following someone.

14-12-2003, Kell
- Changed ATTACK to accept as parameter the UID of the character to attack.
- Changed TRY to make no plevel or touch/distance checks. Use TRYP if you want those checks
  (TRYP 0 only checks for touch/distance, not plevel).
- Added an useful keyword to scripts, that allows one to use "OBJ" as pointer to an item. It's
  similar to ACT but it can be used anywhere. 
  Example:
     OBJ	= 
     SAY You are , with uid .
- Changed MEMORY to allow an UID as parameter, so you can now find the memory related to a specific
  UID. If no argument is used, it uses SRC's UID as usual. Also changed it to be read/write.
  Example:
     MEMORY  0200	// set memory 
     SAY Memory flag regarding  is >.

15-12-2003, Kell
- Changed @UserSkills so that  is the number of the skill being updated, or -1 for the skill
  list. This allows one to stop sending of skill updates to the client.
- NPCs will not say "Yes Master" if SPEECHPET is set in sphere.ini (you can script it in the speech
  triggers if you want them to). If SPEECHPET isn't set, they still won't say anything unless they
  can see their master (which is great for GMs). Players will no longer respond "Sorry".
- Resource gathering was changed so that the SKILLMAKE of the resource item is checked. Resources
  which fail the canmake check are ignored and aren't part of the randomization process. If for some
  reason one wants to go back to the old style, just comment SKILLMAKE on the ore itemdefs.
- @Step on items returning 1 will  now cancel movement to that area. Still, for coherence, all other items
  in that location are still activated.
- Added OF_Skill_DiffFirst = 0008. With this flag turned on, difficulty for a skill is calculated BEFORE
  calling @Start/@SkillStart. This has the advantage of allowing the difficulty for a skill to be changed
  via ACTDIFF within that trigger. Notice that for a skill to fail, ACTDIFF must be set above the current
  (modified) skill. Setting ACTDIFF to a negative value means that the skill will abort, that is, @Fail
  will not be called and no skill gain will be attempted. To always fail set ACTDIFF to a value above the
  possible skill (say, 1001).
  This has the sideffect of calling @SpellCast before @Start/@SkillStart. On the other hand, it is the
  ultimate tool for implementing your own skill difficulties.
  Here's an example of making the difficulty for arms lore AT LEAST the same value as for making the item
  (using the primary skill). Characters with skill above ACTDIFF will always succeed.
  ON = @Start
   if (  <  )
      SRC.ACTDIFF	= 
   endif

16-12-2003, Kell
- You can now use NEWITEM, NEWNPC and NEWDUPE in item scripts, the items will be created into "NEW". Using
  these commands on a character will create the items in both NEW and ACT. If you want to use these
  on a character without changing ACT, use SERV.NEWITEM, etc.
  Example:
    NEWITEM i_gold
    NEW.AMOUNT 100
    NEW.P	= 
  You can also use NEW as a temporary handler, much like you can use OBJ (and to an extenct, ACT).

17-12-2003, Kell
- Functions can now receive "args" when being evaluated, as in 
- Added RANGE=min,max or RANGE=max (min defaults to 0) for ITEMDEF and CHARDEF. Default weapon range
  is 1. Default character range is 1. Range is calculated as (character + weapon -1). 
  Example: Assuming all characters are RANGE=1 (which they are), putting RANGE=2 in an halberd
  means characters equipping it can hit 1 square further.

18-12-2003, Kell
- The main section for DIALOGs is now fully interpreted like other scripts, allowing you to add logic
  to your dialog, use IFs, etc. The only limitation at the moment is that gump commands are only 
  allowed right in the DIALOG section, and not within FUNCTIONs, but hei... it's better. :)
- Dialogs will no longer conflict with each other, this allows for permanent on-screen dialogs. INPDLG
  works too, seeing as there can be only one INPDLG window onscreen at all times.
- Added RESOURCES.n, RESOURCES.n.KEY and RESOURCES.n.VAL to items/characters.

19-12-2003, Kell
- To make writing dialogs easier, added a cursor and relative coordinates:
     dorigin 50 50	// sets the origin to x=50, y=50
  Using "*" near a coordinate makes it relative to the origin, and displaces the origin by some amount:
     dtext     *0    *10    0    the origin is now x=50 y=60, so is the last location
  Using "+" near a coordinate makes it relative to the last location w/o changing the origin.
     dtext     +10     -    0    adds 10 to X (y=150, o.y=100)
  As an example, imagine writing a list of text with 3 columns, each seperated via 200 x and 20 space
  between each row:
  dorigin 10 10
  // first row
  dtext     *0   -    5   1:
    dtext  +10   -    0   the text for row1, col1
  dtext   *200   -    5   2:		// x orig = 200
    dtext  +10   -    0   the text for row1, col2
  dtext   *200   -    5   3:		// x orig = 400
    dtext  +10   -    0   the text for row1, col2

  And now one only has to go down one row. and the text is quite similar. This isn't too easy to explain, it's
  there for whomever might find it useful. If you can't think of a use for it, just ignore it. ;)
- Fixed the bug with FORCHARS/ITEMS/OBJS and keywords starting with "FOR" (like FORensics).
- Changed textadd and gumptext to collapse equal strings of text to the same index. So if you use
    gumptext 10 20  This is an example.
    gumptext 10 40  This is an example.
    gumptext 10 60  This is an example.
  It will only generate ONE text id. This does away with the need to have a seperate TEXT section. Granted,
  such a section is still useful for keeping strings all in one place (in this case it'd be useful), but it
  is no longer mandatory, it becomes simply a matter of style/choice.

20-12-2003, Kell
- Equal PLEVEL should be able to see each other, so they are now.
- You can now open a dialog in a specific page, with DIALOG  d_dialog_name  pagenumber. This isn't actually
  possible with the UO client - what it does is recalculate the dialog page/button numbers so that the selected
  page is first. It's completly invisible though, and works perfectly.
- Added a new command - DTEXT - to gumps, which does the handling of text ids for you (d stands for dynamic):
     dtext x y color  Actual text comes here.
  Text added with gumptext is actually added to the [DIALOG ... TEXT] section. If you're only using a given
  text string once, then it's actually faster using this than using "text" and adding it to the TEXT section
  of the dialog. Simmilar commands, DCROPPEDTEXT and DTEXTENTRY are also in, also taking text instead of an
  index. DHTMLGUMP is also in, but notice that the syntax is like HTMLGUMP, except that you ommit the ID and add
  the text in the end.
  With these changes, you can completly ommit the [DIALOG ... TEXT] section of dialogs. Only those strings
  that are commonly used throughout the dialog should you put in the [DIALOG ... TEXT] section.
  Internally, both gumptext and textadd simply add stuff to the dialog as needed, and send normal "text"
  commands to the client, so they're safe to use. But they free you from having to keep track of a LONG
  list of numbers, and allow you to shape and modify your dialog w/o bothering with text ids.
- You can now use FUNCTIONs that issue gump commands. So you actually make your own gump commands!!! Death to
  copy & paste dialogs!

21-12-2003, Kell
- Fixed a bug in that setting stats & skills via scripts wouldn't correctly parse things. For instance, numerical
  expressions.
- Started work on MANUAL.TXT, to detail the current state of things like triggers and their arguments, seeing as
  reading this changelog is probably a difficult task for a lot of people.
- Changed args in functions to be writeable. This is useful in scripts, but for triggers, the server will read
  back the values and use the new ones wherever it makes sense. For the time being, these triggers were
  changed:
     @GetHit, ARGN1 is the damage being apllied, ARGN2 the damage type (as usual, but now writeable). 
     @Hit, ARGN1 is now the raw damage being applied, prior to armour (writeable). ARGO is the weapon (if any).
     @PersonalSpace, ARGN1 is the stamina required to move (writeable). "return 1" stops the movement, "return 0"
     allows the movement but shows none of the hard-coded messages. Plain "return" or no return, works as standard.
  @Hit, @HitTry and @HitMiss were also changed so that ARGO is the weapon being used (handy so you don't have to
  be looking at layers n stuff).
  I should add that ACTDIFF is also available, and it can be used to change the difficulty of a skill, even make
  a skill succedd that would otherwise fail (by setting it to 0). It can also be used in @HitTry now, and if
  set to any non-negative value, a missing hit will instead succeed.
- Added StrEat function, which removes a word up to the space, from a string (
  or  return "there friend")
- Added  which returns the skill number for some text or -1 if not found.
- After some beta-testing, a few fixes to dialogs.
- LOCAL.xxx within functions for LOCAL . They're a bit more efficient on servers with lots of global
  vars due to faster lookups ). LOCAL variables always come up initially as "0".
- ARGN1, ARGN2 and ARGN3 are set for functions with numeric arguments. So whenever possible, use these instead
  of argv. Example: "myfunction  123 50 89" - these 3 values will be parsed into argn1, argn2 and argn3

22-12-2003, Kell
- Functions can now return strings using "return". Notice that this behaves like TAGs, in that if you do
     return 2+2
  then "2+2" is returned, and not "4". You'll have to explicitly call "eval" on what you want
  to return:
     return 
  Returning strings causes no extra lag, seeing as the old method of returning a value relied on the same
  string which is returned (EVALed). So it is actually faster (although hardly noticeable).
  This might pose a problem problem if you have "return rand" or similar, instead of "return . Shows no error in the console
		if static isn't present, returning 0 - useful to test for a static w/o counting or looping.
    STATICS.n	  same
    STATICS(n).key	Get a key from the appropriate ITEMDEF. eg: 

- Added basic iterator construct, WHILE, with the following syntax:
     WHILE ( condition )
	// do stuff, current iteration number in 
     END // or ENDWHILE

  also added FOR, terminated with either END or ENDFOR, with the following syntax:

     FOR 5	// loops from 0 to 5, current iteration number in LOCAL._FOR
  or FOR 3 5	// loops from 3 to 5, current iteration number in LOCAL._FOR
  or FOR K 5	// loops from 0 to 5, current iteration number in LOCAL.K
  or FOR K 3 5	// loops from 3 to 5, current iteration number in LOCAL.K
	// do stuff
     END  // or ENDFOR

  Changing these LOCAL variables has no effect on the loop.
- Wrote a small assembly function to access the high resolution timer. Works for both windows and Linux,
  now being used in profiling. Profiling works on Linux now. It also looks a lot better in the console
  thanks to the monospaced font.
- Changed the console font under Windows to Courier, which is monospaced, so things come out aligned in
  the console. Under Linux, the console is naturally monospaced.
- You can now add new SKILL sections, up to 70. SERV.MAXSKILL tells you how many skills are loaded. Notice
  that they won't be sent to the client though, the client doesn't support them (hint: @UserSkills). There
  is also a FLAGS key for SKILL section, with the following values:
     [DEFNAME skill_defs]
     SKF_SCRIPTED	01	// no hardcoded behaviour, only triggers are called.
     // feel free to add new tags you find useful, but only above 01000 please, to make room for future
     expansion
  This is heavily experimental, mess with it at your own risk.
- SKILLSELECT skill - force a button select event on the skill list

24-12-2003, Kell
- Fixed TYPEDEFS section in spherefs.scp loosing values when resynced.
- Added , takes a direction as argument (like WALK), returns the area ID we're moving to,
  or 0 if no move is possible.
- Added , takes a direction as argument (like WALK), returns the TILE flags for that position.
  Notice that flag 04 is walkable. Here's a list of flags, you can copy&paste it into spheredefs.scp. This
  keyword might change in the future.


[DEFNAME tile_flags]			// by Shadowlord
tilef_background	01		// No idea. None whatsoever. Maybe it's the blackness.
tilef_weapon		02		// I smack thee with this here ... club?
tilef_transparent	04		// Yeah. So we can see through it?
tilef_translucent	08		// Okay...
tilef_wall		010		// Hey look, we can't walk through it!
tilef_damaging		020		// Lava, perhaps? Fires, hmm!
tilef_impassable	040		// Mountains and stuff, I'll wager.
tilef_wet		080		// Water? Or mud? Or a slick road in a rainstorm? Probably the first.
tilef_unknown		0100		// Uh...
tilef_surface		0200		// Tables or something?
tilef_bridge		0400		// I wonder why they'd have a flag for that.
tilef_stackable		0800	
tilef_window		01000		// So we can see/shoot out?
tilef_noshoot		02000		// ? We can't shoot out or something? So, like a glass window maybe?
tilef_prefixA		04000		// A card
tilef_prefixAn		08000		// An apple
tilef_internal		010000		// hair, beards, etc
tilef_foliage		020000		// Probably bushes and tree leaves and stuff.
tilef_partialHue	040000		// semi-glowy?
tilef_unknown_1		080000		// Well, gee. I should see if it's used on anything...
tilef_map		0100000		// Sounds good to me.
tilef_container		0200000		// They flag these!?
tilef_wearable		0400000		// Omigod!
tilef_lightSource	0800000		// I'm getting tired of typing repetitive shiznit now.
tilef_animated		01000000	// Like fire again. And stuff. Those spinny propeller thingies!
tilef_noDiagonal	02000000	// !?!???!!?
tilef_unknown_2		04000000	// I really hope some of these unknowns are n/w/s/e facing flags.
tilef_armor		08000000	// Armor, okay, so does that count shields? Hmmm?
tilef_roof		010000000	// "Don't fall through me!" Or why isn't it just flagged surface or something?
tilef_door		020000000	// Okay...
tilef_stairBack		040000000	// Don't we have stairs that go forward or left too? This could cover both...
tilef_stairRight	080000000	// Well, whatever, you can climb them, so, hey... Good use for a 

NOTE :	EF flags change from version to version, so make SURE you're using only the EF
	flags you want, if any.

SUMMARY of flags for Sphere.ini:
OptionFlags=	// Flags for options that affect server behaviour but not compatibility
	0001		// OF_Magic_IgnoreAR
	0002		// OF_Magic_CanHarmSelf
	0004		// OF_Magic_StackStats			(Do NOT set this yet)
	0008		// OF_Skill_DiffFirst
	0010		// OF_Archery_CanMove
	0020		// OF_Magic_PreCast

Experimental=	// Flags for options that affect server behaviour and which might affect compatibility
	0001		// EF_XCMD_Spy
	0002		// EF_UNICODE
	0004		// EF_CanSeeLOS
	0008		// EF_ReturnString
	Suggested value: EXPERIMENTAL=01

01-12-2003, Kell
- Added @EquipTest and @ItemEquipTest (return 1 cancels equiping).
- Changed @SkillItemMake so that "return 1" only deletes the item if it's container hasn't
  been set.
- Fixed bug with skills apparently not finishing (also fixes cartography).
- Fixed summoning bug (Linux only). This has to do with doing propper memory initialization
  prior to using points.
- Removed all specific handling for SERV.xxx(y).zzz and made it generic. You can now use
  either syntax: SERV.xxx(y).zzz or SERV.xxx.y.zzz.
- Changed default release options for speed optimization.

02-12-2003, Kell
- Fixed REAPAMOUNT / AMOUNT. It can now take multi-point values in a format similar to
  ADVANCE for skills.
- Added SPEECHSELF= to sphere.ini, to allow setting the name of the speech trigger that
  should be called to intercept player speech. Suggested: SPEECHSELF=spk_player
  "return 1" in said trigger stops the player from actually talking.
- Removed hard coded "home home home" - one can just use the default spk_player speech if
  that feature is desired (but mostly it's not)
- Added SPEECHPET= to sphere.ini, to allow setting the name of the speech trigger that
  is called when a pet listens to its master. "return 1" in said trigger stops the pet
  from listenning.

09-12-2003
- Added TAGs to CHARDEF/ITEMDEF sections. If a TAG does exists at an instance it overrides
  the def value.

10-12-2003, Kell
- Added OptionFlags to sphere.ini, to set multiple options. These will be named OF_
- Added OF_Magic_IgnoreAR = 0001, so that AR doesn't count to stop damage spells.
- Added ACTDIFF to characters to obtain the current action difficulty.
  Suggestion: One can use ACTDIFF to modify difficulty within skill Start triggers.
- Added @Effect trigger to spells, triggered after @SpellEffect
-  can now be used to assume "0" as the default value for a tag.
- TAG0.xxx = yyy can now be used, if yyy is 0, then no tag will be recorded (same as setting
  to a zero length string)
  Using TAG0, you can thus have tags that are only recorded if they are not 0. This is great
  for tags that are usually 0 and are often used (e.g. tags that must exist on all characters).
- Added VAR0 (same functionality as TAG0, but for VAR).

11-12-2003, Kell
- Added OF_Magic_CanHarmSelf = 0002, so that spells with SPELLFLAG_HARM will still affect the
  caster (useful for SPELLEFFECT in scripts)
- Changed rand(x) to allow a 2nd parameter rand(x,y) and return a random number between x and y,
  if y is present.

12-12-2003, Kell
- You can now use @color,font in SYSMESSAGE and MESSAGE. font ranges from 0 to 9, and I quote:
      FONT_BOLD,	// 0 - Bold Text = Large plain filled block letters.
      FONT_SHAD,	// 1 - Text with shadow = small gray
      FONT_BOLD_SHAD,	// 2 - Bold+Shadow = Large Gray block letters.
      FONT_NORMAL,	// 3 - Normal (default) = Filled block letters.
      FONT_GOTH,	// 4 - Gothic = Very large blue letters.
      FONT_ITAL,	// 5 - Italic Script
      FONT_SM_DARK,	// 6 - Small Dark Letters = small Blue
      FONT_COLOR,	// 7 - Colorful Font (Buggy?) = small Gray (hazy)
      FONT_RUNE,	// 8 - Rune font (Only use capital letters with this!)
      FONT_SM_LITE,	// 9 - Small Light Letters = small roman gray font.
- Changed SKILLMAKE to allow getting an individual resource in the list. SKILLMAKE.1 gets the first,
  SKILLMAKE.1.VAL gets the value and SKILLMAKE.1.KEY gets the associated resource key.

13-12-2003, Kell
- Added "RELEASE" to character verbs, does the same as "release" when spoke to a pet.
- Added @NPCFollow trigger, called when an NPC is following someone.

14-12-2003, Kell
- Changed ATTACK to accept as parameter the UID of the character to attack.
- Changed TRY to make no plevel or touch/distance checks. Use TRYP if you want those checks
  (TRYP 0 only checks for touch/distance, not plevel).
- Added an useful keyword to scripts, that allows one to use "OBJ" as pointer to an item. It's
  similar to ACT but it can be used anywhere. 
  Example:
     OBJ	= 
     SAY You are , with uid .
- Changed MEMORY to allow an UID as parameter, so you can now find the memory related to a specific
  UID. If no argument is used, it uses SRC's UID as usual. Also changed it to be read/write.
  Example:
     MEMORY  0200	// set memory 
     SAY Memory flag regarding  is >.

15-12-2003, Kell
- Changed @UserSkills so that  is the number of the skill being updated, or -1 for the skill
  list. This allows one to stop sending of skill updates to the client.
- NPCs will not say "Yes Master" if SPEECHPET is set in sphere.ini (you can script it in the speech
  triggers if you want them to). If SPEECHPET isn't set, they still won't say anything unless they
  can see their master (which is great for GMs). Players will no longer respond "Sorry".
- Resource gathering was changed so that the SKILLMAKE of the resource item is checked. Resources
  which fail the canmake check are ignored and aren't part of the randomization process. If for some
  reason one wants to go back to the old style, just comment SKILLMAKE on the ore itemdefs.
- @Step on items returning 1 will  now cancel movement to that area. Still, for coherence, all other items
  in that location are still activated.
- Added OF_Skill_DiffFirst = 0008. With this flag turned on, difficulty for a skill is calculated BEFORE
  calling @Start/@SkillStart. This has the advantage of allowing the difficulty for a skill to be changed
  via ACTDIFF within that trigger. Notice that for a skill to fail, ACTDIFF must be set above the current
  (modified) skill. Setting ACTDIFF to a negative value means that the skill will abort, that is, @Fail
  will not be called and no skill gain will be attempted. To always fail set ACTDIFF to a value above the
  possible skill (say, 1001).
  This has the sideffect of calling @SpellCast before @Start/@SkillStart. On the other hand, it is the
  ultimate tool for implementing your own skill difficulties.
  Here's an example of making the difficulty for arms lore AT LEAST the same value as for making the item
  (using the primary skill). Characters with skill above ACTDIFF will always succeed.
  ON = @Start
   if (  <  )
      SRC.ACTDIFF	= 
   endif

16-12-2003, Kell
- You can now use NEWITEM, NEWNPC and NEWDUPE in item scripts, the items will be created into "NEW". Using
  these commands on a character will create the items in both NEW and ACT. If you want to use these
  on a character without changing ACT, use SERV.NEWITEM, etc.
  Example:
    NEWITEM i_gold
    NEW.AMOUNT 100
    NEW.P	= 
  You can also use NEW as a temporary handler, much like you can use OBJ (and to an extenct, ACT).

17-12-2003, Kell
- Functions can now receive "args" when being evaluated, as in 
- Added RANGE=min,max or RANGE=max (min defaults to 0) for ITEMDEF and CHARDEF. Default weapon range
  is 1. Default character range is 1. Range is calculated as (character + weapon -1). 
  Example: Assuming all characters are RANGE=1 (which they are), putting RANGE=2 in an halberd
  means characters equipping it can hit 1 square further.

18-12-2003, Kell
- The main section for DIALOGs is now fully interpreted like other scripts, allowing you to add logic
  to your dialog, use IFs, etc. The only limitation at the moment is that gump commands are only 
  allowed right in the DIALOG section, and not within FUNCTIONs, but hei... it's better. :)
- Dialogs will no longer conflict with each other, this allows for permanent on-screen dialogs. INPDLG
  works too, seeing as there can be only one INPDLG window onscreen at all times.
- Added RESOURCES.n, RESOURCES.n.KEY and RESOURCES.n.VAL to items/characters.

19-12-2003, Kell
- To make writing dialogs easier, added a cursor and relative coordinates:
     dorigin 50 50	// sets the origin to x=50, y=50
  Using "*" near a coordinate makes it relative to the origin, and displaces the origin by some amount:
     dtext     *0    *10    0    the origin is now x=50 y=60, so is the last location
  Using "+" near a coordinate makes it relative to the last location w/o changing the origin.
     dtext     +10     -    0    adds 10 to X (y=150, o.y=100)
  As an example, imagine writing a list of text with 3 columns, each seperated via 200 x and 20 space
  between each row:
  dorigin 10 10
  // first row
  dtext     *0   -    5   1:
    dtext  +10   -    0   the text for row1, col1
  dtext   *200   -    5   2:		// x orig = 200
    dtext  +10   -    0   the text for row1, col2
  dtext   *200   -    5   3:		// x orig = 400
    dtext  +10   -    0   the text for row1, col2

  And now one only has to go down one row. and the text is quite similar. This isn't too easy to explain, it's
  there for whomever might find it useful. If you can't think of a use for it, just ignore it. ;)
- Fixed the bug with FORCHARS/ITEMS/OBJS and keywords starting with "FOR" (like FORensics).
- Changed textadd and gumptext to collapse equal strings of text to the same index. So if you use
    gumptext 10 20  This is an example.
    gumptext 10 40  This is an example.
    gumptext 10 60  This is an example.
  It will only generate ONE text id. This does away with the need to have a seperate TEXT section. Granted,
  such a section is still useful for keeping strings all in one place (in this case it'd be useful), but it
  is no longer mandatory, it becomes simply a matter of style/choice.

20-12-2003, Kell
- Equal PLEVEL should be able to see each other, so they are now.
- You can now open a dialog in a specific page, with DIALOG  d_dialog_name  pagenumber. This isn't actually
  possible with the UO client - what it does is recalculate the dialog page/button numbers so that the selected
  page is first. It's completly invisible though, and works perfectly.
- Added a new command - DTEXT - to gumps, which does the handling of text ids for you (d stands for dynamic):
     dtext x y color  Actual text comes here.
  Text added with gumptext is actually added to the [DIALOG ... TEXT] section. If you're only using a given
  text string once, then it's actually faster using this than using "text" and adding it to the TEXT section
  of the dialog. Simmilar commands, DCROPPEDTEXT and DTEXTENTRY are also in, also taking text instead of an
  index. DHTMLGUMP is also in, but notice that the syntax is like HTMLGUMP, except that you ommit the ID and add
  the text in the end.
  With these changes, you can completly ommit the [DIALOG ... TEXT] section of dialogs. Only those strings
  that are commonly used throughout the dialog should you put in the [DIALOG ... TEXT] section.
  Internally, both gumptext and textadd simply add stuff to the dialog as needed, and send normal "text"
  commands to the client, so they're safe to use. But they free you from having to keep track of a LONG
  list of numbers, and allow you to shape and modify your dialog w/o bothering with text ids.
- You can now use FUNCTIONs that issue gump commands. So you actually make your own gump commands!!! Death to
  copy & paste dialogs!

21-12-2003, Kell
- Fixed a bug in that setting stats & skills via scripts wouldn't correctly parse things. For instance, numerical
  expressions.
- Started work on MANUAL.TXT, to detail the current state of things like triggers and their arguments, seeing as
  reading this changelog is probably a difficult task for a lot of people.
- Changed args in functions to be writeable. This is useful in scripts, but for triggers, the server will read
  back the values and use the new ones wherever it makes sense. For the time being, these triggers were
  changed:
     @GetHit, ARGN1 is the damage being apllied, ARGN2 the damage type (as usual, but now writeable). 
     @Hit, ARGN1 is now the raw damage being applied, prior to armour (writeable). ARGO is the weapon (if any).
     @PersonalSpace, ARGN1 is the stamina required to move (writeable). "return 1" stops the movement, "return 0"
     allows the movement but shows none of the hard-coded messages. Plain "return" or no return, works as standard.
  @Hit, @HitTry and @HitMiss were also changed so that ARGO is the weapon being used (handy so you don't have to
  be looking at layers n stuff).
  I should add that ACTDIFF is also available, and it can be used to change the difficulty of a skill, even make
  a skill succedd that would otherwise fail (by setting it to 0). It can also be used in @HitTry now, and if
  set to any non-negative value, a missing hit will instead succeed.
- Added StrEat function, which removes a word up to the space, from a string (
  or  return "there friend")
- Added  which returns the skill number for some text or -1 if not found.
- After some beta-testing, a few fixes to dialogs.
- LOCAL.xxx within functions for LOCAL . They're a bit more efficient on servers with lots of global
  vars due to faster lookups ). LOCAL variables always come up initially as "0".
- ARGN1, ARGN2 and ARGN3 are set for functions with numeric arguments. So whenever possible, use these instead
  of argv. Example: "myfunction  123 50 89" - these 3 values will be parsed into argn1, argn2 and argn3

22-12-2003, Kell
- Functions can now return strings using "return". Notice that this behaves like TAGs, in that if you do
     return 2+2
  then "2+2" is returned, and not "4". You'll have to explicitly call "eval" on what you want
  to return:
     return 
  Returning strings causes no extra lag, seeing as the old method of returning a value relied on the same
  string which is returned (EVALed). So it is actually faster (although hardly noticeable).
  This might pose a problem problem if you have "return rand" or similar, instead of "return . Shows no error in the console
		if static isn't present, returning 0 - useful to test for a static w/o counting or looping.
    STATICS.n	  same
    STATICS(n).key	Get a key from the appropriate ITEMDEF. eg: 

- Added basic iterator construct, WHILE, with the following syntax:
     WHILE ( condition )
	// do stuff, current iteration number in 
     END // or ENDWHILE

  also added FOR, terminated with either END or ENDFOR, with the following syntax:

     FOR 5	// loops from 0 to 5, current iteration number in LOCAL._FOR
  or FOR 3 5	// loops from 3 to 5, current iteration number in LOCAL._FOR
  or FOR K 5	// loops from 0 to 5, current iteration number in LOCAL.K
  or FOR K 3 5	// loops from 3 to 5, current iteration number in LOCAL.K
	// do stuff
     END  // or ENDFOR

  Changing these LOCAL variables has no effect on the loop.
- Wrote a small assembly function to access the high resolution timer. Works for both windows and Linux,
  now being used in profiling. Profiling works on Linux now. It also looks a lot better in the console
  thanks to the monospaced font.
- Changed the console font under Windows to Courier, which is monospaced, so things come out aligned in
  the console. Under Linux, the console is naturally monospaced.
- You can now add new SKILL sections, up to 70. SERV.MAXSKILL tells you how many skills are loaded. Notice
  that they won't be sent to the client though, the client doesn't support them (hint: @UserSkills). There
  is also a FLAGS key for SKILL section, with the following values:
     [DEFNAME skill_defs]
     SKF_SCRIPTED	01	// no hardcoded behaviour, only triggers are called.
     // feel free to add new tags you find useful, but only above 01000 please, to make room for future
     expansion
  This is heavily experimental, mess with it at your own risk.
- SKILLSELECT skill - force a button select event on the skill list

24-12-2003, Kell
- Fixed TYPEDEFS section in spherefs.scp loosing values when resynced.
- Added , takes a direction as argument (like WALK), returns the area ID we're moving to,
  or 0 if no move is possible.
- Added , takes a direction as argument (like WALK), returns the TILE flags for that position.
  Notice that flag 04 is walkable. Here's a list of flags, you can copy&paste it into spheredefs.scp. This
  keyword might change in the future.
- It's Xmas! So I'm off to eat some turkey for the next 48 hours. :) Does this count as an entry in the
  changelog?

27-12-2003, Kell
- Added support for color & render mode in EFFECT. If no color or render effect are specified, old
  effect packet is still sent (which spares 8 bytes). Otherwise the new packet type is sent. Tested
  and works with clients from 2.0.3 (should work on all 2.0.* series).
- Consolidated support for 3.0.* clients, they should work fine, up to LBR (they already worked, just
  spitted some error messages).
- Added modulus (%) operator in numerical expressions (eg: 12 % 3 == 0).
- Added SENDPACKET command for clients. To make it easier to send WORD(2 bytes) and DWORD(4 bytes) values, 
  allowed for 'W' and 'D' prefix to values ('B' is also supported for byte but it's redundant). Here's an
  example, of setting light level:
     SRC.SENDPACKET   04e  D  20
  Both 04e and 20 could use the prefix B, but notice how  uses the prefix D to specify it takes
  the space of a DWORD (4 bytes). So much for complex scripts to break multi-byte stuff in bytes :p
  Notice also that each of the parameters is evaluated and truncated, and only then used. For instance,
  if you put 0fffffffe (which obviously isn't a byte) in place of a BYTE, what you'll get is effectively
  0fe. If you put (2+2) it'll be evaluated to "4" before being used.

28-12-2003, Kell
- Added OSTR, ODEX, OINT.
- Added MODSTR, MODDEX, MODINT - spells affect these.
- STR, DEX and INT are always equal to O + MOD (for the relevant stat). If you have OSTR=50, MODSTR=0 and
  then do STR=60, you will get MODSTR=10 (and OSTR unchanged). 
  *** CHANGED *** read the entry for 19-01-2004
- Added MAXHITS/MAXMANA/MAXSTAM. If set to 0, it defaults to the base max stat (eg, MAXSTR defaults to STR).
  MAX always contains MOD for the appropriate stat. That is to say that if you have MAXHITS=100 and MODSTR=10
  then internally it'll be recorded as MAXHITS being 90, and if MODSTR changes, so does MAXHITS. This makes
  it coherent for stat spells, seeing as they not only change your stats but also max hits/stam/mana.
  To make hits depend on STR again, use
     MAXHITS =	// don't use a value
- You can now write TAGs on accounts. Both TAG and TAG0 are available.
- LOCAL._WHILE fixed, within WHILE loops.
- Changed dialog BUTTON sections to allow 
     ON = min max
  to grab any button with buttonID between min and max (including). Also, argn1 is the buttonID that
  actually got selected (even when specify just a buttonID and not a range, as usual). With the buttonID
  in argn1 you can write more generic functions with little fuss.

29-12-2003, Kell
- Fixed some skills not getting currectly terminated when another skill was used before they finished. An
  example of this is Spells not fizzling when a skill was used before spell ended.
- For skills, @Fail is now only triggered when failure occured due to normal circumstances (eg, failed
  difficulty). @Abort is called when failure occurs due to a situation that aborts the skill, such as
  using a new skill before finishing the previous one or an invalid circumstance.
  If @Fail is triggered, it means that the character will still get a skillcheck for failure (skill raise
  through failure), but if you do a "return 1" in there, it won't (check MANUAL.TXT).
- Started implementing propper behaviour for EF_CanSeeLOS. At the moment, it'll check the height of static
  items in the path to the target.
- The use of "SECTOR" to access keywords related to sector is now mandatory. So, to access "light" or
  "rainchance", SRC.RAINCHANCE used to work, you must do SRC.SECTOR.RAINCHANCE. This has several
  advantages - people usually already use SECTOR anyway, so this makes for faster faster execution of
  commands on characters, seeing as it has less things to try. It is also more coherent.

30-12-2003, Kell
- Fixed a small problem with KARMA/FAME that had the huge effect of blocking the client once it got different
  than 0.
- Added FEATURES= to sphere.ini, to define the features the server will enable on the clients upon connection:
   0001 - (T2A) enables chatbutton
   0002 - (LBR) enables LBR sound (plays MP3s instead of MIDI)
   0004 - (T2A) enables T2A update
   0008 - (LBR) enables LBR update (shows monsters)
  Standard .55i automatically enabled 0001 - but you could disable it.
- DIALOGCLOSE command. First argument is the dialog name, second argument is the button that should be
  triggered on the dialog - 0 if not specified. (eg: DIALOGCLOSE d_my_dialog).
  You can put this as one of the first commands in a DIALOG section, to ensure there is only one dialog of
  that type on the client.

02-01-2004, Kell
- Added connection control keywords to sphere.ini - a value of 0 disables
  any of these settings. These settings are not dumb proof. Make sure you
  know what you're doing if you set these:
  * ConnectingMax=x, where x is the maximum number of clients that can coexist
      in non-game state (http, login, etc). Older clients that are not ingame
      get disconnected when new ones come in. Default: 24
  * ConnectingMaxIP=x, as above, but per IP. Only a maximum of x simultaneous
      "not in game" connections will be allowed per IP. Notice that HTTP
      requests for instance, count as "not in game". Default: 8
  * ClientMaxIP=x, maximum number of connections per IP. This is intended to
      stop flooders, DO NOT SET THIS TOO LOW, or you risk looking stupid. There
      are MANY situations where connections can appear as comming from the same
      IP - a common one is people connecting from cybercaffes. Default: 0
- Fixed a serious bug where login errors (Bad Login) could leave a lingering
  socket. This happened because sockets were made invalid so that they'd get
  closed on the next read cycle, therefore losing all information about the
  socket. Clients are now flagged for disconnection, and socket handling is
  done when clients are freed.
  This means that there should always be a "disconnected" message to pair
  with a "connected" message.
- You will see two numbers after the IP in connected/disconnected messages.
  The first is the number of connections from that IP which are not in-game,
  whereas the second is the total number of connections from that IP.
- In savefiles, OSTR and MODSTR are now saved instead of STR. If "STR" is found,
  it'll be interpreted as OSTR. This works fine to convert old worldfiles, even
 if you have spells, because once they wear off they'll simply make your MODSTR
  negative. This works for all stats obviously (simply using STR as an example).
- Changed it so that the first time you set a stat on an NPC, if the Ostat is 0,
  it'll update Ostat not MODstat. In other words, and as an example, if you do
  STR=20 in @Create, you'll end up with OSTR=20 and MODSTR=0. If you then do
  STR=30 on the same NPC, you'll end up with OSTR=20 and MODSTR=10. 
  **** changed **** see the entry for 19-01-2003
- Fixed a small problem from R3.13 with stat affecting spells not setting MODstat
  correctly.

03-01-2004, Kell
- Added unary operators "*=", "+=", "-=", "/=", "%=", "|=", "&=" and "!=". Internally,
  what these actually do is change a line in the format:
    XXX += YYY
  to
    XXX =  + (YYY))>
  So you can do stuff like
    MANA	+= 10/2			// same as MANA =  + (10/2))>
    ATTR	&= ~attr_magic		// same as ATTR =  & (~attr_magic))>
- Added ".=" operator, to do string concatenation. Internally what it does is change a line
  in the format
    XXX .= YYY
  to
    XXX = YYY
  This is intended to be used with things that can support strings (NAME, TITLE, VAR, LOCAL, etc)
- First attempt to implement propper LOS check counting with z. To have LOS, you must be
  able to walk in a straight line to the target (no news here) AND finish at a reasonable
  height, climbing your way to it. So, if you're on a slope you might have LOS, but if
  you're standing one floor below you won't. These extra texts have no measurable impact on
  performance Enable this behaviour with EF_CanSeeLos (04).
- Diagonal walking (eg, NW) is allowed only if the character can move ortogonally in both
  directions (NW -> N and W). This takes care of a few clientside exploits, as well as NPCs
  walking through corners. Enable this behaviour with EF_DiagonalWalkCheck (010)
- For the effect of stepping on them, all items were considered to have a height of 3. If you
  standed higher than 3 above an item, you wouldn't trigger a step on it. Changed it so that
  if the item's height is above 3, that value is used, and not the hardcoded "3". This allows
  one to get @Step events on stuff like tables.
- If no SRC is defined at the time of a @SpellEffect trigger, then the character subject to the
  spell will be considered the SRC. This fixes SPELLEFFECT under @Timer triggers.
- Added @NPCLookAtChar and @NPCLookAtItem triggers (check the manual). Do not abuse of these
  triggers, as they will affect the CPU usage.

04-01-2004, Kell
- Added ISNEARTYPE, first argument is type, 2nd argument is max distance to search ( if not
  specified, 4 is the default ). Also added ISNEARTYPE.P, which returns "0" if false or the
  point coordinates if true.
- Changed DISTANCE to accept the UID of an object (item/char) to compare the distance, or a
  point. One can now write things like
     >    >
  If no argument is supplied, then SRC.UID is used (as default). If the point/UID is invalid
  an error is printed to the console.
- Made TIMERD readable (its precision is 10x that of TIMER, same scale of SERV.TIME).
- Made USEITEM not check for visibility. The whole purpose of this keyword is to allow
  activating an item via scripts w/o testing for touch, so it doesn't make sense to test
  if the item can be seen. DCLICK performs the usual tests though. The "USE" keyword already
  allowed one to do "USE 0" not to test for touch, but it also tested for visibility, and it
  won't anymore if used like "USE 0".
- Spawns gems now instantly update the display as soon as you set MORE1.
- Double clicking an already negated (more2=0) character spawn sets its timer to 1 so it
  respawns next turn.
- Added MOVENEAR keyword for objects(items/chars). 1st argument is the UID of item to move
  near to, 2nd argument is the distance to the item. If 3rd argument is present and "0",
  then the item will not send an Update. Example:
     ON = @DClick
        MOVENEAR  5	// move to 5 steps away from SRC
  Notice that this movement respects walls & such (which is why it is useful).
- Set ARGN1=1 in @Login not to show MOTD scroll.

05-01-2004, Kell
- Fixed possible exploit with \n and textentry and inpdlg.
- AREA and ROOM sections in the following format
     [AREA name here]
  Should now be written as
     [AREADEF a_some_def]	// ROOMDEF for rooms
     NAME=name here
  The advantage of this format is that you can resync it w/o having conflicting regions.
  Suggestions:	Keep your areas in different formats in seperate files. Either find a script
		to convert your old format to the new one or slowly convert by hand.
		Move [Teleporters] and [Moongates] to their own files (these can't be resynced).
  Note:		You do NOT have to use the new format. It is, however, strongly suggested, as
		it allows you to change an area without rebooting.
		Any future ability to save things on regions will only be available for regions
		in the new format (or regions that have a DEFNAME).
- Added CALL instruction to invoke a function, but sharing the LOCAL variables with the called
  function. Quite useful when you want to break a function in small pieces that are logically
  yet not functionally seperate. In other words, if you invoke a function with CALL, all your
  LOCAL will be available to the underlying function. Example
    [FUNCTION myfunction1]
       LOCAL.VAL1	= 12
       CALL myfunction2 1, 2		// LOCAL.VAL1 will be available to myfunction2
       // if myfunction2 changes LOCAL.VAL1 it will change here aswell.
  If you do not pass arguments to the called function, then args/argn/argv are also shared,
  and the process is faster than invoking the function w/o CALL. If you pass arguments to the
  function, then only LOCAL is shared, and the process is an infinitesimal amount slower. Not
  noticeable, no real impact, but conceptually slower. 
  This can also be used as , faster without arguments, slower with.
- Recently realized that ALL DEFNAMEs are put into VAR. That means that all itemdefs, chardefs,
  etc have an entry in VAR (try  ). Now, this is potentially confusing and source
  for many problems:
     1) Whenever you're trying to access a VAR, you go through ALL the existing defnames.
     2) You can accidentally create a var that is also a defname... and oooooops!
  So to cope with this, changed it so that VAR/VAR0 only contains global variables that can be
  modified, whereas DEF/DEF0 contains item defnames and can only be read. The difference in speed
  is visible! EVERY time you were accessing a VAR you'd be searching through an array with a few
  thousand elements. Now each lookup searches only through the variables your scritps have created
  (which even on an extremely scripted shard shouldn't reach a hundred).
  This also makes it possible to identify WHICH variables are supposed to be saved.
  Although this is a huge change internally, it won't affect scripts except in the following
  situation:
     1) You defined a DEFNAME flag in scripts that you then changed during execution. This is
        highly uncommon, but if you decide you need this sort of behaviour just create the create
        the VAR once via scripts, it will be saved to spherevars.scp.
     2) You were accessing DEFNAMEs via VAR. No real reason to do it, seeing as DEFs / VARs can
        be accessed w/o the VAR. prefix.
  If not using DEF or VAR to access a variable, you'll get first the VAR if exists, and then the
  DEF. That means that old behaviour is kept.
- VARs are now saved to spheredata.scp. If that file isn't present at boottime the shard will print
  a warning, but it will continue, and it'll be created on the next save.
- GMPages will now be saved to spheredata.scp. Too many people are interested in parsing these to
  make special stuff (eg webpage interfaces or mirc scripts), so now they won't have to parse the
  whole world to read in this stuff.

06-01-2004, Kell
- Added "S" flag to SENDPACKET, allows one to send strings of characters directly. String is not
  within quotes it stops at the first space. Example
     SENDPACKET 00 S"This is the string to send" 0
     SENDPACKET 00 SUpToTheSpace 0
  If the string must be null terminated, simply put a 0 in there, as above. Otherwise, you'll probably
  need to specify length (strlen function) - depends on packet
- Added new walk limiting code, wildly based on the bit-bucket algorithm used in IP QoS DiffServ
  routers: there is a maximum speed at which you can walk (it's fixed, different walking or foot). If
  you walk faster than that speed, every tenth of second you walk faster than expected is a point you
  loose. Every 10th of second you take above the time expected is a point you win. The number of points
  you start with and the maximum is WALKBUFFER in sphere.ini, and I've tested it with values
  around 40 for good connections and 70 for laggy connections.
  If a player speedwalks, he'll soon drop below 0, and stop moving, then have to compensate with equally
  slow walking periods, like it happens when there's a burst of lag.
  WALKREGEN is the speed at which you regen walk points, in percentage.
  Default values: WALKBUFFER=50   WALKREGEN=25
  Hints:
	WALKBUFFER	lower for more strict control. However, setting it lower also increases the
  			chance of limiting someone which is just experiencing lag. Raise this value
			if you lower WALKREGEN.
	WALKREGEN	set lower for longer-lasting punishments. It makes sense to lower this value
			if you raise WALKBUFFER.
- Removed some EF_ flags that are no longer necessary seeing as they proved to be harmless. Make sure
  you consult MANUAL.TXT.
- Changed trigger @DropOn_Item and @ItemDropOn_Item to be activated for container items too.
  Activated when item with the trigger is dropped on another item (dropped on something else).
- Added @DropOn_Self and @ItemDropOn_Self, activated when an item is dropped on the item with the
  trigger (something was dropped on self).
- Implemented trigger @DropOn_Char and @ItemDropOn_Char.
- If these triggers fail, will only bounce the item if it's still being dragged. That allows the
  scripts in the triggers to define a new place for item.
- Made sure clients can only drop stuff into the bankbox if they are standing in the place where it
  was opened. This could now be checked within scripts aswell.
- Fixed an Injection exploit regarding accessing the bank away from the place it was opened in.
- Added @SkillGain and @Gain triggers. Check MANUAL.TXT for more info.

07-01-2004, Kell
- Automatically assign a DEFNAME to areas and rooms defined in the old format (AREA / ROOM). This
  defname is built upon the NAME, and is made unique by adding a number to it.
- In the console, you can type "d a" to output all the areas and rooms to a file "map_all.scp". I
  strongly suggest you replace your map with this file, as it'll allow you to finally get rid of the
  old format.
  NOTE: Teleporters and Moongates aren't saved in this file, so you should split those to a different
  file, to allow areas to be resynced.
- It is strongly suggested that you do the above, and get rid of the old format areas/rooms. Doing it
  has the following advantages:
  * Loading will be faster, because the server won't have to try and find a good defname for areas.
  * You can edit areas, and resync (even change their name) with no conflicts.
  * TAGs on areas are only saved for areas that have a valid DEFNAME, so if you do this, TAGs will be
    saved on all your areas.
- Added @Targon_Cancel for items.

Valid XHTML 1.0 Transitional Valid CSS!