3.1.0 API Changes - Animation System

by Zootfizzle | 26/02/2009 18:40:09

Zootfizzle

This is the official list of changes to the UI API for the upcoming 3.1.0 patch. This thread will also contain detailed documentation for the new systems we are adding. Information here will be updated periodically, and this may not necessarily be a complete list.


A sprocket here, a sprocket there, and soon there's sprockets everywhere!

by Zootfizzle | 26/02/2009 19:08:20

Zootfizzle

Purpose
A new animation system has been added to the WoW UI framework for patch 3.1.0. This system supports the XML specification of animation behaviors and it runs as efficiently as possible. Previously, animations could only be simulated by iteratively repositioning UI elements in Lua (via calls to SetPoint). The problems with that method were that it slowed the framerate of the game, it frequently led to code duplication, and it was not easy to develop new custom animation behaviors. In addition, rotation could not be accomplished by directly rotating frames. Instead, Scripters had to rotate texture coordinates within a texture to accomplish rotation.

The new animation system addresses these problems. However, in its current state, the animation system causes UI elements to go through what can best be described as an out of body experience. For example, if a button is positioned at coordinates (50,50) and an animation moves it 50 pixels to the right (50,0), you would not be able to highlight the button by mousing over the button's position on the screen (100, 50). To highlight the button, you would instead have to mouse over the button's original position (50, 50) to highlight it. In other words, the Anchor system positions Regions and the Animation system makes them run around the screen until they're told to Stop. Animations may stop either by the programmer stopping them explicitly (via calls to animation Stop functions) or as a side effect of the Anchor system altering a Region's points (SetPoint, SetAllPoints, ClearAllPoints, OnDragStart)

Tech Overview
Animations operate on any UI element of type Region. At this time, Regions consist of Frames, FontStrings, and Textures.

The abstract base type UIObject has subsumed the GetParent function of Region. The two new types Animation and AnimationGroup are both derived from UIObject.

The new animation system is offset-based. This means that any animation applied to a Region will modify the Region's current values by an offset. What the offset is depends on the type of animation. For example, if you have a Translation animation with an offset of (5,5) and you play the animation on the Frame at position (25,30), the Frame will end up at position (30,35).

The offset-based nature of this system means that multiple animations that play at the same time will stack. Using the previous example, if you have another Translation with an offset of (10,15) and you play the animation at the same time as the previous animation, then the Frame will smoothly travel from position (25,30) to position (40,45).

[ Post edited by Zootfizzle ]


A sprocket here, a sprocket there, and soon there's sprockets everywhere!

by Zootfizzle | 26/02/2009 19:22:00

Zootfizzle

An entirely new set of tags have been introduced to support Animations in XML. You can start with one of the existing UI element tags: <Frame>, <Texture>, or <FontString>.

Under one of these elements, you can make an <Animations> tag, which can contain any number of <AnimationGroup> tags, which can subsequently contain any number of specific Animation tags.

<Animations>

Note: This is the opening tag you use to attach animations to a Region. Only one of these can be the child of any Region tag (<Frame>, <Texture>, <FontString>).

Attributes
    None
Scripts
    None
Children
    AnimationGroup
<AnimationGroup>

Note: Any number of these can be placed under an <Animations> tag. These control the playback and looping of groups of Animations.

There are currently two looping types: one that can make the group repeat itself and one that can make the group play in reverse when it finishes.

The order that animations play in is determined by the order attribute of the child animations. Animations are played in ascending order. If more than one animation specifies the same order, they will play simultaneously.

Attributes
    name
      Name of the animation group.

    inherits
      Specifies a virtual AnimationGroup from which this group should inherit.

    looping
      An enumerated value. One of NONE, REPEAT, BOUNCE.
      REPEAT replays the group when it finishes playing.
      BOUNCE plays the group in reverse when it finishes playing. This produces a bouncing effect.
Scripts
    OnPlay
      Fires when the Play function gets called on the group or one of its children.

    OnPause
      Fires when the Pause function is called on the group or one of its children.

    OnStop
      Fires when either the '''Stop''' function is called on the group or one of its children, when an ancestor frame implicitly stops animations (via SetPoint, SetParent, SetAllPoints, ClearAllPoints), or when an ancestor begins to Drag (via OnDragStart).

      Arguments
      requested - true if the Stop function was called on this group

    OnUpdate
      Fires after all animation updates for the current tick have been applied.
      Passes a number parameter which stores the number of seconds since the last update.

    OnFinished
      Fires after this group finishes playing. This will not be fired for looping animation groups unless you call the '''Finish''' function on the group.

      Arguments
      requested - true if the "Finish" function was called on this group

    OnLoop
      Fires after this group finishes a loop cycle

      Arguments
      loopState - The loop state that this animation is transitioning to
Children
    Animation, Translation, Rotation, Scale, Alpha, and Scripts.

[ Post edited by Zootfizzle ]


A sprocket here, a sprocket there, and soon there's sprockets everywhere!

by Zootfizzle | 26/02/2009 19:41:34

Zootfizzle

<Animation>

Note: Base animation type. This type is not abstract even though it does not modify its parent UI elements by default. This type is for making custom animations via the OnUpdate script.

