vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- StatRings Ring Template
2 ----------------------------------------------------------------------
3 --
4 -- Template code for partial ring display
5 --
6 -- Divides the ring up into four quadrants:
7 -- Q1-TopRight Q2-BottomRight Q3-BottomLeft Q4-TopLeft
8 --
9 -- Other terminology:
10 -- self.radius - The outer radius of the ring (Also the texture width)
11 -- self.ringFactor - The ratio of inner radius/outer radius
12  
13 ---------------------------------------------------------------------------
14 -- QUADRANT MAPPING FUNCTIONS
15 -- The subsetting code is all written relative to the first quandrant, but
16 -- each quadrant has a pair of functions to manage mapping location and
17 -- texture operations from that 'normalized' coordinate system into the
18 -- appropriate one for the quadrant in question
19 --
20 -- SUBSET FUNCTION
21 -- This function displays a subset of a quadrant, using a subset of a
22 -- texture (The texture subsetting is optional, so the same function
23 -- can be used for slice stretching). Note this does not issue a
24 -- ClearAllPoints.
25 --
26 -- setSubsetFuncs[quadrant](tex, parname, radius, xlo, xhi, ylo, yhi, notex)
27 --
28 -- Parameters:
29 -- tex - The texture object
30 -- parname - The name of the texture's parent (for SetPoint use)
31 -- radius - The outer radius of the ring (i.e. texture width & height)
32 -- xlo, xhi - X Coordinate bounds (from center of the ring)
33 -- ylo, yhi - Y Coordinate bounds (From center of the ring)
34 -- notex - (OPTIONAL) If present and true, do not set texture coords.
35 -- just change points.
36 --
37 -- SLICE FUNCTION
38 -- This function sets the texture coordinates for a slice texture, so that
39 -- it's correctly oriented for the quadrant.
40 --
41 -- setSliceFuncs[quadrant](tex)
42 --
43 -- Parameters:
44 -- tex - The slice texture object
45 --
46 local setSubsetFuncs = {};
47 local setSliceFuncs = {};
48  
49 -- Q3: BOTTOM LEFT
50 setSubsetFuncs[1] = function(tex, parname, radius, xlo, xhi, ylo, yhi, notex)
51 if (not notex) then
52 tex:SetTexCoord(xhi, xlo, ylo, yhi);
53 end
54 tex:SetPoint("BOTTOMRIGHT", parname, "BOTTOMLEFT", -xlo*radius, -yhi*radius);
55 tex:SetPoint("TOPLEFT", parname, "BOTTOMLEFT", -xhi*radius, -ylo*radius);
56 end
57  
58 -- Q4: TOP LEFT
59 setSubsetFuncs[2] = function(tex, parname, radius, xlo, xhi, ylo, yhi, notex)
60 if (not notex) then
61 tex:SetTexCoord(yhi, ylo, xhi, xlo);
62 end
63 tex:SetPoint("BOTTOMLEFT", parname, "BOTTOMLEFT", -yhi*radius, xlo*radius);
64 tex:SetPoint("TOPRIGHT", parname, "BOTTOMLEFT", -ylo*radius, xhi*radius);
65 end
66  
67 -- Q1: TOP RIGHT
68 setSubsetFuncs[3] = function(tex, parname, radius, xlo, xhi, ylo, yhi, notex)
69 if (not notex) then
70 tex:SetTexCoord(xlo, xhi, yhi, ylo);
71 end
72 tex:SetPoint("TOPLEFT", parname, "BOTTOMLEFT", xlo*radius, yhi*radius);
73 tex:SetPoint("BOTTOMRIGHT", parname, "BOTTOMLEFT", xhi*radius, ylo*radius);
74 end
75  
76 -- Q2: BOTTOM RIGHT
77 setSubsetFuncs[4] = function(tex, parname, radius, xlo, xhi, ylo, yhi, notex)
78 if (not notex) then
79 tex:SetTexCoord(ylo, yhi, xlo, xhi);
80 end
81 tex:SetPoint("TOPRIGHT", parname, "BOTTOMLEFT", yhi*radius, -xlo*radius);
82 tex:SetPoint("BOTTOMLEFT", parname, "BOTTOMLEFT", ylo*radius, -xhi*radius);
83 end
84  
85 -- Slice text coord setting funcs
86 setSliceFuncs[1] = function(tex) tex:SetTexCoord(0, 1, 1, 0); end
87 setSliceFuncs[2] = function(tex) tex:SetTexCoord(1, 0, 1, 0); end
88 setSliceFuncs[3] = function(tex) tex:SetTexCoord(1, 0, 0, 1); end
89 setSliceFuncs[4] = function(tex) tex:SetTexCoord(0, 1, 0, 1); end
90  
91 -- The 'Work' function, which handles subset rendering for a single
92 -- quadrant (normalized to Q1)
93 --
94 -- Params:
95 -- self - The ring template instance
96 -- A - The angle within the quadrant (degrees, 0 <= A < 90)
97 -- T - The main texture for the quadrant
98 -- SS - The texture subset mapping function for the quadrant
99  
100 function StatRingsRingTemplate_DoQuadrantReversed(self, A, T, SS)
101 -- Grab local references to important textures
102 local C = self.chip;
103 local S = self.slice;
104  
105 -- If no part of this quadrant is visible, just hide all the textures
106 -- and be done.
107 if (A == 0) then
108 T:Hide();
109 C:Hide();
110 S:Hide();
111 return;
112 end
113  
114 -- More local references, grab the ring dimensions, and the frame name.
115 local RF = self.ringFactor;
116 local OR = self.radius;
117 local name = self.name;
118  
119 -- Drawing scheme uses three locations
120 -- E (Ex,Ey) - The 'End' position (Nx=1, Ny=0)
121 -- O (Ox,Oy) - Intersection of angle line with Outer edge
122 -- I (Ix,Iy) - Intersection of angle line with Inner edge
123  
124 -- Calculated locations:
125 -- Arad - Angle in radians
126 -- Ox,Oy - O coordinates
127 -- Ix,Iy - I coordinates
128 local Arad = math.rad(A);
129 local Ox = math.cos(Arad);
130 local Oy = math.sin(Arad);
131 local Ix = Ox * RF;
132 local Iy = Oy * RF;
133  
134 -- Treat first and last halves differently to maximize size of main
135 -- texture subset.
136 if (A <= 45) then
137 -- Main subset is from N to I
138 SS(T, name, OR, Ix, 1, 0, Iy);
139 -- Chip is subset from (Ix,Oy) to (Ox,Ny) (Right edge of main)
140 SS(C, name, OR, Ox, 1, Iy, Oy);
141 else
142 -- Main subset is from N to O
143 SS(T, name, OR, Ox, 1, 0, Oy);
144 -- Chip is subset from (Nx,Iy) to (Ix,Oy) (Bottom edge of main)
145 SS(C, name, OR, Ix, Ox, 0, Iy);
146 end
147 -- Strech slice between I and O
148 SS(S, name, OR, Ix, Ox, Iy, Oy, 1);
149 -- All three textures are visible
150 T:Show();
151 C:Show();
152 S:Show();
153 end
154  
155 function StatRingsRingTemplate_DoQuadrant(self, A, T, SS)
156 -- Grab local references to important textures
157 local C = self.chip;
158 local S = self.slice;
159  
160 -- If no part of this quadrant is visible, just hide all the textures
161 -- and be done.
162 if (A == 0) then
163 T:Hide();
164 C:Hide();
165 S:Hide();
166 return;
167 end
168  
169 -- More local references, grab the ring dimensions, and the frame name.
170 local RF = self.ringFactor;
171 local OR = self.radius;
172 local name = self.name;
173  
174 -- Drawing scheme uses three locations
175 -- N (Nx,Ny) - The 'Noon' position (Nx=0, Ny=1)
176 -- O (Ox,Oy) - Intersection of angle line with Outer edge
177 -- I (Ix,Iy) - Intersection of angle line with Inner edge
178  
179 -- Calculated locations:
180 -- Arad - Angle in radians
181 -- Ox,Oy - O coordinates
182 -- Ix,Iy - I coordinates
183 local Arad = math.rad(A);
184 local Ox = math.sin(Arad);
185 local Oy = math.cos(Arad);
186 local Ix = Ox * RF;
187 local Iy = Oy * RF;
188  
189 -- Treat first and last halves differently to maximize size of main
190 -- texture subset.
191 if (A <= 45) then
192 -- Main subset is from N to I
193 SS(T, name, OR, 0, Ix, Iy, 1);
194 -- Chip is subset from (Ix,Oy) to (Ox,Ny) (Right edge of main)
195 SS(C, name, OR, Ix, Ox, Oy, 1);
196 else
197 -- Main subset is from N to O
198 SS(T, name, OR, 0, Ox, Oy, 1);
199 -- Chip is subset from (Nx,Iy) to (Ix,Oy) (Bottom edge of main)
200 SS(C, name, OR, 0, Ix, Iy, Oy);
201 end
202 -- Strech slice between I and O
203 SS(S, name, OR, Ix, Ox, Iy, Oy, 1);
204 -- All three textures are visible
205 T:Show();
206 C:Show();
207 S:Show();
208 end
209  
210 -- Method function to set the angle to display
211 --
212 -- Param:
213 -- self - The ring template instance
214 -- angle - The angle in degrees (0 <= angle <= 180)
215  
216 function StatRingsRingTemplate_SetAngle(self, angle)
217  
218 -- Bounds checking on the angle so that it's between 0 and 180 (inclusive)
219 if (angle < 0) then
220 angle = 0;
221 end
222 if (angle > 180) then
223 angle = 180;
224 end
225  
226 -- Avoid duplicate work
227 if (self.angle == angle and not self.dirty) then
228 return;
229 end
230  
231 -- Determine the quadrant, and angle within the quadrant
232 -- (Quadrant 5 means 'all quadrants filled')
233 local quad = math.floor(angle / 90) + 1;
234 local A = math.mod(angle, 90);
235 local quadOfs = self.quadOffset or 0;
236 local effQuad;
237 if (self.reversed) then
238 effQuad = math.mod((4-quad)+quadOfs, 4)+1;
239 else
240 effQuad = math.mod(quad+quadOfs-1, 4)+1;
241 end
242  
243 -- Check to see if we've changed quandrants since the last time we were
244 -- called. Quadrant changes re-configure some textures.
245 if (quad ~= self.lastQuad or self.dirty) then
246 -- Loop through all quadrants
247 for i=1,2 do
248 T=self.quadrants[i];
249 if (self.reversed) then
250 qi = math.mod((4-i)+quadOfs, 4)+1;
251 else
252 qi = math.mod(i+quadOfs-1, 4)+1;
253 end
254 if (i < quad) then
255 -- If this quadrant is full shown, then show all of the texture
256 T:ClearAllPoints();
257 --if (self.reversed) then
258 --setSubsetFuncs[i+2](T, self.name, self.radius, 0.0, 1.0, 0.0, 1.0);
259 --else
260 setSubsetFuncs[qi](T, self.name, self.radius, 0.0, 1.0, 0.0, 1.0);
261 --end
262  
263 T:Show();
264 elseif (i == quad) then
265 -- If this quadrant is partially or fully shown, begin by
266 -- showing all of the texture. Also configure the slice
267 -- texture's orientation.
268 T:ClearAllPoints();
269 setSubsetFuncs[qi](T, self.name, self.radius, 0.0, 0.8, 0.4, 1.0);
270 --[[
271 if (self.reversed) then
272 setSubsetFuncs[qi](T, self.name, self.radius, 0.0, 0.8, 0.4, 1.0);
273 else
274 setSubsetFuncs[i](T, self.name, self.radius, 0.0, 0.8, 0.4, 1.0);
275 end
276 ]]
277 T:Show();
278 if (self.reversed) then
279 setSliceFuncs[math.mod(qi+1,4)+1](self.slice);
280 else
281 setSliceFuncs[qi](self.slice);
282 end
283 --[[
284 if (self.reversed) then
285 setSliceFuncs[i+2](self.slice);
286 else
287 setSliceFuncs[i](self.slice);
288 end
289 ]]
290 else
291 -- If this quadrant is not shown at all, hide it.
292 T:Hide();
293 end
294 end
295  
296 -- Hide the chip and slice textures, and de-anchor them (They'll be
297 -- re-anchored as necessary later).
298 self.chip:Hide();
299 self.chip:ClearAllPoints();
300 self.slice:Hide();
301 self.slice:ClearAllPoints();
302  
303 -- Remember this for next time
304 self.lastQuad = quad;
305 end
306  
307 -- Remember the angle for next time
308 self.angle = angle;
309  
310 -- Extra bounds check for paranoia (also handles quad 5 case)
311 if ((quad < 1) or (quad > 2)) then
312 return;
313 end
314  
315 -- Get quadrant-specific elements
316 local T = self.quadrants[quad];
317 --local SS = setSubsetFuncs[quad];
318 local SS = setSubsetFuncs[effQuad];
319  
320 -- Call the quadrant function to do the work
321 if SS ~= nil then
322 if (self.reversed) then
323 StatRingsRingTemplate_DoQuadrantReversed(self, A, T, SS)
324 else
325 StatRingsRingTemplate_DoQuadrant(self, A, T, SS)
326 end
327 end
328 self.dirty = false;
329 end
330  
331  
332  
333 ---------------------------------------------------------------------------
334 -- Some handy method functions
335  
336 -- StatsRingRingTemplate:CallTextureMethod(method, ...)
337 --
338 -- Invokes the named method on all of the textures in the ring,
339 -- passing in whatever arguments are given.
340 --
341 -- e.g. ring:CallTextureMethod("SetVertexColor", 1.0, 0.5, 0.2, 1.0);
342  
343 local function StatsRingsRingTemplate_CallTextureMethod(self, method, ...)
344 self.quadrants[1][method](self.quadrants[1], unpack(arg));
345 self.quadrants[2][method](self.quadrants[2], unpack(arg));
346 self.chip[method](self.chip, unpack(arg));
347 self.slice[method](self.slice, unpack(arg));
348 end
349  
350  
351 -- StatsRingRingTemplate:SetRingTextures(ringFactor,ringTexFile,sliceTexFile)
352 --
353 -- Sets the textures to use for this ring
354 --
355 -- Param:
356 -- ringFactor - The ring factor (Inner Radius / Outer Radius)
357 -- ringTexFile - The ring texture filename
358 -- sliceTexFile - The slice texture filename
359  
360 local function StatsRingsRingTemplate_SetRingTextures(self, ringFactor,
361 ringTexture,
362 sliceTexture)
363 DEFAULT_CHAT_FRAME:AddMessage("called setringtextures");
364 local savedAngle = self.angle;
365 self.angle = nil;
366 self.lastQuad = nil;
367  
368 self.ringFactor = ringFactor;
369  
370 for i=1,2 do
371 self.quadrants[i]:SetTexture(ringTexture);
372 end
373 self.chip:SetTexture(ringTexture);
374 self.slice:SetTexture(sliceTexture);
375  
376 if (savedAngle) then
377 self:SetAngle(savedAngle);
378 end
379 end
380  
381 -- Method function to set whether or not ring growth is reversed.
382 --
383 -- Param:
384 -- self - The ring template instance
385 -- isReversed - Whether to reverse or not
386 function StatRingsRingTemplate_SetReversed(self, isReversed)
387 if (isReversed) then
388 isReversed = true;
389 else
390 isReversed = nil;
391 end
392 if (isReversed == self.reversed) then
393 return;
394 end
395 self.reversed = isReversed;
396 end
397  
398 -- The OnLoad method, call this for each template object to set it up and
399 -- get things going
400 function StatRingsRingTemplate_OnLoad()
401 -- Just do global this resolution once.
402 local this = this;
403  
404 -- Grab texture references and frame name
405 this.name = this:GetName();
406 this.quadrants = {};
407 this.quadrants[1] = getglobal(this.name .. "TQ1");
408 this.quadrants[2] = getglobal(this.name .. "TQ2");
409 this.chip = getglobal(this.name .. "TC");
410 this.slice = getglobal(this.name .. "TS");
411  
412 -- Initialize size and default texture ringFactor
413 this.radius = (this:GetWidth() * 0.5);
414 this.ringFactor = 0.94;
415  
416 -- Add ring methods
417 this.SetAngle = StatRingsRingTemplate_SetAngle;
418 this.CallTextureMethod = StatsRingsRingTemplate_CallTextureMethod;
419 this.SetRingTextures = StatsRingsRingTemplate_SetRingTextures;
420 this.Init = StatRings_Init;
421 this.SetMax = StatRings_SetMax;
422 this.SetValue = StatRings_SetValue;
423 this.Update = StatRings_Update;
424 this.AddUpdateFunction = StatRings_AddUpdateFunction;
425 this.RemoveUpdateFunction = StatRings_RemoveUpdateFunction;
426 this.UpdateColor = StatRings_UpdateColor;
427 this.SetReversed = StatRingsRingTemplate_SetReversed;
428  
429 this.startValue = 0;
430 this.endValue = 0;
431 this.maxValue = 0;
432 this.fadeTime = 0;
433 this.maxFadeTime = 1;
434 this.alphaState = -1;
435 this.PI = 3.14159265;
436 this.casting = 0;
437 this.channeling = 0;
438 this.spellstart = GetTime();
439 this.baseColor = {["r"] = 1, ["g"] = 0.6, ["b"] = 0.1};
440 this.baseAlpha = 0.5;
441 this.destAlpha = 0.5;
442  
443 this.updateFuncs = {};
444  
445 this:SetScript("OnUpdate", StatRings_Update);
446 -- Set angle to zero (initializes texture visibility)
447 this:AddUpdateFunction(StatRings_DoFadeUpdate);
448 this:AddUpdateFunction(StatRingsTest_AlphaUpdate);
449 this:AddUpdateFunction(StatRings_Casting);
450  
451 this:SetAngle(0);
452 end
453  
454 function StatRings_SetMax(self, max)
455 if max == nil then max = 1; end
456 this.maxValue = max;
457 -- sr_pr(this.name .. "ring Max set to " .. this.maxValue);
458 end
459  
460 function StatRings_SetValue(self, value)
461 if value == nil then value = 0; end
462 if value == 0 then
463 value = this.maxValue / 10000; end
464 if this.casting == 1 then
465 this.startValue = value; end
466 this.endValue = value
467 this.fadeTime = 0;
468 end
469  
470 function StatRings_Update()
471 for idx, func in this.updateFuncs do
472 func(this, arg1);
473 end
474 end
475  
476 function StatRings_AddUpdateFunction(self, arg1)
477 local found = false;
478 for idx, f in this.updateFuncs do
479 if arg1 == f then
480 found = true;
481 break;
482 end
483 end
484 if not found then
485 table.insert(this.updateFuncs, arg1);
486 end
487 end
488  
489 function StatRings_RemoveUpdateFunction(self, func)
490 for idx, f in this.updateFuncs do
491 if func == f then
492 table.remove(this.updateFuncs, idx);
493 break;
494 end
495 end
496 end
497  
498 function StatRings_Casting(this)
499 if ( this.casting == nil ) then
500 this.casting = 0; end
501 if ( this.channeling == nil ) then
502 this.channeling = 0; end
503 if ( this.spellstart == nil ) then
504 this.spellstart = GetTime(); end
505  
506 if ( this.casting == 1) then
507 local status = (GetTime() - this.spellstart)*1000;
508 local time_remaining = this.maxValue - status;
509  
510 if ( this.channeling == 1) then
511 status = time_remaining;
512 end
513  
514 if ( status > this.maxValue ) then
515 status = this.maxValue
516 end
517  
518 this:SetValue(status);
519  
520 if ( time_remaining < 0 ) then
521 time_remaining = 0;
522 end
523  
524 local intlength = string.len(string.format("%u",time_remaining/1000));
525 local texttime = strsub(string.format("%f",time_remaining/1000),1,intlength+2) .. "s";
526 Moog_HudCastTime:SetText(texttime);
527 end
528 end
529  
530 function StatRings_DoFadeUpdate(this, tdelta)
531 tdelta = arg1;
532 if this.fadeTime < this.maxFadeTime then
533 this.fadeTime = this.fadeTime + tdelta;
534 if this.fadeTime > this.maxFadeTime then
535 this.fadeTime = this.maxFadeTime;
536 end
537 local delta = this.endValue - this.startValue;
538 local diff = delta * (this.fadeTime / this.maxFadeTime);
539 this.startValue = this.startValue + diff;
540 local angle = this.startValue / this.maxValue * 180;
541 if angle <= 90 then
542 this.ringFactor = 0.9 + ((90 - angle) / (90/0.1));
543 elseif angle <= 180 then
544 this.ringFactor = 0.9 + ((angle - 90) / (90/0.1));
545 --[[
546 elseif angle <= 270 then
547 this.ringFactor = 0.9 + ((270 - angle) / (90/0.1));
548 elseif angle > 270 then
549 this.ringFactor = 0.9 + ((angle - 270) / (90/0.1));
550 ]]
551 end
552 this:SetAngle((this.startValue / this.maxValue) * 180);
553 end
554 end
555  
556 function StatRingsTest_AlphaUpdate(this)
557 --[[
558 if getglobal(this:GetName() .. "MoveAnchor"):IsVisible() then
559 this:SetAlpha(0.8);
560 this:SetAngle(180);
561 return;
562 end
563 ]]
564 local destAlpha = this.destAlpha;
565  
566 local nowAlpha = this.baseAlpha;
567  
568 if (nowAlpha < destAlpha) then
569 nowAlpha = nowAlpha + (arg1/2);
570 if (nowAlpha > destAlpha) then
571 nowAlpha = destAlpha;
572 end
573 elseif (nowAlpha > destAlpha) then
574 nowAlpha = nowAlpha - (arg1/2);
575 if (nowAlpha < destAlpha) then
576 nowAlpha = destAlpha;
577 end
578 end
579  
580 this.baseAlpha = nowAlpha;
581  
582 -- New white blink code
583 -- blinkstate is amount remaining of 1 second blink
584 local blinkstate = 1-(GetTime() - Moog_SpellBlinkTime);
585  
586 if (blinkstate <= 0) then
587 this:CallTextureMethod("SetVertexColor",this.baseColor.r, this.baseColor.g, this.baseColor.b,1);
588 this:SetAlpha(nowAlpha);
589 else
590 local blinkcolor = {["r"] = ((1-this.baseColor.r)*blinkstate)+this.baseColor.r,
591 ["g"] = ((1-this.baseColor.g)*blinkstate)+this.baseColor.g,
592 ["b"] = ((1-this.baseColor.b)*blinkstate)+this.baseColor.b};
593 this:CallTextureMethod("SetVertexColor",blinkcolor.r, blinkcolor.g, blinkcolor.b,1);
594 this:SetAlpha(((0.9-this.baseAlpha)*blinkstate)+this.baseAlpha);
595 end
596  
597 end
598  
599 function StatRingsTest_SetAlpha(this, destAlpha, instant)
600 if (destAlpha < 0) then
601 destAlpha = 0.0;
602 elseif (destAlpha > 1) then
603 destAlpha = 1.0;
604 end
605  
606 if (this.baseAlpha == destAlpha) then
607 return;
608 end
609  
610 if (instant) then
611 this.baseAlpha = destAlpha;
612 end
613  
614 this.destAlpha = destAlpha;
615 end
616  
617 function StatRings_UpdateColor(self, color)
618 if color == nil then
619 color = {["r"] = 1, ["g"] = 0.6, ["b"] = 0.1};
620 end
621 if (color) then
622 self.baseColor = color;
623 -- self:CallTextureMethod("SetVertexColor",color.r, color.g, color.b,1);
624 end
625 end