Attributes
    name
      Name of the animation.

    inherits
      Specifies a virtual Animation from which this group should inherit.

    startDelay
      Seconds to delay before the animation begins updating.

    endDelay
      Seconds to delay after the animation finishes updating.

    duration
      Duration of the animation.

    maxFramerate
      Maximum frames per second that this animation updates its progress.

    order
      Order within the parent group which this animation plays.

    smoothing
      Smooths out the animation update progress. One of NONE, IN, OUT, or IN_OUT.
Scripts
    OnPlay
      Fires when the Play function is called on this animation or its parent

    OnPause
      Fires when the Pause function is called on this animation or its parent

    OnStop
      Fires when either the Stop function is called on the group or one of its children, when an ancestor frame implicitly stops animations (via SetPoint, SetParent, SetAllPoints, ClearAllPoints), or when an ancestor begins to Drag (via OnDragStart).

      Arguments
      requested - true if the Stop function was called on this group.

    OnUpdate
      Fires after this animation has applied its update for the current tick. This may fire more than once per frame in low framerate conditions.

      Arguments
      elapsed - number of seconds applied to the current animation update

    OnFinished
      Fires after this Animation finishes playing.
Children

<Translation>

Note: Inherits all attributes and scripts from <Animation>. Translates a Region from its current position by an offset.

Attributes
    offsetX
      Amount to offset on the X-axis.

    offsetY
      Amount to offset on the Y-axis.

<Rotation>
    Note: Inherits all attributes and scripts from <Animation>. Rotates a Region by an amount specified either in degrees or radians.
Attributes
    radians
      Amount of radians to rotate.

    degrees
      Amount of degrees to rotate. This is overriden by radians if both are specified.

<Scale>

Note: Inherits all attributes and scripts from <Animation>. Scales a Region by an amount. The Scale can be non-uniform.

Attributes
    scaleX
      Amount to scale along the X-axis.

    scaleY
      Amount to scale along the Y-axis.

<Alpha>

Note: Inherits all attributes and scripts from <Animation>. Changes the normalized [0,1] alpha value of a Region by an amount.

Attributes
    change
      Amount to change a Region's alpha. Note that amounts less than -1 or greater than +1 are clamped.

[ Post edited by Zootfizzle ]

by Slouken | 08/08/2007 19:40:50

Slouken


Q u o t e:

Slash Commands



Maybe "Macro Commands"?


Q u o t e:

* NEW - /petautocasttoggle <slot> (note -- slot is a guess, it may take skill name also)



Yes, it works just like /petautocaston and /petautocastoff which also take a spell name.

by Zootfizzle | 26/02/2009 20:10:06

Zootfizzle

<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/1801/XMLSchema-instance" 
xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Frame name="AnimFrame" parent="UIParent" frameStrata="LOW" toplevel="true" hidden="false">
<Size x="64" y="64"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="PlayerFrame" relativePoint="BOTTOMLEFT">
<Offset x="225" y="0"/>
</Anchor>
</Anchors>
<Animations>
<AnimationGroup name="$parentAnimGroup" looping="BOUNCE">
<Translation name="$parentTranslate1" offsetX="150" offsetY="0" startDelay="0" duration="1"
smoothing="IN_OUT" order="1" maxFramerate="30">
<Scripts>
<OnPlay/>
<OnPause/>
<OnStop/>
<OnUpdate/>
<OnFinished/>
</Scripts>
</Translation>
<Rotation name="$parentRot1" degrees="180" startDelay="0.5" endDelay="0.5" duration="1" smoothing="OUT" order="3">
<Origin point="CENTER">
<Offset x="0" y="0"/>
</Origin>
</Rotation>
<Scale name="$parentScale1" scaleX="1.5" scaleY="1.5" duration="1" smoothing="IN" order="4">
<Origin point="CENTER"/>
</Scale>
<Scripts>
<OnFinished/>
</Scripts>
</AnimationGroup>
<AnimationGroup name="$parentPulse" looping="BOUNCE">
<Animation duration="0.5">
<Scripts>
<OnLoad>
self.regionParent = self:GetRegionParent();
self.min = 0.0;
self.max = 1.0;
</OnLoad>
<OnUpdate>
local alpha = self.min + (self.max - self.min)*self:GetProgress();
self.regionParent:SetAlpha(alpha);
</OnUpdate>
</Scripts>
</Animation>
<Animation duration="0.5">
<Scripts>
<OnLoad>
self.regionParent = self:GetRegionParent();
self.min = 64.0;
self.max = 94.0;
</OnLoad>
<OnUpdate>
local size = self.min + (self.max - self.min)*self:GetProgress();
self.regionParent:SetWidth(size);
self.regionParent:SetHeight(size);
</OnUpdate>
</Scripts>
</Animation>
</AnimationGroup>
</Animations>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentTexture" file="Interface\CharacterFrame\TemporaryPortrait-Male-Human">
<Size x="64" y="64"/>
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="0" y="0"/>
</Anchor>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self:RegisterEvent("PLAYER_UPDATE_RESTING");
</OnLoad>
<OnEvent>
AnimFrameAnimGroup:Play();
</OnEvent>
</Scripts>
</Frame>
</Ui>

[ Post edited by Zootfizzle ]

by Slouken | 08/08/2007 19:42:02

Slouken


Q u o t e:

I'm fairly sure slouken will have made sure that it'll always be faster to do:


frame:RegisterEvent("SOME_EVENT");


than


if (not frame:IsEventRegistered("SOME_EVENT")) then
frame:RegisterEvent("SOME_EVENT");
end



Yes, the first call is faster, since the internal code already checks to see if the frame is already registered.

by Zootfizzle | 26/02/2009 20:37:01

Zootfizzle

Changes to Existing Types

Region
  • Region:CreateAnimationGroup(["name"[,";inheritsFrom"]])
    Create and return a new AnimationGroup as a child of this Region.

  • Region:StopAnimating()
    Stops any active animations on the Region and its children.

  • Region:GetAnimationGroups()
    Returns all AnimationGroups that are children of this Region

  • Region:IsDragging()
    True if this Region or its Parent is being dragged.
New Types

Object

This is a new abstract type. Animations and Regions both derive from this type.
  • Object:GetParent()
    Moved from Region:GetParent(). This is essentially the same as the old version, except that you can no longer assume that your object has a Frame type in its hierarchy somewhere.
AnimationGroup

This manages playback, order, and looping of its child Animations. Animations in a group will play in ascending order according to their order fields (accessible via SetOrder and GetOrder). If two or more Animations have the same order value, then they will play simultaneously. The next animation will not play until all Animations with that order value are done.
  • AnimationGroup:Play()
    Start playing the animations in this group.

  • AnimationGroup:Pause()
    Pause the animations in this group.

  • AnimationGroup:Stop()
    Stop all animations in this group.

  • AnimationGroup:Finish()
    Notify this group to stop playing once the current loop cycle is done. Does nothing if this group is not playing.

  • AnimationGroup:GetProgress()
    Returns the progress of this animation as a unit value [0,1].

  • AnimationGroup:IsDone()
    Returns true if the group has finished playing.

  • AnimationGroup:IsPlaying()
    Returns true if the group is playing.

  • AnimationGroup:IsPaused()
    Returns true if the group is paused.

  • AnimationGroup:GetDuration()
    Gets the total duration across all child Animations that the group will take to complete one loop cycle.

  • AnimationGroup:SetLooping(loopType)
    Sets the type of looping for the group. Input is [NONE, REPEAT, or BOUNCE].

  • AnimationGroup:GetLooping()
    Gets the type of looping for the group.

  • AnimationGroup:GetLoopState()
    Gets the current loop state of the group. Output is [NONE, FORWARD, or REVERSE].

  • AnimationGroup:CreateAnimation("animationType", ["name"[,"inheritsFrom"]])
    Create and return an Animation as a child of this group.

  • AnimationGroup:HasScript()
    Same as Frame:HasScript. Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

  • AnimationGroup:GetScript()
    Same as Frame:HasScript. Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

  • AnimationGroup:SetScript()
    Same as Frame:HasScript. Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

[ Post edited by Zootfizzle ]

by Zootfizzle | 26/02/2009 20:58:56

Zootfizzle

Animation

This is a base animation type. This handles all animation timing and bookkeeping. An animation tag must always be parented by an AnimationGroup tag.
  • Animation:Play()
    Play the animation.

  • Animation:Pause()
    Pause the animation.

  • Animation:Stop()
    Stop the animation.

  • Animation:IsDone()
    Returns true if the animation has finished playing.

  • Animation:IsPlaying()
    Returns true if the animation is playing.

  • Animation:IsPaused()
    Returns true if the animation is paused.

  • Animation:IsStopped()
    Returns true if the animation is stopped.

  • Animation:IsDelaying()
    Returns true if the animation is in the middle of a start or end delay.

  • Animation:GetElapsed()
    Gets the amount of time in seconds that the animation has been playing for.

  • Animation:SetStartDelay(delaySec)
    Set the number of seconds that the animation delays before it starts to progress.

  • Animation:GetStartDelay()
    Get the number of seconds that the animation delays before it starts to progress.

  • Animation:SetEndDelay(delaySec)
    Set the number of seconds the animation delays after finishing.

  • Animation:GetEndDelay()
    Get the number of seconds the animation delays after finishing.

  • Animation:SetDuration(durationSec)
    Set the number of seconds it takes for the animation to progress from start to finish.

  • Animation:GetDuration()
    Get the number of seconds it takes for the animation to progress from start to finish.

  • Animation:GetProgress()
    Returns the progress of the animation as a unit value [0,1]. Ignores start and end delay.

  • Animation:GetSmoothProgress()
    Returns a smoothed, [0,1] progress value for the animation.

  • Animation:GetProgressWithDelay()
    Returns the progress of the animation combined with its start and end delay.

  • Animation:SetMaxFramerate(framerate)
    Sets the maximum frames per second that the animation will update its progress.

  • Animation:GetMaxFramerate()
    Gets the maximum frames per second that the animation will update its progress.

  • Animation:SetOrder(order)
    Sets the order that the animation plays within its parent group. Range is [1,100].

  • Animation:GetOrder()
    Gets the order of the animation within its parent group.

  • Animation:SetSmoothing(smoothType)
    Sets the smoothing type for the animation. Input is [IN,OUT, or IN_OUT].

  • Animation:GetSmoothing()
    Gets the smoothing type for the animation.

  • Animation:SetParent(animGroup or "animGroupName")
    Sets the parent for the animation. If the animation was not already a child of the parent, the parent will insert the animation into the proper order amongst its children.

  • Animation:GetRegionParent()
    Gets the Region object that the animation operates on. The region object is this Animation's parent's parent (the AnimationGroup's parent).

  • Animation:HasScript("handler")
    Same as Frame:HasScript, Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

  • Animation:GetScript("handler")
    Same as Frame:GetScript, Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

  • Animation:SetScript("handler")
    Same as Frame:SetScript, Input is [OnLoad, OnPlay, OnPaused, OnStop, OnFinished, OnUpdate].

by Slouken | 09/08/2007 02:47:21

Slouken

Changed IsCurrentCast() to IsSelectedSpell()
Added IsCurrentSpell() and IsConsumableSpell() corresponding to IsCurrentAction(), and IsConsumableAction()

by Zootfizzle | 26/02/2009 20:59:34

Zootfizzle

Translation

This is an affine transformation that moves a parent Region by an offset. Translation has all of the methods of Animation, plus the following:
  • Translation:SetOffset(x, y)
    Sets the offset that the animation's parent Region would travel.

  • Translation:GetOffset()
    Gets the offset that the animation's parent Region would travel.
Rotation

This is an affine transformation that rotates a parent Region about an origin. Rotation has all of the methods of Animation, plus the following:
  • Rotation:SetDegrees(degrees)
    Sets the amount of degrees that the animation's parent Region would rotate.

  • Rotation:GetDegrees()
    Gets the amount of degrees that the animation's parent Region would rotate.

  • Rotation:SetRadians(radians)
    Sets the amount of radians that the animation's parent Region would travel.

  • Rotation:GetRadians()
    Sets the amount of radians that the animation's parent Region would travel.

  • Rotation:SetOrigin(point, offsetX, offsetY)
    Sets the animation's origin of rotation for its parent Region.

  • Rotation:GetOrigin()
    Gets the point, X offset, and Y offset of the animation's origin of rotation for its parent Region.
Scale

This is an affine transformation that scales a parent Region about an origin. The scale can be non-uniform. Scale has all of the methods of Animation, plus the following:
  • Scale:SetScale(x, y)
    Sets the X scalar and the Y scalar that the animation's parent Region should scale by.

  • Scale:GetScale()
    Gets the X scalar and the Y scalar that the animation's parent Region should scale by.

  • Scale:SetOrigin(point, offsetX, offsetY)
    Sets the animation's origin of rotation for its parent Region.

  • Scale:GetOrigin()
    Gets the point, X offset, and Y offset of the animation's origin of rotation for its parent Region.
Alpha

This animation changes the alpha value of its parent region. Alpha has all of the methods of Animation plus the following:
  • Alpha:SetChange(change)
    Sets the amount that the alpha value of this animation's parent Region changes by.

  • Alpha:GetChange()
    Gets the amount that the alpha value of this animation's parent Region changes by.

by Slouken | 27/08/2007 23:51:21

Slouken

Added for 2.3:
item, link = GetMacroItem(macro)
spell, rank = GetMacroSpell(macro)

by Slouken | 27/08/2007 23:53:00

Slouken


Q u o t e:

This could have the potential to seriously change the dynamics of druid play.



Yes, this is intentional.

by Slouken | 30/08/2007 22:25:46

Slouken

Yes.

by Slouken | 02/09/2007 00:35:34

Slouken

That's not a bug. That part of the link is optional, but refers to a specific item if speciffied.

by Slouken | 07/09/2007 21:32:14

Slouken

New in 2.3:
FontString:SetFormattedText(format, ...)
Button:SetFormattedText(format, ...)

This allows you to skip the format step in doing something like this:
text:SetText(format("%.1f", GetFramerate()))
e.g.
text:SetFormattedText("%.1f", GetFramerate())
... and in doing so reduce the amount of garbage that is generated.

by Slouken | 07/09/2007 23:11:45

Slouken

Oh, whoops! :)

by Slouken | 08/09/2007 01:08:18

Slouken

I considered that, but GameTooltip has an optional parameter to SetText(), and mixing variable arguments with optional arguments gets really messy, especially when those variable arguments can be positional. :)

If there's a specific spot that's creating lots of garbage in the default UI, let me know and I'll take a look.

by Slouken | 18/09/2007 18:31:57

Slouken

Auction API Changes

QueryAuctionItems
- New argument (bool), setting it to true will retrieve all auction house data (not just 50 items). This can only be used once every 15 minutes. This is intended to reduce our load from add-ons such as auctioneer that are going to download the entire auction house anyways.

CanSendAuctionQuery()
- Now returns two results. First (bool) is if you can send a regular query, second (bool) is if you can ask for all auction house data.

IsAuctionSortReversed()
- Now returns two results. First (bool) is true if the sort is reversed, second (bool) is true if we’re actually using this sort.

sort, reversed = GetAuctionSort(type, index)
- New function, allows enumeration of what sorts are being currently used on the table and in what order.
o 'type' – string – which table to retrieve the sort for (ie. “owner”, “bidder” or “list”).
o 'index' - number – the index of the sort to retrieve (1 for the first sort, 2 for the second sort, etc).
o 'sort' – string - the sort being used (nil if there isn’t a sort at this index)
o 'reversed' – bool – true if the sort is reversed

SortAuctionClearSort(type)
- New function, allows the caller to clear all previous sorts for a table.
o 'type' – string – which table to clear the sorts on (ie. “owner”, “bidder”, or “list”).

SortAuctionSetSort(type, sort, reverse)
- New function, allows the caller to add a sort to a table. The sort is added to the beginning of the sort list (not the end), pushing all other sorts down.
o 'type' – string – which table to clear the sorts on (ie. “owner”, “bidder”, or “list”).
o 'sort' – string – the sort to add (ie. “quality”, “level”, “duration”, “status”, “bid”, “name”, “buyout”, “seller”, “buyoutthenbid”, “quantity”).
o 'reverse' – bool – true if this sort should be applied in reverse order.

SortAuctionApplySort(type)
- New function, performs the sort that was built up using SortAuctionClearSort, SortAuctionSetSort
o 'type' – string – which table to clear the sorts on (ie. “owner”, “bidder”, or “list”).

There is a new sort type “quantity”, which allows sorts by the number of items.

by Slouken | 18/09/2007 18:39:33

Slouken

Mail API Changes

When composing mail, there are now “slots”, that you can drag items into (1 is the first slot, 2 is the second slot, etc). Once the mail arrives, you use an “index” to refer to each attachment.

ClickSendMailItemButton(attachSlot)
- Added an additional “attachSlot” argument to this existing function
o 'attachSlot' – number – indicates which attachment slot the user clicked on when composing mail.

GetSendMailItem(attachSlot)
- Added an additional “attachSlot” argument to this existing function
o 'attachSlot' – number – indicates which attachment slot to get information about when composing mail

GetSendMailItemLink(attachSlot)
- Added an additional “attachSlot” argument to this existing function
o 'attachSlot' – number – indicates which attachment slot to get information about when composing mail

GetSendMailPrice()
- No change for parameters, but note that the cost of sending mail now changes depending on how many items have been attached.

GetInboxItem(messageIndex, attachIndex)
- Added an additional “attachIndex” argument to this existing function
o 'messageIndex' – number – indicates which message to get info about the item from
o 'attachIndex' – number – indicates which message attachment to get info about

GetInboxItemLink(messageIndex, attachIndex)
- Added an additional “attachIndex” argument to this existing function
o 'messageIndex' – number – indicates which message to get info about the item from
o 'attachIndex' – number – indicates which message attachment to get info about

TakeInboxItem(messageIndex, attachIndex)
- Added an additional “attachIndex” argument to this existing function
o 'messageIndex' – number – indicates which message to get info about the item from
o 'attachIndex' – number – indicates which message attachment to get info about

by Slouken | 18/09/2007 18:48:07

Slouken

FYI, in 2.3 the game will be performing extra garbage collection outside of combat to keep memory use down.

As always, the game will perform better if you don't generate any garbage, and here are some tips to do that:
* If you're composing a formatted string to display in a button or font string, use the new FontString:SetFormattedText(fmt, ...) API
* If you write a function that returns many values, consider returning them directly instead of creating a table and returning that table.
* If returning a table from a function really is most convenient, have the caller of that function pass in the table to be filled out instead of creating a new table inside the function.

by Slouken | 19/09/2007 01:31:16

Slouken


Q u o t e:

Is there a maximum number of slots for this? What are the initial conditions - ie, is it dynamic akin to the KeyRing?



The maximum number of slots is 12.

by Slouken | 20/09/2007 18:30:45

Slouken

Coming in 2.3:
Added FontString:GetStringHeight()
Added a parameter to :GetWidth() and :GetHeight() to ignore the rect and return 0 if no width and height have been explicitly set. This parameter defaults to false.

by Slouken | 20/09/2007 18:33:21

Slouken

Coming in 2.3:
Added 'form' as a synonym for 'stance' in the macro options.

by Slouken | 21/09/2007 23:24:23

Slouken

In 2.3 you should no longer need to call :UpdateScrollChildRect(). If a child frame, texture or fontstring has changed, the scroll parent will automatically recalculate it's scroll rect and dispatch events appropriately.

Of course, please test this out on the test realm when it goes live, and report any bugs.

by Slouken | 03/10/2007 20:53:22

Slouken

Added in 2.3:
EditBox:SetCursorPosition(position)
position = EditBox:GetCursorPosition()

by Slouken | 12/10/2007 04:39:12

Slouken

Any particular reason you need to override tostring()?

by Slouken | 12/10/2007 21:26:13

Slouken

Coming in 2.3 is a way to log taint spreading through global variables.

To turn taint logging on:
/console taintLog 1

To turn taint logging off:
/console taintLog 0

The taint log is saved in Logs\taint.log, and contains entries for every global that is tainted, and each time Blizzard code becomes tainted by reading a tainted global variable. It also has an entry for every action that is blocked by taint, including what frame the action was trying to affect.

If you're running into problems with actions being blocked in combat, please turn taint logging on, and post a link to the log file generated during that session.

Keep in mind that taint is normally fine, it only becomes a problem when it's introduced into the code path of secure code.

[ Post edited by Slouken ]

by Slouken | 13/10/2007 02:15:38

Slouken


Q u o t e:

I currently put a 'SET TargetNearestDistance=60' in my config.wtf file. I'm wondering if this change is meant to stop my ability to change this setting, or is in regard to another issue.


Yep, that's exactly what it's for.

by Slouken | 13/10/2007 02:20:45

Slouken

BTW, here's some sample output from this test case:
1. Run this macro: /script PetActionBarFrame = PetActionBarFrame
2. Bring out a pet
3. Mount up
4. Enter combat and dismount

Logs\taint.log:
10/12 17:01:03.292 Global variable PetActionBarFrame tainted by MACRO_TAINT - PetActionBarFrame = PetActionBarFrame:1
10/12 17:01:08.379 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:128 PetActionBar_Update()
10/12 17:01:08.379 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:128 PetActionBar_Update()
10/12 17:01:08.379 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:128 PetActionBar_Update()
10/12 17:01:08.391 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:128 PetActionBar_Update()
10/12 17:01:15.240 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\UIParent.lua:2203 UIParent_ManageFramePositions()
10/12 17:01:15.240 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 MultiBarRight:SetPoint()
10/12 17:01:15.240 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 ShapeshiftBarFrame:SetPoint()
10/12 17:01:15.240 Global variable PETACTIONBAR_YPOS tainted by MACRO_TAINT - Interface\FrameXML\UIParent.lua:2291 setglobal()
10/12 17:01:15.240 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 VoiceChatTalkers:SetPoint()
10/12 17:01:15.240 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 MultiBarBottomLeft:SetPoint()
10/12 17:01:15.240 Global variable BATTLEFIELD_TAB_OFFSET_Y tainted by MACRO_TAINT - Interface\FrameXML\UIParent.lua:2291 setglobal()
10/12 17:01:15.240 Global variable CONTAINER_OFFSET_Y tainted by MACRO_TAINT - Interface\FrameXML\UIParent.lua:2291 setglobal()
10/12 17:01:15.240 Global variable CONTAINER_OFFSET_X tainted by MACRO_TAINT - Interface\FrameXML\UIParent.lua:2289 setglobal()
10/12 17:01:15.247 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 PossessBarFrame:SetPoint()
10/12 17:01:15.449 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:341 UnlockPetActionBar()
10/12 17:01:15.451 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:341 UnlockPetActionBar()
10/12 17:01:15.451 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:341 UnlockPetActionBar()
10/12 17:01:15.654 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:184 HidePetActionBar()
10/12 17:01:15.654 Execution tainted by MACRO_TAINT while reading PetActionBarFrame - Interface\FrameXML\PetActionBarFrame.lua:162 ShowPetActionBar()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\PetActionBarFrame.lua:163 PetActionBarFrame:Show()
10/12 17:01:15.654 Global variable PETACTIONBAR_XPOS tainted by MACRO_TAINT - Interface\FrameXML\PetActionBarFrame.lua:174 ShowPetActionBar()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 MultiBarRight:SetPoint()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 ShapeshiftBarFrame:SetPoint()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 VoiceChatTalkers:SetPoint()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 MultiBarBottomLeft:SetPoint()
10/12 17:01:15.654 An action was blocked in combat because of taint from MACRO_TAINT - Interface\FrameXML\UIParent.lua:2297 PossessBarFrame:SetPoint()
10/12 17:01:15.732 Execution tainted by MACRO_TAINT while reading CONTAINER_OFFSET_X - Interface\FrameXML\GameTooltip.lua:75 GameTooltip_SetDefaultAnchor()
10/12 17:01:15.821 Execution tainted by MACRO_TAINT while reading CONTAINER_OFFSET_X - Interface\FrameXML\GameTooltip.lua:75 GameTooltip_SetDefaultAnchor()

by Slouken | 13/10/2007 02:35:13

Slouken

The limit is 50 yards, I believe.

by Slouken | 14/10/2007 04:59:06

Slouken

I'm not sure. It's on my list to look at next week.

by Slouken | 17/10/2007 07:47:23

Slouken

Yep, it should be in the next test realm update in a few days.

by Slouken | 18/10/2007 03:58:37

Slouken

No promises, but it's looking like /cancelform followed by a spell cast will not be needed in 2.3.

By default any spell that requires you to leave your current form will automatically cancel your form before casting. This applies to shadowform and stealth as well. You can disable this with /console autoUnshift 0

Barring unforseen complications, this should be on the test realm after next week's update, so please test it out thoroughly at that time.

[ Post edited by Slouken ]

by Slouken | 18/10/2007 07:59:37

Slouken


Q u o t e:


Will client side functionality of /cancelform still exist to allow us to shapeshift back into the same form?


I'm not sure what you mean. /cancelform doesn't have functionality to allow you to shapeshift back into the same form...

But, you could do something like this:
/use Super Healing Potion
/cast Dire Bear Form
and it would switch to caster form, use a potion and put you back into bear form, assuming that you had enough mana to return to bear form.

by Slouken | 19/10/2007 01:46:49

Slouken

The Interface AddOn Kit has been updated to work with the 2.3 test realm:
http://www.worldofwarcraft.com/ui/

by Slouken | 19/10/2007 18:51:26

Slouken

No, the 1.5 second cooldown is by design. You can't start casting again until that client-side cooldown has elapsed, and you'll notice that, because it's client side, latency doesn't affect it.

[ Post edited by Slouken ]

by Slouken | 19/10/2007 20:47:48

Slouken

No, it starts immediately when the cast is sent to the server. There's a bug currently where this doesn't happen on the test realm, but that's fixed either for this weekend or next week's test realm update.

by Slouken | 20/10/2007 03:05:53

Slouken


Q u o t e:

Does that mean that if you cast too early, such that the server receives the cast before the previous cast has finished, you'll have to wait for the client side GCD and your new cast will fail? Or will the failure response from the server cancel the client's GCD when it's received? Or have I just misunderstood completely?


The failure response from the server cancels the client's GCD.

by Slouken | 20/10/2007 03:12:10

Slouken

The test server update should be up. Please try out the taint log!

If you get a message "Interface action failed because of an AddOn", this means that an AddOn interfered with the Blizzard UI in some way. Instructions on turning on taint logging and posting the resulting log can be found here:
Interface action failed because of an AddOn

[ Post edited by Slouken ]

by Slouken | 21/10/2007 02:06:42

Slouken

Yes, the global cooldown fix will be in next week's PTR update.

Also note that once the global cooldown is fixed, it's still a bad idea to spam cast, since as noted you have to wait for the server to tell you that you cast too early to be able to cast again. Nothing in this has changed from previous patches. You can simply try to cast early now where you had to abort casting previously. Previously the cost of casting too early was that you interrupted your cast nearly completed, now the cost is that you wait latency for the error from the server.

The designers aren't planning on adding a spell queue, since that destroys the immediate response between input and action.

The current thought is also that we won't be sending casts to the server during the global cooldown, both to reduce bandwidth (and flood disconnections) and to lessen the incentive to spam cast.

Of course everything is still in development, and we may decide to pull the change entirely. If you would like to contribute your opinion, please create a thread in the suggestions forum.

[ Post edited by Slouken ]

by Slouken | 21/10/2007 17:50:44

Slouken


Q u o t e:

So, you near the end of a cast, if you FAIL a casting attempt because you sent it too soon, you get DOUBLY penalized for latency, once for the server to tell your gcd to end, and then again when you finally send a succesful cast to the server.



Can you show a timeline of how this is would be worse than the current situation in practice?

Things to take into consideration:

* The client can't initiate casts more often than the global cooldown, so it's only a problems for spells with longer cast times than the global cooldown.

* in 2.2 you couldn't initiate a cast on the client before the client received notification from the server that the previous cast had completed.

* This discussion doesn't really involve people using /stopcasting, because they aren't the ones spam casting. In 2.2 they would interrupt their previous cast, losing the time already spent casting, and in 2.3 they wait the round trip latency for the error message from the server, both of which are less efficient than getting the timing right.

The goal is simply to allow people to do the same sort of "advance casting" in 2.3 as they do in 2.2, but without requiring /stopcasting macros.

by Slouken | 21/10/2007 18:06:50

Slouken


Q u o t e:


So my 1.5 sec Flash of Light Spell is always penalized by latency?



Nope, assuming constant latency your 1.5 second Flash of Light can be cast back to back.
0.0s: Client starts casting Flash of Light, starts 1.5 second global cooldown
0.25s: Server starts casting Flash of Light
0.5s: Client sees Flash of Light start casting
1.5s: Client finishes global cooldown, starts casting Flash of Light, starts global cooldown
1.75s: Server completes casting Flash of Light, starts casting new Flash of Light
2.0s: Client sees Flash of Light complete and new cast start


Q u o t e:

But I could circumvent that with quartz and stop casting.



Yep, now you don't need stop casting.


Q u o t e:

But a click 1ms too quick triggers a penalty of GCD + latency, yes?



Yes.


Q u o t e:

Does it cancel my previous spell?



No.

by Slouken | 21/10/2007 18:35:30

Slouken


Q u o t e:


Which means the real penalty is 2x latency, rather than GCD+latency (one full round trip of latency to hear you are too early, plus another one way trip to start a new cast [once you push the button after you get the error])..


Yes, but remember this overlaps the casting time for the previous cast, so it's not quite as bad as it sounds.

by Slouken | 21/10/2007 18:43:20

Slouken


Q u o t e:

Still not perfect, but I still think this is better than 2.2 and before. If you don't like the change... keep using stopcasting macros, as they are not disabling that functionality, but instead making it so you don't have to use them.


Exactly. The goal was to allow the same sort of advance casting that was previously done with /stopcasting macros, for all spells.

As far as I can tell the behavior is always better than 2.2, but still occasionally causes delays roughly equivalent to your latency if your latency is variable or the server is heavily loaded. This is something we're currently discussing.

[ Post edited by Slouken ]

by Slouken | 22/10/2007 18:31:45

Slouken

For 2.3:

Added an insert mode to ScrollingMessageFrame, defaulting to BOTTOM

Xml tag:
insertMode=”TOP” (or “BOTTOM”)

functions:
ScrollingMessageFrame:SetInsertMode(mode)
mode = ScrollingMessageFrame:GetInsertMode()


ScrollingMessageFrame:SetScrollFromBottom(offset)
renamed to:
ScrollingMessageFrame:SetScrollOffset(offset)

[ Post edited by Slouken ]

by Slouken | 22/10/2007 20:35:08

Slouken

Yes, this is actually what we're going to be evaluating for the next test realm update.

The casting latency discussion is hereby closed in this thread. If you want to continue discussion please create a new thread for it.

by Slouken | 23/10/2007 05:41:33

Slouken

There's a GCD fix in the next test realm update, can you retest when that gets there?

by Slouken | 23/10/2007 05:44:25

Slouken

In the next test realm update there's an update to the way taint works:
* While an AddOn function is running, the taint is set to the AddOn that defined the function. This is much more intuitive and should help make the logs more useful.

Edit: I also added stack trace information to the taint log, so you can see what AddOns are involved, not just the last one executing.

[ Post edited by Slouken ]

by Slouken | 23/10/2007 15:51:41

Slouken

That sounds great, thanks!

by Slouken | 24/10/2007 02:43:20

Slouken

In an upcoming test realm update, taintLog can be set to 0, 1, or 2.
0 = Do not log any taint messages
1 = Log action blocked messages along with relevant global variable messages where possible
2 = Log each time a global variable is tainted and each time Blizzard code is tainted

The format for the logging in mode 1 is pretty nice:

Global variable PETACTIONBAR_YPOS tainted by CT_BottomBar - setglobal()
Interface\FrameXML\UIParent.lua:2295 UIParent_ManageFramePositions()
MainMenuBarMaxLevelBar:OnShow()
MainMenuBarMaxLevelBar:Show()
Interface\FrameXML\ReputationFrame.lua:244
ReputationWatchBar_Update()
ReputationWatchBar:OnEvent()
Execution tainted by CT_BottomBar while reading PETACTIONBAR_YPOS - getglobal()
Interface\FrameXML\UIParent.lua:2228 UIParent_ManageFramePositions()
Interface\FrameXML\WorldStateFrame.lua:134 WorldStateAlwaysUpFrame_Update()
Interface\FrameXML\WorldStateFrame.lua:43 WorldStateAlwaysUpFrame_OnEvent()
WorldStateAlwaysUpFrame:OnEvent()
An action was blocked in combat because of taint from CT_BottomBar - VoiceChatTalkers:SetPoint()
Interface\FrameXML\UIParent.lua:2301 UIParent_ManageFramePositions()
Interface\FrameXML\WorldStateFrame.lua:134 WorldStateAlwaysUpFrame_Update()
Interface\FrameXML\WorldStateFrame.lua:43 WorldStateAlwaysUpFrame_OnEvent()
WorldStateAlwaysUpFrame:OnEvent()

[ Post edited by Slouken ]

by Slouken | 25/10/2007 22:55:40

Slouken

Added for 2.3:
durability, maximum = GetInventoryItemDurability(slotid)
durability, maximum = GetContainerItemDurability(bagid, slotid)

[ Post edited by Slouken ]

by Slouken | 28/10/2007 04:01:14

Slouken

Thats the extent of the functionality, yes.

by Slouken | 28/10/2007 09:34:16

Slouken

I don't know if this matters for your problem, but in 2.3 the scroll child rect is automatically updated when the children are shown/hidden/resized.

by Slouken | 28/10/2007 20:40:21

Slouken

That's really weird. Can you make a macro that shows this problem with no AddOns loaded?

by Slouken | 29/10/2007 19:23:15

Slouken


Q u o t e:
I've been getting a ton of OnLoad script errors from addons with xml frames.

The one I've seen most often is not being able to find a child frame that was created by the inherited template in the OnLoad script using something like getglobal(this:GetName().."Button").

Edit: GETGLOBAL IS BROKEN!

/script global_var=1;ChatFrame1:AddMessage(type(getglobal("global_var&quot;)))
prints 'nil'


Got it, this is fixed for the next test realm update. It only affects code that triggers taint log messages.

Thanks!

by Slouken | 30/10/2007 21:41:14

Slouken

It's not a bug, cast sequences always reset at the end of their sequence. The reset syntax is simply additional conditions that may cause the sequence to reset.

by Slouken | 30/10/2007 21:50:09

Slouken

No problem. :)

by Slouken | 30/10/2007 23:56:04

Slouken

From the taint expert:
Using UIDropDownMenu_CreateInfo() should no longer cause taint issues to spread to other dropdowns.

Blizzard Announcement Recent Blizzard Announcements

 



Loaded in 0.18843 seconds